pkg/cmd/serviceaccount/phases/create/roleassignment.go (69 lines of code) (raw):
package phases
import (
"context"
"github.com/pkg/errors"
"monis.app/mlog"
"github.com/Azure/azure-workload-identity/pkg/cloud"
"github.com/Azure/azure-workload-identity/pkg/cmd/serviceaccount/options"
"github.com/Azure/azure-workload-identity/pkg/cmd/serviceaccount/phases/workflow"
)
const (
roleAssignmentPhaseName = "role-assignment"
)
type roleAssignmentPhase struct {
}
// NewRoleAssignmentPhase creates a new phase to create role assignment
func NewRoleAssignmentPhase() workflow.Phase {
p := &roleAssignmentPhase{}
return workflow.Phase{
Name: roleAssignmentPhaseName,
Aliases: []string{"ra"},
Description: "Create role assignment between the AAD application and the Azure cloud resource",
PreRun: p.prerun,
Run: p.run,
Flags: []string{
options.AzureScope.Flag,
options.AzureRole.Flag,
options.ServicePrincipalName.Flag,
options.ServicePrincipalObjectID.Flag,
},
}
}
func (p *roleAssignmentPhase) prerun(data workflow.RunData) error {
createData, ok := data.(CreateData)
if !ok {
return errors.Errorf("invalid data type %T", data)
}
if createData.AzureScope() == "" {
return options.FlagIsRequiredError(options.AzureScope.Flag)
}
if createData.AzureRole() == "" {
return options.FlagIsRequiredError(options.AzureRole.Flag)
}
if createData.ServicePrincipalName() == "" && createData.ServicePrincipalObjectID() == "" {
return options.OneOfFlagsIsRequiredError(options.ServicePrincipalName.Flag, options.ServicePrincipalObjectID.Flag)
}
return nil
}
func (p *roleAssignmentPhase) run(ctx context.Context, data workflow.RunData) error {
createData := data.(CreateData)
// create the role assignment using object id of the service principal
ra, err := createData.AzureClient().CreateRoleAssignment(ctx, createData.AzureScope(), createData.AzureRole(), createData.ServicePrincipalObjectID())
if err != nil {
if cloud.IsRoleAssignmentExists(err) {
mlog.WithValues(
"scope", createData.AzureScope(),
"role", createData.AzureRole(),
"servicePrincipalObjectID", createData.ServicePrincipalObjectID(),
"roleAssignmentID", ra.ID,
).WithName(roleAssignmentPhaseName).Debug("role assignment has previously been created")
} else {
return errors.Wrap(err, "failed to create role assignment")
}
}
mlog.WithValues(
"scope", createData.AzureScope(),
"role", createData.AzureRole(),
"servicePrincipalObjectID", createData.ServicePrincipalObjectID(),
"roleAssignmentID", ra.ID,
).WithName(roleAssignmentPhaseName).Info("created role assignment")
return nil
}