Skip to content

Commit

Permalink
Added SDK calls for assignSpRole function (#272)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vidya2606 authored May 15, 2024
1 parent 7975039 commit 8db86bd
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 9 deletions.
8 changes: 8 additions & 0 deletions cmd/setup-gh.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription"
"github.com/Azure/draft/pkg/cred"
"github.com/manifoldco/promptui"
Expand Down Expand Up @@ -50,6 +51,13 @@ application and service principle, and will configure that application to trust

sc.AzClient.GraphClient = graphClient

roleAssignmentClient, err := armauthorization.NewRoleAssignmentsClient(sc.SubscriptionID, azCred, nil)
if err != nil {
return fmt.Errorf("getting role assignment client: %w", err)
}

sc.AzClient.RoleAssignClient = roleAssignmentClient

fillSetUpConfig(sc)

s := spinner.CreateSpinner("--> Setting up Github OIDC...")
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22.0
require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization v1.0.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0
github.com/briandowns/spinner v1.23.0
github.com/cenkalti/backoff/v4 v4.3.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 h1:FDif4R1+UUR+00q6wquyX
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2/go.mod h1:aiYBYui4BJ/BJCAIKs92XiPyQfTaBWqvHujDwKb6CBU=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization v1.0.0 h1:qtRcg5Y7jNJ4jEzPq4GpWLfTspHdNe2ZK6LjwGcjgmU=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization v1.0.0/go.mod h1:lPneRe3TwsoDRKY4O6YDLXHhEWrD+TIRa8XrV/3/fqw=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0 h1:UrGzkHueDwAWDdjQxC+QaXHd4tVCkISYE9j7fSSXF8k=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0/go.mod h1:qskvSQeW+cxEE2bcKYyKimB1/KiQ9xpJ99bcHY0BX6c=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
Expand Down
14 changes: 12 additions & 2 deletions pkg/providers/az-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import (
"context"
"errors"
"fmt"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription"

msgraph "github.com/microsoftgraph/msgraph-sdk-go"
)

type AzClient struct {
AzTenantClient azTenantClient
GraphClient GraphClient
AzTenantClient azTenantClient
GraphClient GraphClient
RoleAssignClient RoleAssignClient
}

//go:generate mockgen -source=./az-client.go -destination=./mock/az-client.go .
Expand Down Expand Up @@ -43,3 +47,9 @@ func (g *GraphServiceClient) GetApplicationObjectId(ctx context.Context, appId s
}
return *appObjectId, nil
}

type RoleAssignClient interface {
CreateByID(ctx context.Context, roleAssignmentID string, parameters armauthorization.RoleAssignmentCreateParameters, options *armauthorization.RoleAssignmentsClientCreateByIDOptions) (armauthorization.RoleAssignmentsClientCreateByIDResponse, error)
}

var _ RoleAssignClient = &armauthorization.RoleAssignmentsClient{}
23 changes: 16 additions & 7 deletions pkg/providers/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription"
"os/exec"
"time"
Expand Down Expand Up @@ -61,7 +62,7 @@ func InitiateAzureOIDCFlow(ctx context.Context, sc *SetUpCmd, s spinner.Spinner)
return err
}

if err := sc.assignSpRole(); err != nil {
if err := sc.assignSpRole(ctx); err != nil {
return err
}

Expand Down Expand Up @@ -165,14 +166,22 @@ func (sc *SetUpCmd) CreateServicePrincipal() error {
return nil
}

func (sc *SetUpCmd) assignSpRole() error {
func (sc *SetUpCmd) assignSpRole(ctx context.Context) error {
log.Debug("Assigning contributor role to service principal...")
scope := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s", sc.SubscriptionID, sc.ResourceGroupName)
assignSpRoleCmd := exec.Command("az", "role", "assignment", "create", "--role", "contributor", "--subscription", sc.SubscriptionID, "--assignee-object-id", sc.spObjectId, "--assignee-principal-type", "ServicePrincipal", "--scope", scope, "--only-show-errors")
out, err := assignSpRoleCmd.CombinedOutput()

objectID := sc.spObjectId
roleID := "contributor"

parameters := armauthorization.RoleAssignmentCreateParameters{
Properties: &armauthorization.RoleAssignmentProperties{
PrincipalID: &objectID,
RoleDefinitionID: &roleID,
},
}

_, err := sc.AzClient.RoleAssignClient.CreateByID(ctx, roleID, parameters, nil)
if err != nil {
log.Printf("%s\n", out)
return err
return fmt.Errorf("creating role assignment: %w", err)
}

log.Debug("Role assigned successfully!")
Expand Down
64 changes: 64 additions & 0 deletions pkg/providers/azure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription"
mock_providers "github.com/Azure/draft/pkg/providers/mock"
"go.uber.org/mock/gomock"
Expand Down Expand Up @@ -243,3 +244,66 @@ func TestGetAppObjectId_EmptyAppIdFromGraphClient(t *testing.T) {
t.Errorf("Expected error '%v', got '%v'", expectedError, err)
}
}

var principalId = "mockPrincipalID"
var roleDefId = "mockRoleDefinitionID"
var Id = "mockID"
var name = "mockName"
var Idtype = "mocktype"

func TestAssignSpRole(t *testing.T) {
tests := []struct {
name string
expectedError error
mockResponse armauthorization.RoleAssignmentsClientCreateByIDResponse
}{
{
name: "Success",
expectedError: nil,
mockResponse: armauthorization.RoleAssignmentsClientCreateByIDResponse{
RoleAssignment: armauthorization.RoleAssignment{
Properties: &armauthorization.RoleAssignmentPropertiesWithScope{
PrincipalID: &principalId,
RoleDefinitionID: &roleDefId,
},
ID: &Id,
Name: &name,
Type: &Idtype,
},
},
},
{
name: "Error",
expectedError: errors.New("error"),
mockResponse: armauthorization.RoleAssignmentsClientCreateByIDResponse{},
},
{
name: "ErrorDuringRoleAssignment",
expectedError: errors.New("error during role assignment"),
mockResponse: armauthorization.RoleAssignmentsClientCreateByIDResponse{},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockRoleAssignClient := mock_providers.NewMockRoleAssignClient(ctrl)

mockRoleAssignClient.EXPECT().CreateByID(gomock.Any(), "contributor", gomock.Any(), gomock.Any()).Return(tt.mockResponse, tt.expectedError)

sc := &SetUpCmd{
AzClient: AzClient{
RoleAssignClient: mockRoleAssignClient,
},
spObjectId: "testObjectId",
}

err := sc.assignSpRole(context.Background())
if !errors.Is(err, tt.expectedError) {
t.Errorf("Expected error: %v, got: %v", tt.expectedError, err)
}
})
}
}
39 changes: 39 additions & 0 deletions pkg/providers/mock/az-client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8db86bd

Please sign in to comment.