pkg/cmd/serviceaccount/phases/create/serviceaccount.go (80 lines of code) (raw):

package phases import ( "context" "time" "github.com/pkg/errors" "monis.app/mlog" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/Azure/azure-workload-identity/pkg/cmd/serviceaccount/options" "github.com/Azure/azure-workload-identity/pkg/cmd/serviceaccount/phases/workflow" "github.com/Azure/azure-workload-identity/pkg/kuberneteshelper" "github.com/Azure/azure-workload-identity/pkg/webhook" ) const ( serviceAccountPhaseName = "service-account" ) type serviceAccountPhase struct { kubeClient client.Client } // NewServiceAccountPhase creates a new phase to create a Kubernetes service account func NewServiceAccountPhase() workflow.Phase { p := &serviceAccountPhase{} return workflow.Phase{ Name: serviceAccountPhaseName, Aliases: []string{"sa"}, Description: "Create Kubernetes service account in the current KUBECONFIG context and add azure-workload-identity labels and annotations to it", PreRun: p.prerun, Run: p.run, Flags: []string{ options.ServiceAccountNamespace.Flag, options.ServiceAccountName.Flag, options.ServiceAccountTokenExpiration.Flag, options.AADApplicationName.Flag, options.AADApplicationClientID.Flag, }, } } func (p *serviceAccountPhase) prerun(data workflow.RunData) error { createData, ok := data.(CreateData) if !ok { return errors.Errorf("invalid data type %T", data) } if createData.ServiceAccountNamespace() == "" { return options.FlagIsRequiredError(options.ServiceAccountNamespace.Flag) } if createData.ServiceAccountName() == "" { return options.FlagIsRequiredError(options.ServiceAccountName.Flag) } minTokenExpirationDuration := time.Duration(webhook.MinServiceAccountTokenExpiration) * time.Second maxTokenExpirationDuration := time.Duration(webhook.MaxServiceAccountTokenExpiration) * time.Second if createData.ServiceAccountTokenExpiration() < minTokenExpirationDuration { return errors.Errorf("--service-account-token-expiration must be greater than or equal to %s", minTokenExpirationDuration.String()) } if createData.ServiceAccountTokenExpiration() > maxTokenExpirationDuration { return errors.Errorf("--service-account-token-expiration must be less than or equal to %s", maxTokenExpirationDuration.String()) } var err error if p.kubeClient, err = createData.KubeClient(); err != nil { return errors.Wrap(err, "failed to get kubernetes client") } return nil } func (p *serviceAccountPhase) run(ctx context.Context, data workflow.RunData) error { createData := data.(CreateData) // TODO(aramase) make the update behavior configurable. If the service account already exists, fail if --overwrite is not specified err := kuberneteshelper.CreateOrUpdateServiceAccount( ctx, p.kubeClient, createData.ServiceAccountNamespace(), createData.ServiceAccountName(), createData.AADApplicationClientID(), createData.AzureTenantID(), createData.ServiceAccountTokenExpiration(), ) if err != nil { return errors.Wrap(err, "failed to create kubernetes service account") } mlog.WithValues( "namespace", createData.ServiceAccountNamespace(), "name", createData.ServiceAccountName(), ).WithName(serviceAccountPhaseName).Info("created kubernetes service account") return nil }