Skip to content

Commit

Permalink
chore(roleassignment): make roleassignments service async
Browse files Browse the repository at this point in the history
Signed-off-by: Ashutosh Kumar <[email protected]>
  • Loading branch information
sonasingh46 committed Jan 19, 2022
1 parent 2bb771b commit 3073807
Show file tree
Hide file tree
Showing 13 changed files with 482 additions and 223 deletions.
18 changes: 10 additions & 8 deletions azure/scope/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"strings"
"time"

"sigs.k8s.io/cluster-api-provider-azure/azure/services/roleassignments"

"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2021-04-01/compute"
"github.com/Azure/go-autorest/autorest/to"
"github.com/pkg/errors"
Expand Down Expand Up @@ -281,17 +283,17 @@ func (m *MachineScope) DiskSpecs() []azure.ResourceSpecGetter {
}

// RoleAssignmentSpecs returns the role assignment specs.
func (m *MachineScope) RoleAssignmentSpecs() []azure.RoleAssignmentSpec {
func (m *MachineScope) RoleAssignmentSpecs() []azure.ResourceSpecGetter {
roles := make([]azure.ResourceSpecGetter, 1)
if m.AzureMachine.Spec.Identity == infrav1.VMIdentitySystemAssigned {
return []azure.RoleAssignmentSpec{
{
MachineName: m.Name(),
Name: m.AzureMachine.Spec.RoleAssignmentName,
ResourceType: azure.VirtualMachine,
},
roles[0] = &roleassignments.RoleAssignmentSpec{
Name: m.AzureMachine.Spec.RoleAssignmentName,
MachineName: m.Name(),
ResourceType: azure.VirtualMachine,
}
return roles
}
return []azure.RoleAssignmentSpec{}
return []azure.ResourceSpecGetter{}
}

// VMExtensionSpecs returns the vm extension specs.
Expand Down
12 changes: 7 additions & 5 deletions azure/scope/machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"strings"
"testing"

"sigs.k8s.io/cluster-api-provider-azure/azure/services/roleassignments"

autorestazure "github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/go-autorest/autorest/azure/auth"
"github.com/Azure/go-autorest/autorest/to"
Expand Down Expand Up @@ -378,7 +380,7 @@ func TestMachineScope_RoleAssignmentSpecs(t *testing.T) {
tests := []struct {
name string
machineScope MachineScope
want []azure.RoleAssignmentSpec
want []azure.ResourceSpecGetter
}{
{
name: "returns empty if VM identity is system assigned",
Expand All @@ -390,7 +392,7 @@ func TestMachineScope_RoleAssignmentSpecs(t *testing.T) {
},
},
},
want: []azure.RoleAssignmentSpec{},
want: []azure.ResourceSpecGetter{},
},
{
name: "returns RoleAssignmentSpec if VM identity is not system assigned",
Expand All @@ -406,11 +408,11 @@ func TestMachineScope_RoleAssignmentSpecs(t *testing.T) {
},
},
},
want: []azure.RoleAssignmentSpec{
{
want: []azure.ResourceSpecGetter{
&roleassignments.RoleAssignmentSpec{
ResourceType: azure.VirtualMachine,
MachineName: "machine-name",
Name: "azure-role-assignment-name",
ResourceType: azure.VirtualMachine,
},
},
},
Expand Down
19 changes: 11 additions & 8 deletions azure/scope/machinepool.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"strings"
"time"

"sigs.k8s.io/cluster-api-provider-azure/azure/services/roleassignments"

"sigs.k8s.io/cluster-api-provider-azure/util/futures"

"github.com/Azure/go-autorest/autorest/to"
Expand Down Expand Up @@ -571,17 +573,18 @@ func (m *MachinePoolScope) SaveVMImageToStatus(image *infrav1.Image) {
}

// RoleAssignmentSpecs returns the role assignment specs.
func (m *MachinePoolScope) RoleAssignmentSpecs() []azure.RoleAssignmentSpec {
func (m *MachinePoolScope) RoleAssignmentSpecs() []azure.ResourceSpecGetter {
roles := make([]azure.ResourceSpecGetter, 1)
if m.AzureMachinePool.Spec.Identity == infrav1.VMIdentitySystemAssigned {
return []azure.RoleAssignmentSpec{
{
MachineName: m.Name(),
Name: m.AzureMachinePool.Spec.RoleAssignmentName,
ResourceType: azure.VirtualMachineScaleSet,
},
roles[0] = &roleassignments.RoleAssignmentSpec{
Name: m.AzureMachinePool.Spec.RoleAssignmentName,
MachineName: m.Name(),
ResourceGroup: azure.VirtualMachineScaleSet,
SubscriptionID: m.SubscriptionID(),
}
return roles
}
return []azure.RoleAssignmentSpec{}
return []azure.ResourceSpecGetter{}
}

// VMSSExtensionSpecs returns the vmss extension specs.
Expand Down
2 changes: 1 addition & 1 deletion azure/services/async/async.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ func processOngoingOperation(ctx context.Context, scope FutureScope, client Futu
func (s *Service) CreateResource(ctx context.Context, spec azure.ResourceSpecGetter, serviceName string) (result interface{}, err error) {
ctx, log, done := tele.StartSpanWithLogger(ctx, "async.Service.CreateResource")
defer done()

resourceName := spec.ResourceName()
rgName := spec.ResourceGroupName()

Expand All @@ -102,6 +101,7 @@ func (s *Service) CreateResource(ctx context.Context, spec azure.ResourceSpecGet

// Get the resource if it already exists, and use it to construct the desired resource parameters.
var existingResource interface{}

if existing, err := s.Creator.Get(ctx, spec); err != nil && !azure.ResourceNotFound(err) {
return nil, errors.Wrapf(err, "failed to get existing resource %s/%s (service: %s)", rgName, resourceName, serviceName)
} else if err == nil {
Expand Down
71 changes: 58 additions & 13 deletions azure/services/roleassignments/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ package roleassignments
import (
"context"

"github.com/pkg/errors"

azureautorest "github.com/Azure/go-autorest/autorest/azure"

"github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/authorization/mgmt/authorization"
"github.com/Azure/go-autorest/autorest"

Expand All @@ -28,7 +32,12 @@ import (

// client wraps go-sdk.
type client interface {
Create(context.Context, string, string, authorization.RoleAssignmentCreateParameters) (authorization.RoleAssignment, error)
//Create(context.Context, string, string, authorization.RoleAssignmentCreateParameters) (authorization.RoleAssignment, error)
Get(context.Context, azure.ResourceSpecGetter) (interface{}, error)
CreateOrUpdateAsync(context.Context, azure.ResourceSpecGetter, interface{}) (interface{}, azureautorest.FutureAPI, error)
IsDone(context.Context, azureautorest.FutureAPI) (bool, error)
Result(context.Context, azureautorest.FutureAPI, string) (interface{}, error)
DeleteAsync(context.Context, azure.ResourceSpecGetter) (azureautorest.FutureAPI, error)
}

// azureClient contains the Azure go-sdk Client.
Expand All @@ -51,18 +60,54 @@ func newRoleAssignmentClient(subscriptionID string, baseURI string, authorizer a
return roleClient
}

// Create creates a role assignment.
// Parameters:
// scope - the scope of the role assignment to create. The scope can be any REST resource instance. For
// example, use '/subscriptions/{subscription-id}/' for a subscription,
// '/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}' for a resource group, and
// '/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider}/{resource-type}/{resource-name}'
// for a resource.
// roleAssignmentName - the name of the role assignment to create. It can be any valid GUID.
// parameters - parameters for the role assignment.
func (ac *azureClient) Create(ctx context.Context, scope string, roleAssignmentName string, parameters authorization.RoleAssignmentCreateParameters) (authorization.RoleAssignment, error) {
ctx, _, done := tele.StartSpanWithLogger(ctx, "roleassignments.AzureClient.Create")
// Get gets the specified role assignment by the role assignment name.
func (ac *azureClient) Get(ctx context.Context, spec azure.ResourceSpecGetter) (interface{}, error) {
ctx, span := tele.Tracer().Start(ctx, "roleassignments.AzureClient.Get")
defer span.End()
raSpec := spec.(*RoleAssignmentSpec)
// ToDo: Check if correct scope is being passed
return ac.roleassignments.Get(ctx, raSpec.Scope, spec.ResourceName())
}

// CreateOrUpdateAsync creates a roleassignment.
// Creating a roleassignment is not a long running operation, so we don't ever return a future.
func (ac *azureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, parameters interface{}) (interface{}, azureautorest.FutureAPI, error) {
ctx, _, done := tele.StartSpanWithLogger(ctx, "groups.AzureClient.CreateOrUpdate")
defer done()
assignment, ok := parameters.(authorization.RoleAssignmentPropertiesWithScope)
if !ok {
return nil, nil, errors.Errorf("%T is not a authorization.RoleAssignment", parameters)
}
//scope := fmt.Sprintf("/subscriptions/%s/", *assignment.Scope)
roleAssignmentCreatePrams := authorization.RoleAssignmentCreateParameters{
Properties: &authorization.RoleAssignmentProperties{
PrincipalID: assignment.PrincipalID,
RoleDefinitionID: assignment.RoleDefinitionID,
},
}
result, err := ac.roleassignments.Create(ctx, *assignment.Scope, spec.ResourceName(), roleAssignmentCreatePrams)
return result, nil, err
}

// IsDone returns true if the long-running operation has completed.
func (ac *azureClient) IsDone(ctx context.Context, future azureautorest.FutureAPI) (bool, error) {
ctx, _, done := tele.StartSpanWithLogger(ctx, "roleassignments.AzureClient.IsDone")
defer done()

isDone, err := future.DoneWithContext(ctx, ac.roleassignments)
if err != nil {
return false, errors.Wrap(err, "failed checking if the operation was complete")
}
return isDone, nil
}

// Result fetches the result of a long-running operation future.
func (ac *azureClient) Result(ctx context.Context, futureData azureautorest.FutureAPI, futureType string) (interface{}, error) {
// Result is a no-op for role assignment as only Delete operations return a future.
return nil, nil
}

return ac.roleassignments.Create(ctx, scope, roleAssignmentName, parameters)
func (ac *azureClient) DeleteAsync(ctx context.Context, spec azure.ResourceSpecGetter) (azureautorest.FutureAPI, error) {
// ToDo: Complete this function
return nil, nil
}
78 changes: 70 additions & 8 deletions azure/services/roleassignments/mock_roleassignments/client_mock.go

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

Loading

0 comments on commit 3073807

Please sign in to comment.