2022-12-07 05:48:54 -05:00
/ *
Copyright ( c ) Edgeless Systems GmbH
SPDX - License - Identifier : AGPL - 3.0 - only
* /
package cmd
import (
"fmt"
"strings"
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
2023-01-12 05:35:26 -05:00
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/spf13/afero"
2022-12-07 05:48:54 -05:00
"github.com/spf13/cobra"
)
// newIAMCreateAWSCmd returns a new cobra.Command for the iam create aws command.
func newIAMCreateAWSCmd ( ) * cobra . Command {
cmd := & cobra . Command {
Use : "aws" ,
Short : "Create IAM configuration on AWS for your Constellation cluster" ,
Long : "Create IAM configuration on AWS for your Constellation cluster." ,
Args : cobra . ExactArgs ( 0 ) ,
RunE : runIAMCreateAWS ,
}
2023-01-17 08:01:56 -05:00
cmd . Flags ( ) . String ( "prefix" , "" , "name prefix for all resources (required)" )
2022-12-07 05:48:54 -05:00
must ( cobra . MarkFlagRequired ( cmd . Flags ( ) , "prefix" ) )
2023-01-17 08:01:56 -05:00
cmd . Flags ( ) . String ( "zone" , "" , "AWS availability zone the resources will be created in, e.g. us-east-2a (required)\n" +
"Find available zones here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-availability-zones. " +
"Note that we do not support every zone / region. You can find a list of all supported regions in our docs." )
2022-12-07 05:48:54 -05:00
must ( cobra . MarkFlagRequired ( cmd . Flags ( ) , "zone" ) )
2023-01-17 08:01:56 -05:00
cmd . Flags ( ) . Bool ( "yes" , false , "create the IAM configuration without further confirmation" )
2022-12-07 05:48:54 -05:00
return cmd
}
func runIAMCreateAWS ( cmd * cobra . Command , args [ ] string ) error {
spinner := newSpinner ( cmd . ErrOrStderr ( ) )
defer spinner . Stop ( )
2023-01-12 05:35:26 -05:00
fileHandler := file . NewHandler ( afero . NewOsFs ( ) )
2022-12-07 05:48:54 -05:00
creator := cloudcmd . NewIAMCreator ( spinner )
2023-01-12 05:35:26 -05:00
return iamCreateAWS ( cmd , spinner , creator , fileHandler )
2022-12-07 05:48:54 -05:00
}
2023-01-12 05:35:26 -05:00
func iamCreateAWS ( cmd * cobra . Command , spinner spinnerInterf , creator iamCreator , fileHandler file . Handler ) error {
2022-12-07 05:48:54 -05:00
// Get input variables.
awsFlags , err := parseAWSFlags ( cmd )
if err != nil {
return err
}
// Confirmation.
if ! awsFlags . yesFlag {
2023-01-12 05:35:26 -05:00
cmd . Printf ( "The following IAM configuration will be created:\n\n" )
cmd . Printf ( "Region:\t\t%s\n" , awsFlags . region )
cmd . Printf ( "Name Prefix:\t%s\n\n" , awsFlags . prefix )
if awsFlags . generateConfig {
cmd . Printf ( "The configuration file %s will be automatically generated and populated with the IAM values.\n" , awsFlags . configPath )
}
2022-12-07 05:48:54 -05:00
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 )
2023-01-12 05:35:26 -05:00
conf := createConfig ( cloudprovider . AWS )
2022-12-07 05:48:54 -05:00
iamFile , err := creator . Create ( cmd . Context ( ) , cloudprovider . AWS , & cloudcmd . IAMConfig {
AWS : cloudcmd . AWSIAMConfig {
Region : awsFlags . region ,
Prefix : awsFlags . prefix ,
} ,
} )
2023-01-12 05:35:26 -05:00
2022-12-07 05:48:54 -05:00
spinner . Stop ( )
if err != nil {
return err
}
2023-01-12 05:35:26 -05:00
cmd . Println ( ) // Print empty line to separate after spinner ended.
if awsFlags . generateConfig {
conf . Provider . AWS . Region = awsFlags . region
conf . Provider . AWS . Zone = awsFlags . zone
conf . Provider . AWS . IAMProfileControlPlane = iamFile . AWSOutput . ControlPlaneInstanceProfile
conf . Provider . AWS . IAMProfileWorkerNodes = iamFile . AWSOutput . WorkerNodeInstanceProfile
if err := fileHandler . WriteYAML ( awsFlags . configPath , conf , file . OptMkdirAll ) ; err != nil {
return err
}
cmd . Printf ( "Your IAM configuration was created and filled into %s successfully.\n" , awsFlags . configPath )
return nil
}
2022-12-07 05:48:54 -05:00
2023-01-12 05:35:26 -05:00
cmd . Printf ( "region:\t\t\t%s\n" , awsFlags . region )
cmd . Printf ( "zone:\t\t\t%s\n" , awsFlags . zone )
2022-12-07 05:48:54 -05:00
cmd . Printf ( "iamProfileControlPlane:\t%s\n" , iamFile . AWSOutput . ControlPlaneInstanceProfile )
2023-01-12 05:35:26 -05:00
cmd . Printf ( "iamProfileWorkerNodes:\t%s\n\n" , iamFile . AWSOutput . WorkerNodeInstanceProfile )
2022-12-07 05:48:54 -05:00
cmd . Println ( "Your IAM configuration was created successfully. Please fill the above values into your configuration file." )
return nil
}
// parseAWSFlags parses and validates the flags of the iam create aws command.
func parseAWSFlags ( cmd * cobra . Command ) ( awsFlags , error ) {
var region string
prefix , err := cmd . Flags ( ) . GetString ( "prefix" )
if err != nil {
return awsFlags { } , fmt . Errorf ( "parsing prefix string: %w" , err )
}
zone , err := cmd . Flags ( ) . GetString ( "zone" )
if err != nil {
return awsFlags { } , fmt . Errorf ( "parsing zone string: %w" , err )
}
if strings . HasPrefix ( zone , "eu-central-1" ) {
region = "eu-central-1"
} else if strings . HasPrefix ( zone , "us-east-2" ) {
region = "us-east-2"
} else if strings . HasPrefix ( zone , "ap-south-1" ) {
region = "ap-south-1"
} else {
return awsFlags { } , fmt . Errorf ( "invalid AWS region, to find a correct region please refer to our docs and https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-availability-zones" )
}
2023-01-12 05:35:26 -05:00
configPath , err := cmd . Flags ( ) . GetString ( "config" )
if err != nil {
return awsFlags { } , fmt . Errorf ( "parsing config string: %w" , err )
}
generateConfig , err := cmd . Flags ( ) . GetBool ( "generate-config" )
if err != nil {
return awsFlags { } , fmt . Errorf ( "parsing generate-config bool: %w" , err )
}
2022-12-07 05:48:54 -05:00
yesFlag , err := cmd . Flags ( ) . GetBool ( "yes" )
if err != nil {
return awsFlags { } , fmt . Errorf ( "parsing yes bool: %w" , err )
}
return awsFlags {
2023-01-12 05:35:26 -05:00
zone : zone ,
prefix : prefix ,
region : region ,
generateConfig : generateConfig ,
configPath : configPath ,
yesFlag : yesFlag ,
2022-12-07 05:48:54 -05:00
} , nil
}
// awsFlags contains the parsed flags of the iam create aws command.
type awsFlags struct {
2023-01-12 05:35:26 -05:00
prefix string
region string
zone string
generateConfig bool
configPath string
yesFlag bool
2022-12-07 05:48:54 -05:00
}