constellation/cli/internal/cmd/iamcreateazure.go
Moritz Sanft e844ceb2b1
cli: adopt Cobra cli reference style (#997)
* adapt to Cobra CLI ref style

* linting

* change multi-line reference style

* lowercase short descriptions

* Revert "lowercase short descriptions"

This reverts commit 499dc3577a.

* use 2 newlines on long description and add dots

* mark required flags

* Update cli/internal/cmd/iamcreateaws.go

Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>

* Update cli/internal/cmd/upgradeexecute.go

Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>

* Update cli/internal/cmd/upgradeexecute.go

Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>

Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
2023-01-17 14:01:56 +01:00

172 lines
5.8 KiB
Go

/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package cmd
import (
"fmt"
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)
// newIAMCreateAzureCmd returns a new cobra.Command for the iam create azure command.
func newIAMCreateAzureCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "azure",
Short: "Create IAM configuration on Microsoft Azure for your Constellation cluster",
Long: "Create IAM configuration on Microsoft Azure for your Constellation cluster.",
Args: cobra.ExactArgs(0),
RunE: runIAMCreateAzure,
}
cmd.Flags().String("resourceGroup", "", "name prefix of the two resource groups your cluster / IAM resources will be created in (required)")
must(cobra.MarkFlagRequired(cmd.Flags(), "resourceGroup"))
cmd.Flags().String("region", "", "region the resources will be created in, e.g. westus (required)")
must(cobra.MarkFlagRequired(cmd.Flags(), "region"))
cmd.Flags().String("servicePrincipal", "", "name of the service principal that will be created (required)")
must(cobra.MarkFlagRequired(cmd.Flags(), "servicePrincipal"))
cmd.Flags().Bool("yes", false, "create the IAM configuration without further confirmation")
return cmd
}
func runIAMCreateAzure(cmd *cobra.Command, args []string) error {
spinner := newSpinner(cmd.ErrOrStderr())
defer spinner.Stop()
fileHandler := file.NewHandler(afero.NewOsFs())
creator := cloudcmd.NewIAMCreator(spinner)
return iamCreateAzure(cmd, spinner, creator, fileHandler)
}
func iamCreateAzure(cmd *cobra.Command, spinner spinnerInterf, creator iamCreator, fileHandler file.Handler) error {
// Get input variables.
azureFlags, err := parseAzureFlags(cmd)
if err != nil {
return err
}
// Confirmation.
if !azureFlags.yesFlag {
cmd.Printf("The following IAM configuration will be created:\n\n")
cmd.Printf("Region:\t\t\t%s\n", azureFlags.region)
cmd.Printf("Resource Group:\t\t%s\n", azureFlags.resourceGroup)
cmd.Printf("Service Principal:\t%s\n\n", azureFlags.servicePrincipal)
if azureFlags.generateConfig {
cmd.Printf("The configuration file %s will be automatically generated and populated with the IAM values.\n", azureFlags.configPath)
}
ok, err := askToConfirm(cmd, "Do you want to create the configuration?")
if err != nil {
return err
}
if !ok {
cmd.Println("The creation of the configuration was aborted.")
return nil
}
}
// Creation.
spinner.Start("Creating", false)
conf := createConfig(cloudprovider.Azure)
iamFile, err := creator.Create(cmd.Context(), cloudprovider.Azure, &cloudcmd.IAMConfig{
Azure: cloudcmd.AzureIAMConfig{
Region: azureFlags.region,
ServicePrincipal: azureFlags.servicePrincipal,
ResourceGroup: azureFlags.resourceGroup,
},
})
spinner.Stop()
if err != nil {
return err
}
cmd.Println() // Print empty line to separate after spinner ended.
if azureFlags.generateConfig {
conf.Provider.Azure.SubscriptionID = iamFile.AzureOutput.SubscriptionID
conf.Provider.Azure.TenantID = iamFile.AzureOutput.TenantID
conf.Provider.Azure.Location = azureFlags.region
conf.Provider.Azure.ResourceGroup = azureFlags.resourceGroup
conf.Provider.Azure.UserAssignedIdentity = iamFile.AzureOutput.UAMIID
conf.Provider.Azure.AppClientID = iamFile.AzureOutput.ApplicationID
conf.Provider.Azure.ClientSecretValue = iamFile.AzureOutput.ApplicationClientSecretValue
if err := fileHandler.WriteYAML(azureFlags.configPath, conf, file.OptMkdirAll); err != nil {
return err
}
cmd.Printf("Your IAM configuration was created and filled into %s successfully.\n", azureFlags.configPath)
return nil
}
cmd.Printf("subscription:\t\t%s\n", iamFile.AzureOutput.SubscriptionID)
cmd.Printf("tenant:\t\t\t%s\n", iamFile.AzureOutput.TenantID)
cmd.Printf("location:\t\t%s\n", azureFlags.region)
cmd.Printf("resourceGroup:\t\t%s\n", azureFlags.resourceGroup)
cmd.Printf("userAssignedIdentity:\t%s\n", iamFile.AzureOutput.UAMIID)
cmd.Printf("appClientID:\t\t%s\n", iamFile.AzureOutput.ApplicationID)
cmd.Printf("appClientSecretValue:\t%s\n\n", iamFile.AzureOutput.ApplicationClientSecretValue)
cmd.Println("Your IAM configuration was created successfully. Please fill the above values into your configuration file.")
return nil
}
// parseAzureFlags parses and validates the flags of the iam create azure command.
func parseAzureFlags(cmd *cobra.Command) (azureFlags, error) {
region, err := cmd.Flags().GetString("region")
if err != nil {
return azureFlags{}, fmt.Errorf("parsing region string: %w", err)
}
resourceGroup, err := cmd.Flags().GetString("resourceGroup")
if err != nil {
return azureFlags{}, fmt.Errorf("parsing resourceGroup string: %w", err)
}
servicePrincipal, err := cmd.Flags().GetString("servicePrincipal")
if err != nil {
return azureFlags{}, fmt.Errorf("parsing servicePrincipal string: %w", err)
}
configPath, err := cmd.Flags().GetString("config")
if err != nil {
return azureFlags{}, fmt.Errorf("parsing config string: %w", err)
}
generateConfig, err := cmd.Flags().GetBool("generate-config")
if err != nil {
return azureFlags{}, fmt.Errorf("parsing generate-config bool: %w", err)
}
yesFlag, err := cmd.Flags().GetBool("yes")
if err != nil {
return azureFlags{}, fmt.Errorf("parsing yes bool: %w", err)
}
return azureFlags{
servicePrincipal: servicePrincipal,
resourceGroup: resourceGroup,
region: region,
generateConfig: generateConfig,
configPath: configPath,
yesFlag: yesFlag,
}, nil
}
// azureFlags contains the parsed flags of the iam create azure command.
type azureFlags struct {
region string
resourceGroup string
servicePrincipal string
generateConfig bool
configPath string
yesFlag bool
}