Move workspace path functions to sub-package of cmd

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2023-08-08 15:42:06 +02:00 committed by Daniel Weiße
parent 99c579b45a
commit 89b342900f
21 changed files with 213 additions and 189 deletions

View file

@ -14,6 +14,7 @@ import (
"strings"
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
"github.com/edgelesssys/constellation/v2/cli/internal/cmd/pathprefix"
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/config"
@ -129,15 +130,15 @@ func newIAMCreateGCPCmd() *cobra.Command {
// createRunIAMFunc is the entrypoint for the iam create command. It sets up the iamCreator
// and starts IAM creation for the specific cloud provider.
func createRunIAMFunc(provider cloudprovider.Provider) func(cmd *cobra.Command, args []string) error {
var providerCreator func(workspace string) providerIAMCreator
var providerCreator func(pf pathprefix.PathPrefixer) providerIAMCreator
switch provider {
case cloudprovider.AWS:
providerCreator = func(string) providerIAMCreator { return &awsIAMCreator{} }
providerCreator = func(pathprefix.PathPrefixer) providerIAMCreator { return &awsIAMCreator{} }
case cloudprovider.Azure:
providerCreator = func(string) providerIAMCreator { return &azureIAMCreator{} }
providerCreator = func(pathprefix.PathPrefixer) providerIAMCreator { return &azureIAMCreator{} }
case cloudprovider.GCP:
providerCreator = func(workspace string) providerIAMCreator {
return &gcpIAMCreator{workspace}
providerCreator = func(pf pathprefix.PathPrefixer) providerIAMCreator {
return &gcpIAMCreator{pf}
}
default:
return func(cmd *cobra.Command, args []string) error {
@ -154,25 +155,26 @@ func createRunIAMFunc(provider cloudprovider.Provider) func(cmd *cobra.Command,
if err != nil {
return fmt.Errorf("parsing Terraform log level %s: %w", logLevelString, err)
}
workspace, err := cmd.Flags().GetString("workspace")
workDir, err := cmd.Flags().GetString("workspace")
if err != nil {
return fmt.Errorf("parsing workspace string: %w", err)
}
pf := pathprefix.New(workDir)
iamCreator, err := newIAMCreator(cmd, workspace, logLevel)
iamCreator, err := newIAMCreator(cmd, pf, logLevel)
if err != nil {
return fmt.Errorf("creating iamCreator: %w", err)
}
defer iamCreator.spinner.Stop()
defer iamCreator.log.Sync()
iamCreator.provider = provider
iamCreator.providerCreator = providerCreator(workspace)
iamCreator.providerCreator = providerCreator(pf)
return iamCreator.create(cmd.Context())
}
}
// newIAMCreator creates a new iamiamCreator.
func newIAMCreator(cmd *cobra.Command, workspace string, logLevel terraform.LogLevel) (*iamCreator, error) {
func newIAMCreator(cmd *cobra.Command, pf pathprefix.PathPrefixer, logLevel terraform.LogLevel) (*iamCreator, error) {
spinner, err := newSpinnerOrStderr(cmd)
if err != nil {
return nil, fmt.Errorf("creating spinner: %w", err)
@ -181,7 +183,7 @@ func newIAMCreator(cmd *cobra.Command, workspace string, logLevel terraform.LogL
if err != nil {
return nil, fmt.Errorf("creating logger: %w", err)
}
log.Debugf("Terraform logs will be written into %s at level %s", terraformLogPath(workspace), logLevel.String())
log.Debugf("Terraform logs will be written into %s at level %s", pf.PrefixPath(constants.TerraformLogFile), logLevel.String())
return &iamCreator{
cmd: cmd,
@ -206,6 +208,7 @@ type iamCreator struct {
providerCreator providerIAMCreator
iamConfig *cloudcmd.IAMConfigOptions
log debugLog
pf pathprefix.PathPrefixer
}
// create IAM configuration on the iamCreator's cloud provider.
@ -216,7 +219,7 @@ func (c *iamCreator) create(ctx context.Context) error {
}
c.log.Debugf("Using flags: %+v", flags)
if err := c.checkWorkingDir(flags.workspace); err != nil {
if err := c.checkWorkingDir(); err != nil {
return err
}
@ -235,14 +238,14 @@ func (c *iamCreator) create(ctx context.Context) error {
var conf config.Config
if flags.updateConfig {
c.log.Debugf("Parsing config %s", configPath(flags.workspace))
c.log.Debugf("Parsing config %s", c.pf.PrefixPath(constants.ConfigFilename))
if err = c.fileHandler.ReadYAML(constants.ConfigFilename, &conf); err != nil {
return fmt.Errorf("error reading the configuration file: %w", err)
}
if err := validateConfigWithFlagCompatibility(c.provider, conf, flags); err != nil {
return err
}
c.cmd.Printf("The configuration file %q will be automatically updated with the IAM values and zone/region information.\n", configPath(flags.workspace))
c.cmd.Printf("The configuration file %q will be automatically updated with the IAM values and zone/region information.\n", c.pf.PrefixPath(constants.ConfigFilename))
}
c.spinner.Start("Creating", false)
@ -260,12 +263,12 @@ func (c *iamCreator) create(ctx context.Context) error {
}
if flags.updateConfig {
c.log.Debugf("Writing IAM configuration to %s", configPath(flags.workspace))
c.log.Debugf("Writing IAM configuration to %s", c.pf.PrefixPath(constants.ConfigFilename))
c.providerCreator.writeOutputValuesToConfig(&conf, flags, iamFile)
if err := c.fileHandler.WriteYAML(constants.ConfigFilename, conf, file.OptOverwrite); err != nil {
return err
}
c.cmd.Printf("Your IAM configuration was created and filled into %s successfully.\n", configPath(flags.workspace))
c.cmd.Printf("Your IAM configuration was created and filled into %s successfully.\n", c.pf.PrefixPath(constants.ConfigFilename))
return nil
}
@ -277,10 +280,12 @@ func (c *iamCreator) create(ctx context.Context) error {
// parseFlagsAndSetupConfig parses the flags of the iam create command and fills the values into the IAM config (output values of the command).
func (c *iamCreator) parseFlagsAndSetupConfig() (iamFlags, error) {
cwd, err := c.cmd.Flags().GetString("workspace")
workDir, err := c.cmd.Flags().GetString("workspace")
if err != nil {
return iamFlags{}, fmt.Errorf("parsing config string: %w", err)
}
c.pf = pathprefix.New(workDir)
yesFlag, err := c.cmd.Flags().GetBool("yes")
if err != nil {
return iamFlags{}, fmt.Errorf("parsing yes bool: %w", err)
@ -291,7 +296,6 @@ func (c *iamCreator) parseFlagsAndSetupConfig() (iamFlags, error) {
}
flags := iamFlags{
workspace: cwd,
yesFlag: yesFlag,
updateConfig: updateConfig,
}
@ -305,9 +309,9 @@ func (c *iamCreator) parseFlagsAndSetupConfig() (iamFlags, error) {
}
// checkWorkingDir checks if the current working directory already contains a Terraform dir.
func (c *iamCreator) checkWorkingDir(workspace string) error {
func (c *iamCreator) checkWorkingDir() error {
if _, err := c.fileHandler.Stat(constants.TerraformIAMWorkingDir); err == nil {
return fmt.Errorf("the current working directory already contains the Terraform workspace directory %q. Please run the command in a different directory or destroy the existing workspace", terraformIAMWorkspace(workspace))
return fmt.Errorf("the current working directory already contains the Terraform workspace directory %q. Please run the command in a different directory or destroy the existing workspace", c.pf.PrefixPath(constants.TerraformIAMWorkingDir))
}
return nil
}
@ -317,7 +321,6 @@ type iamFlags struct {
aws awsFlags
azure azureFlags
gcp gcpFlags
workspace string
yesFlag bool
updateConfig bool
}
@ -488,7 +491,7 @@ func (c *azureIAMCreator) parseAndWriteIDFile(_ cloudcmd.IAMOutput, _ file.Handl
// gcpIAMCreator implements the providerIAMCreator interface for GCP.
type gcpIAMCreator struct {
workspace string
pf pathprefix.PathPrefixer
}
func (c *gcpIAMCreator) parseFlagsAndSetupConfig(cmd *cobra.Command, flags iamFlags, iamConfig *cloudcmd.IAMConfigOptions) (iamFlags, error) {
@ -552,12 +555,12 @@ func (c *gcpIAMCreator) printOutputValues(cmd *cobra.Command, flags iamFlags, _
cmd.Printf("projectID:\t\t%s\n", flags.gcp.projectID)
cmd.Printf("region:\t\t\t%s\n", flags.gcp.region)
cmd.Printf("zone:\t\t\t%s\n", flags.gcp.zone)
cmd.Printf("serviceAccountKeyPath:\t%s\n\n", gcpServiceAccountKeyPath(c.workspace))
cmd.Printf("serviceAccountKeyPath:\t%s\n\n", c.pf.PrefixPath(constants.GCPServiceAccountKeyFilename))
}
func (c *gcpIAMCreator) writeOutputValuesToConfig(conf *config.Config, flags iamFlags, _ cloudcmd.IAMOutput) {
conf.Provider.GCP.Project = flags.gcp.projectID
conf.Provider.GCP.ServiceAccountKeyPath = gcpServiceAccountKeyFile // File was created in workspace, so only the filename is needed.
conf.Provider.GCP.ServiceAccountKeyPath = constants.GCPServiceAccountKeyFilename // File was created in workspace, so only the filename is needed.
conf.Provider.GCP.Region = flags.gcp.region
conf.Provider.GCP.Zone = flags.gcp.zone
for groupName, group := range conf.NodeGroups {
@ -573,7 +576,7 @@ func (c *gcpIAMCreator) parseAndWriteIDFile(iamFile cloudcmd.IAMOutput, fileHand
return err
}
return fileHandler.WriteJSON(gcpServiceAccountKeyFile, tmpOut, file.OptNone)
return fileHandler.WriteJSON(constants.GCPServiceAccountKeyFilename, tmpOut, file.OptNone)
}
// parseIDFile parses the given base64 encoded JSON string of the GCP service account key and returns a map.