mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-06-05 13:19:35 -04:00
Move workspace path functions to sub-package of cmd
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
99c579b45a
commit
89b342900f
21 changed files with 213 additions and 189 deletions
|
@ -36,7 +36,6 @@ go_library(
|
||||||
"validargs.go",
|
"validargs.go",
|
||||||
"verify.go",
|
"verify.go",
|
||||||
"version.go",
|
"version.go",
|
||||||
"workspace.go",
|
|
||||||
],
|
],
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/cli/internal/cmd",
|
importpath = "github.com/edgelesssys/constellation/v2/cli/internal/cmd",
|
||||||
visibility = ["//cli:__subpackages__"],
|
visibility = ["//cli:__subpackages__"],
|
||||||
|
@ -44,6 +43,7 @@ go_library(
|
||||||
"//bootstrapper/initproto",
|
"//bootstrapper/initproto",
|
||||||
"//cli/internal/cloudcmd",
|
"//cli/internal/cloudcmd",
|
||||||
"//cli/internal/clusterid",
|
"//cli/internal/clusterid",
|
||||||
|
"//cli/internal/cmd/pathprefix",
|
||||||
"//cli/internal/featureset",
|
"//cli/internal/featureset",
|
||||||
"//cli/internal/helm",
|
"//cli/internal/helm",
|
||||||
"//cli/internal/kubernetes",
|
"//cli/internal/kubernetes",
|
||||||
|
@ -140,6 +140,7 @@ go_test(
|
||||||
"//bootstrapper/initproto",
|
"//bootstrapper/initproto",
|
||||||
"//cli/internal/cloudcmd",
|
"//cli/internal/cloudcmd",
|
||||||
"//cli/internal/clusterid",
|
"//cli/internal/clusterid",
|
||||||
|
"//cli/internal/cmd/pathprefix",
|
||||||
"//cli/internal/helm",
|
"//cli/internal/helm",
|
||||||
"//cli/internal/kubernetes",
|
"//cli/internal/kubernetes",
|
||||||
"//cli/internal/terraform",
|
"//cli/internal/terraform",
|
||||||
|
|
|
@ -12,9 +12,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/cmd/pathprefix"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/featureset"
|
"github.com/edgelesssys/constellation/v2/cli/internal/featureset"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
|
@ -50,7 +50,7 @@ type fetchMeasurementsFlags struct {
|
||||||
signatureURL *url.URL
|
signatureURL *url.URL
|
||||||
insecure bool
|
insecure bool
|
||||||
force bool
|
force bool
|
||||||
workspace string
|
pf pathprefix.PathPrefixer
|
||||||
}
|
}
|
||||||
|
|
||||||
type configFetchMeasurementsCmd struct {
|
type configFetchMeasurementsCmd struct {
|
||||||
|
@ -90,7 +90,7 @@ func (cfm *configFetchMeasurementsCmd) configFetchMeasurements(
|
||||||
return errors.New("fetching measurements is not supported")
|
return errors.New("fetching measurements is not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
cfm.log.Debugf("Loading configuration file from %q", filepath.Join(flags.workspace, constants.ConfigFilename))
|
cfm.log.Debugf("Loading configuration file from %q", flags.pf.PrefixPath(constants.ConfigFilename))
|
||||||
|
|
||||||
conf, err := config.New(fileHandler, constants.ConfigFilename, fetcher, flags.force)
|
conf, err := config.New(fileHandler, constants.ConfigFilename, fetcher, flags.force)
|
||||||
var configValidationErr *config.ValidationError
|
var configValidationErr *config.ValidationError
|
||||||
|
@ -173,7 +173,7 @@ func (cfm *configFetchMeasurementsCmd) configFetchMeasurements(
|
||||||
if err := fileHandler.WriteYAML(constants.ConfigFilename, conf, file.OptOverwrite); err != nil {
|
if err := fileHandler.WriteYAML(constants.ConfigFilename, conf, file.OptOverwrite); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cfm.log.Debugf("Configuration written to %s", configPath(flags.workspace))
|
cfm.log.Debugf("Configuration written to %s", flags.pf.PrefixPath(constants.ConfigFilename))
|
||||||
cmd.Print("Successfully fetched measurements and updated Configuration\n")
|
cmd.Print("Successfully fetched measurements and updated Configuration\n")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ func (cfm *configFetchMeasurementsCmd) parseURLFlag(cmd *cobra.Command, flag str
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfm *configFetchMeasurementsCmd) parseFetchMeasurementsFlags(cmd *cobra.Command) (*fetchMeasurementsFlags, error) {
|
func (cfm *configFetchMeasurementsCmd) parseFetchMeasurementsFlags(cmd *cobra.Command) (*fetchMeasurementsFlags, error) {
|
||||||
workspace, err := cmd.Flags().GetString("workspace")
|
workDir, err := cmd.Flags().GetString("workspace")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parsing workspace argument: %w", err)
|
return nil, fmt.Errorf("parsing workspace argument: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ func (cfm *configFetchMeasurementsCmd) parseFetchMeasurementsFlags(cmd *cobra.Co
|
||||||
signatureURL: measurementsSignatureURL,
|
signatureURL: measurementsSignatureURL,
|
||||||
insecure: insecure,
|
insecure: insecure,
|
||||||
force: force,
|
force: force,
|
||||||
workspace: workspace,
|
pf: pathprefix.New(workDir),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/cmd/pathprefix"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
||||||
|
@ -41,7 +42,7 @@ func newConfigGenerateCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
type generateFlags struct {
|
type generateFlags struct {
|
||||||
workspace string
|
pf pathprefix.PathPrefixer
|
||||||
k8sVersion string
|
k8sVersion string
|
||||||
attestationVariant variant.Variant
|
attestationVariant variant.Variant
|
||||||
}
|
}
|
||||||
|
@ -80,7 +81,7 @@ func (cg *configGenerateCmd) configGenerate(cmd *cobra.Command, fileHandler file
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Config file written to", configPath(flags.workspace))
|
cmd.Println("Config file written to", flags.pf.PrefixPath(constants.ConfigFilename))
|
||||||
cmd.Println("Please fill in your CSP-specific configuration before proceeding.")
|
cmd.Println("Please fill in your CSP-specific configuration before proceeding.")
|
||||||
cmd.Println("For more information refer to the documentation:")
|
cmd.Println("For more information refer to the documentation:")
|
||||||
cmd.Println("\thttps://docs.edgeless.systems/constellation/getting-started/first-steps")
|
cmd.Println("\thttps://docs.edgeless.systems/constellation/getting-started/first-steps")
|
||||||
|
@ -137,7 +138,7 @@ func supportedVersions() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseGenerateFlags(cmd *cobra.Command) (generateFlags, error) {
|
func parseGenerateFlags(cmd *cobra.Command) (generateFlags, error) {
|
||||||
workspace, err := cmd.Flags().GetString("workspace")
|
workDir, err := cmd.Flags().GetString("workspace")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return generateFlags{}, fmt.Errorf("parsing workspace flag: %w", err)
|
return generateFlags{}, fmt.Errorf("parsing workspace flag: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -166,7 +167,7 @@ func parseGenerateFlags(cmd *cobra.Command) (generateFlags, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return generateFlags{
|
return generateFlags{
|
||||||
workspace: workspace,
|
pf: pathprefix.New(workDir),
|
||||||
k8sVersion: resolvedVersion,
|
k8sVersion: resolvedVersion,
|
||||||
attestationVariant: attestationVariant,
|
attestationVariant: attestationVariant,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
"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/cli/internal/terraform"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
|
@ -44,6 +45,7 @@ func NewCreateCmd() *cobra.Command {
|
||||||
|
|
||||||
type createCmd struct {
|
type createCmd struct {
|
||||||
log debugLog
|
log debugLog
|
||||||
|
pf pathprefix.PathPrefixer
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCreate(cmd *cobra.Command, _ []string) error {
|
func runCreate(cmd *cobra.Command, _ []string) error {
|
||||||
|
@ -71,11 +73,11 @@ func (c *createCmd) create(cmd *cobra.Command, creator cloudCreator, fileHandler
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.log.Debugf("Using flags: %+v", flags)
|
c.log.Debugf("Using flags: %+v", flags)
|
||||||
if err := c.checkDirClean(flags.workspace, fileHandler); err != nil {
|
if err := c.checkDirClean(fileHandler); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log.Debugf("Loading configuration file from %q", configPath(flags.workspace))
|
c.log.Debugf("Loading configuration file from %q", c.pf.PrefixPath(constants.ConfigFilename))
|
||||||
conf, err := config.New(fileHandler, constants.ConfigFilename, fetcher, flags.force)
|
conf, err := config.New(fileHandler, constants.ConfigFilename, fetcher, flags.force)
|
||||||
c.log.Debugf("Configuration file loaded: %+v", conf)
|
c.log.Debugf("Configuration file loaded: %+v", conf)
|
||||||
var configValidationErr *config.ValidationError
|
var configValidationErr *config.ValidationError
|
||||||
|
@ -168,7 +170,7 @@ func (c *createCmd) create(cmd *cobra.Command, creator cloudCreator, fileHandler
|
||||||
idFile, err := creator.Create(cmd.Context(), opts)
|
idFile, err := creator.Create(cmd.Context(), opts)
|
||||||
spinner.Stop()
|
spinner.Stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return translateCreateErrors(cmd, flags.workspace, err)
|
return translateCreateErrors(cmd, c.pf, err)
|
||||||
}
|
}
|
||||||
c.log.Debugf("Successfully created the cloud resources for the cluster")
|
c.log.Debugf("Successfully created the cloud resources for the cluster")
|
||||||
|
|
||||||
|
@ -188,11 +190,12 @@ func (c *createCmd) parseCreateFlags(cmd *cobra.Command) (createFlags, error) {
|
||||||
}
|
}
|
||||||
c.log.Debugf("Yes flag is %t", yes)
|
c.log.Debugf("Yes flag is %t", yes)
|
||||||
|
|
||||||
workspace, err := cmd.Flags().GetString("workspace")
|
workDir, err := cmd.Flags().GetString("workspace")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return createFlags{}, fmt.Errorf("parsing config path argument: %w", err)
|
return createFlags{}, fmt.Errorf("parsing config path argument: %w", err)
|
||||||
}
|
}
|
||||||
c.log.Debugf("Workspace set to %q", workspace)
|
c.log.Debugf("Workspace set to %q", workDir)
|
||||||
|
c.pf = pathprefix.New(workDir)
|
||||||
|
|
||||||
force, err := cmd.Flags().GetBool("force")
|
force, err := cmd.Flags().GetBool("force")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -208,10 +211,9 @@ func (c *createCmd) parseCreateFlags(cmd *cobra.Command) (createFlags, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return createFlags{}, fmt.Errorf("parsing Terraform log level %s: %w", logLevelString, err)
|
return createFlags{}, fmt.Errorf("parsing Terraform log level %s: %w", logLevelString, err)
|
||||||
}
|
}
|
||||||
c.log.Debugf("Terraform logs will be written into %s at level %s", terraformLogPath(workspace), logLevel.String())
|
c.log.Debugf("Terraform logs will be written into %s at level %s", c.pf.PrefixPath(constants.TerraformLogFile), logLevel.String())
|
||||||
|
|
||||||
return createFlags{
|
return createFlags{
|
||||||
workspace: workspace,
|
|
||||||
tfLogLevel: logLevel,
|
tfLogLevel: logLevel,
|
||||||
force: force,
|
force: force,
|
||||||
yes: yes,
|
yes: yes,
|
||||||
|
@ -220,44 +222,43 @@ func (c *createCmd) parseCreateFlags(cmd *cobra.Command) (createFlags, error) {
|
||||||
|
|
||||||
// createFlags contains the parsed flags of the create command.
|
// createFlags contains the parsed flags of the create command.
|
||||||
type createFlags struct {
|
type createFlags struct {
|
||||||
workspace string
|
|
||||||
tfLogLevel terraform.LogLevel
|
tfLogLevel terraform.LogLevel
|
||||||
force bool
|
force bool
|
||||||
yes bool
|
yes bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkDirClean checks if files of a previous Constellation are left in the current working dir.
|
// checkDirClean checks if files of a previous Constellation are left in the current working dir.
|
||||||
func (c *createCmd) checkDirClean(workspace string, fileHandler file.Handler) error {
|
func (c *createCmd) checkDirClean(fileHandler file.Handler) error {
|
||||||
c.log.Debugf("Checking admin configuration file")
|
c.log.Debugf("Checking admin configuration file")
|
||||||
if _, err := fileHandler.Stat(constants.AdminConfFilename); !errors.Is(err, fs.ErrNotExist) {
|
if _, err := fileHandler.Stat(constants.AdminConfFilename); !errors.Is(err, fs.ErrNotExist) {
|
||||||
return fmt.Errorf("file '%s' already exists in working directory, run 'constellation terminate' before creating a new one", adminConfPath(workspace))
|
return fmt.Errorf("file '%s' already exists in working directory, run 'constellation terminate' before creating a new one", c.pf.PrefixPath(constants.AdminConfFilename))
|
||||||
}
|
}
|
||||||
c.log.Debugf("Checking master secrets file")
|
c.log.Debugf("Checking master secrets file")
|
||||||
if _, err := fileHandler.Stat(constants.MasterSecretFilename); !errors.Is(err, fs.ErrNotExist) {
|
if _, err := fileHandler.Stat(constants.MasterSecretFilename); !errors.Is(err, fs.ErrNotExist) {
|
||||||
return fmt.Errorf("file '%s' already exists in working directory. Constellation won't overwrite previous master secrets. Move it somewhere or delete it before creating a new cluster", masterSecretPath(workspace))
|
return fmt.Errorf("file '%s' already exists in working directory. Constellation won't overwrite previous master secrets. Move it somewhere or delete it before creating a new cluster", c.pf.PrefixPath(constants.MasterSecretFilename))
|
||||||
}
|
}
|
||||||
c.log.Debugf("Checking cluster IDs file")
|
c.log.Debugf("Checking cluster IDs file")
|
||||||
if _, err := fileHandler.Stat(constants.ClusterIDsFilename); !errors.Is(err, fs.ErrNotExist) {
|
if _, err := fileHandler.Stat(constants.ClusterIDsFilename); !errors.Is(err, fs.ErrNotExist) {
|
||||||
return fmt.Errorf("file '%s' already exists in working directory. Constellation won't overwrite previous cluster IDs. Move it somewhere or delete it before creating a new cluster", clusterIDsPath(workspace))
|
return fmt.Errorf("file '%s' already exists in working directory. Constellation won't overwrite previous cluster IDs. Move it somewhere or delete it before creating a new cluster", c.pf.PrefixPath(constants.ClusterIDsFilename))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func translateCreateErrors(cmd *cobra.Command, workspace string, err error) error {
|
func translateCreateErrors(cmd *cobra.Command, pf pathprefix.PathPrefixer, err error) error {
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(err, terraform.ErrTerraformWorkspaceDifferentFiles):
|
case errors.Is(err, terraform.ErrTerraformWorkspaceDifferentFiles):
|
||||||
cmd.PrintErrln("\nYour current working directory contains an existing Terraform workspace which does not match the expected state.")
|
cmd.PrintErrln("\nYour current working directory contains an existing Terraform workspace which does not match the expected state.")
|
||||||
cmd.PrintErrln("This can be due to a mix up between providers, versions or an otherwise corrupted workspace.")
|
cmd.PrintErrln("This can be due to a mix up between providers, versions or an otherwise corrupted workspace.")
|
||||||
cmd.PrintErrln("Before creating a new cluster, try \"constellation terminate\".")
|
cmd.PrintErrln("Before creating a new cluster, try \"constellation terminate\".")
|
||||||
cmd.PrintErrf("If this does not work, either move or delete the directory %q.\n", terraformClusterWorkspace(workspace))
|
cmd.PrintErrf("If this does not work, either move or delete the directory %q.\n", pf.PrefixPath(constants.TerraformWorkingDir))
|
||||||
cmd.PrintErrln("Please only delete the directory if you made sure that all created cloud resources have been terminated.")
|
cmd.PrintErrln("Please only delete the directory if you made sure that all created cloud resources have been terminated.")
|
||||||
return err
|
return err
|
||||||
case errors.Is(err, terraform.ErrTerraformWorkspaceExistsWithDifferentVariables):
|
case errors.Is(err, terraform.ErrTerraformWorkspaceExistsWithDifferentVariables):
|
||||||
cmd.PrintErrln("\nYour current working directory contains an existing Terraform workspace which was initiated with different input variables.")
|
cmd.PrintErrln("\nYour current working directory contains an existing Terraform workspace which was initiated with different input variables.")
|
||||||
cmd.PrintErrln("This can be the case if you have tried to create a cluster before with different options which did not complete, or the workspace is corrupted.")
|
cmd.PrintErrln("This can be the case if you have tried to create a cluster before with different options which did not complete, or the workspace is corrupted.")
|
||||||
cmd.PrintErrln("Before creating a new cluster, try \"constellation terminate\".")
|
cmd.PrintErrln("Before creating a new cluster, try \"constellation terminate\".")
|
||||||
cmd.PrintErrf("If this does not work, either move or delete the directory %q.\n", terraformClusterWorkspace(workspace))
|
cmd.PrintErrf("If this does not work, either move or delete the directory %q.\n", pf.PrefixPath(constants.TerraformWorkingDir))
|
||||||
cmd.PrintErrln("Please only delete the directory if you made sure that all created cloud resources have been terminated.")
|
cmd.PrintErrln("Please only delete the directory if you made sure that all created cloud resources have been terminated.")
|
||||||
return err
|
return err
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -255,7 +255,7 @@ func TestCheckDirClean(t *testing.T) {
|
||||||
require.NoError(tc.fileHandler.Write(f, []byte{1, 2, 3}, file.OptNone))
|
require.NoError(tc.fileHandler.Write(f, []byte{1, 2, 3}, file.OptNone))
|
||||||
}
|
}
|
||||||
c := &createCmd{log: logger.NewTest(t)}
|
c := &createCmd{log: logger.NewTest(t)}
|
||||||
err := c.checkDirClean("", tc.fileHandler)
|
err := c.checkDirClean(tc.fileHandler)
|
||||||
|
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
"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/cli/internal/terraform"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
"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
|
// createRunIAMFunc is the entrypoint for the iam create command. It sets up the iamCreator
|
||||||
// and starts IAM creation for the specific cloud provider.
|
// and starts IAM creation for the specific cloud provider.
|
||||||
func createRunIAMFunc(provider cloudprovider.Provider) func(cmd *cobra.Command, args []string) error {
|
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 {
|
switch provider {
|
||||||
case cloudprovider.AWS:
|
case cloudprovider.AWS:
|
||||||
providerCreator = func(string) providerIAMCreator { return &awsIAMCreator{} }
|
providerCreator = func(pathprefix.PathPrefixer) providerIAMCreator { return &awsIAMCreator{} }
|
||||||
case cloudprovider.Azure:
|
case cloudprovider.Azure:
|
||||||
providerCreator = func(string) providerIAMCreator { return &azureIAMCreator{} }
|
providerCreator = func(pathprefix.PathPrefixer) providerIAMCreator { return &azureIAMCreator{} }
|
||||||
case cloudprovider.GCP:
|
case cloudprovider.GCP:
|
||||||
providerCreator = func(workspace string) providerIAMCreator {
|
providerCreator = func(pf pathprefix.PathPrefixer) providerIAMCreator {
|
||||||
return &gcpIAMCreator{workspace}
|
return &gcpIAMCreator{pf}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *cobra.Command, args []string) error {
|
||||||
|
@ -154,25 +155,26 @@ func createRunIAMFunc(provider cloudprovider.Provider) func(cmd *cobra.Command,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("parsing Terraform log level %s: %w", logLevelString, err)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("parsing workspace string: %w", err)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("creating iamCreator: %w", err)
|
return fmt.Errorf("creating iamCreator: %w", err)
|
||||||
}
|
}
|
||||||
defer iamCreator.spinner.Stop()
|
defer iamCreator.spinner.Stop()
|
||||||
defer iamCreator.log.Sync()
|
defer iamCreator.log.Sync()
|
||||||
iamCreator.provider = provider
|
iamCreator.provider = provider
|
||||||
iamCreator.providerCreator = providerCreator(workspace)
|
iamCreator.providerCreator = providerCreator(pf)
|
||||||
return iamCreator.create(cmd.Context())
|
return iamCreator.create(cmd.Context())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// newIAMCreator creates a new iamiamCreator.
|
// 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)
|
spinner, err := newSpinnerOrStderr(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("creating spinner: %w", err)
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("creating logger: %w", err)
|
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{
|
return &iamCreator{
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
|
@ -206,6 +208,7 @@ type iamCreator struct {
|
||||||
providerCreator providerIAMCreator
|
providerCreator providerIAMCreator
|
||||||
iamConfig *cloudcmd.IAMConfigOptions
|
iamConfig *cloudcmd.IAMConfigOptions
|
||||||
log debugLog
|
log debugLog
|
||||||
|
pf pathprefix.PathPrefixer
|
||||||
}
|
}
|
||||||
|
|
||||||
// create IAM configuration on the iamCreator's cloud provider.
|
// 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)
|
c.log.Debugf("Using flags: %+v", flags)
|
||||||
|
|
||||||
if err := c.checkWorkingDir(flags.workspace); err != nil {
|
if err := c.checkWorkingDir(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,14 +238,14 @@ func (c *iamCreator) create(ctx context.Context) error {
|
||||||
|
|
||||||
var conf config.Config
|
var conf config.Config
|
||||||
if flags.updateConfig {
|
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 {
|
if err = c.fileHandler.ReadYAML(constants.ConfigFilename, &conf); err != nil {
|
||||||
return fmt.Errorf("error reading the configuration file: %w", err)
|
return fmt.Errorf("error reading the configuration file: %w", err)
|
||||||
}
|
}
|
||||||
if err := validateConfigWithFlagCompatibility(c.provider, conf, flags); err != nil {
|
if err := validateConfigWithFlagCompatibility(c.provider, conf, flags); err != nil {
|
||||||
return err
|
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)
|
c.spinner.Start("Creating", false)
|
||||||
|
@ -260,12 +263,12 @@ func (c *iamCreator) create(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if flags.updateConfig {
|
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)
|
c.providerCreator.writeOutputValuesToConfig(&conf, flags, iamFile)
|
||||||
if err := c.fileHandler.WriteYAML(constants.ConfigFilename, conf, file.OptOverwrite); err != nil {
|
if err := c.fileHandler.WriteYAML(constants.ConfigFilename, conf, file.OptOverwrite); err != nil {
|
||||||
return err
|
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
|
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).
|
// 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) {
|
func (c *iamCreator) parseFlagsAndSetupConfig() (iamFlags, error) {
|
||||||
cwd, err := c.cmd.Flags().GetString("workspace")
|
workDir, err := c.cmd.Flags().GetString("workspace")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return iamFlags{}, fmt.Errorf("parsing config string: %w", err)
|
return iamFlags{}, fmt.Errorf("parsing config string: %w", err)
|
||||||
}
|
}
|
||||||
|
c.pf = pathprefix.New(workDir)
|
||||||
|
|
||||||
yesFlag, err := c.cmd.Flags().GetBool("yes")
|
yesFlag, err := c.cmd.Flags().GetBool("yes")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return iamFlags{}, fmt.Errorf("parsing yes bool: %w", err)
|
return iamFlags{}, fmt.Errorf("parsing yes bool: %w", err)
|
||||||
|
@ -291,7 +296,6 @@ func (c *iamCreator) parseFlagsAndSetupConfig() (iamFlags, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := iamFlags{
|
flags := iamFlags{
|
||||||
workspace: cwd,
|
|
||||||
yesFlag: yesFlag,
|
yesFlag: yesFlag,
|
||||||
updateConfig: updateConfig,
|
updateConfig: updateConfig,
|
||||||
}
|
}
|
||||||
|
@ -305,9 +309,9 @@ func (c *iamCreator) parseFlagsAndSetupConfig() (iamFlags, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkWorkingDir checks if the current working directory already contains a Terraform dir.
|
// 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 {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -317,7 +321,6 @@ type iamFlags struct {
|
||||||
aws awsFlags
|
aws awsFlags
|
||||||
azure azureFlags
|
azure azureFlags
|
||||||
gcp gcpFlags
|
gcp gcpFlags
|
||||||
workspace string
|
|
||||||
yesFlag bool
|
yesFlag bool
|
||||||
updateConfig bool
|
updateConfig bool
|
||||||
}
|
}
|
||||||
|
@ -488,7 +491,7 @@ func (c *azureIAMCreator) parseAndWriteIDFile(_ cloudcmd.IAMOutput, _ file.Handl
|
||||||
|
|
||||||
// gcpIAMCreator implements the providerIAMCreator interface for GCP.
|
// gcpIAMCreator implements the providerIAMCreator interface for GCP.
|
||||||
type gcpIAMCreator struct {
|
type gcpIAMCreator struct {
|
||||||
workspace string
|
pf pathprefix.PathPrefixer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gcpIAMCreator) parseFlagsAndSetupConfig(cmd *cobra.Command, flags iamFlags, iamConfig *cloudcmd.IAMConfigOptions) (iamFlags, error) {
|
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("projectID:\t\t%s\n", flags.gcp.projectID)
|
||||||
cmd.Printf("region:\t\t\t%s\n", flags.gcp.region)
|
cmd.Printf("region:\t\t\t%s\n", flags.gcp.region)
|
||||||
cmd.Printf("zone:\t\t\t%s\n", flags.gcp.zone)
|
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) {
|
func (c *gcpIAMCreator) writeOutputValuesToConfig(conf *config.Config, flags iamFlags, _ cloudcmd.IAMOutput) {
|
||||||
conf.Provider.GCP.Project = flags.gcp.projectID
|
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.Region = flags.gcp.region
|
||||||
conf.Provider.GCP.Zone = flags.gcp.zone
|
conf.Provider.GCP.Zone = flags.gcp.zone
|
||||||
for groupName, group := range conf.NodeGroups {
|
for groupName, group := range conf.NodeGroups {
|
||||||
|
@ -573,7 +576,7 @@ func (c *gcpIAMCreator) parseAndWriteIDFile(iamFile cloudcmd.IAMOutput, fileHand
|
||||||
return err
|
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.
|
// parseIDFile parses the given base64 encoded JSON string of the GCP service account key and returns a map.
|
||||||
|
|
|
@ -707,13 +707,13 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
readConfig := &config.Config{}
|
readConfig := &config.Config{}
|
||||||
readErr := fileHandler.ReadYAML(constants.ConfigFilename, readConfig)
|
readErr := fileHandler.ReadYAML(constants.ConfigFilename, readConfig)
|
||||||
require.NoError(readErr)
|
require.NoError(readErr)
|
||||||
assert.Equal(gcpServiceAccountKeyFile, readConfig.Provider.GCP.ServiceAccountKeyPath)
|
assert.Equal(constants.GCPServiceAccountKeyFilename, readConfig.Provider.GCP.ServiceAccountKeyPath)
|
||||||
}
|
}
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
assert.True(tc.creator.createCalled)
|
assert.True(tc.creator.createCalled)
|
||||||
assert.Equal(tc.creator.id.GCPOutput, validIAMIDFile.GCPOutput)
|
assert.Equal(tc.creator.id.GCPOutput, validIAMIDFile.GCPOutput)
|
||||||
readServiceAccountKey := &map[string]string{}
|
readServiceAccountKey := &map[string]string{}
|
||||||
readErr := fileHandler.ReadJSON(gcpServiceAccountKeyFile, readServiceAccountKey)
|
readErr := fileHandler.ReadJSON(constants.GCPServiceAccountKeyFilename, readServiceAccountKey)
|
||||||
require.NoError(readErr)
|
require.NoError(readErr)
|
||||||
assert.Equal("not_a_secret", (*readServiceAccountKey)["private_key_id"])
|
assert.Equal("not_a_secret", (*readServiceAccountKey)["private_key_id"])
|
||||||
})
|
})
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
"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/cli/internal/terraform"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/gcpshared"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/gcpshared"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
|
@ -51,6 +52,7 @@ func runIAMDestroy(cmd *cobra.Command, _ []string) error {
|
||||||
|
|
||||||
type destroyCmd struct {
|
type destroyCmd struct {
|
||||||
log debugLog
|
log debugLog
|
||||||
|
pf pathprefix.PathPrefixer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *destroyCmd) iamDestroy(cmd *cobra.Command, spinner spinnerInterf, destroyer iamDestroyer, fsHandler file.Handler) error {
|
func (c *destroyCmd) iamDestroy(cmd *cobra.Command, spinner spinnerInterf, destroyer iamDestroyer, fsHandler file.Handler) error {
|
||||||
|
@ -60,27 +62,27 @@ func (c *destroyCmd) iamDestroy(cmd *cobra.Command, spinner spinnerInterf, destr
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if there is a possibility that the cluster is still running by looking out for specific files
|
// check if there is a possibility that the cluster is still running by looking out for specific files
|
||||||
c.log.Debugf("Checking if %q exists", adminConfPath(flags.workspace))
|
c.log.Debugf("Checking if %q exists", c.pf.PrefixPath(constants.AdminConfFilename))
|
||||||
_, err = fsHandler.Stat(constants.AdminConfFilename)
|
_, err = fsHandler.Stat(constants.AdminConfFilename)
|
||||||
if !errors.Is(err, os.ErrNotExist) {
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
return fmt.Errorf("file %q still exists, please make sure to terminate your cluster before destroying your IAM configuration", adminConfPath(flags.workspace))
|
return fmt.Errorf("file %q still exists, please make sure to terminate your cluster before destroying your IAM configuration", c.pf.PrefixPath(constants.AdminConfFilename))
|
||||||
}
|
}
|
||||||
c.log.Debugf("Checking if %q exists", clusterIDsPath(flags.workspace))
|
c.log.Debugf("Checking if %q exists", c.pf.PrefixPath(constants.ClusterIDsFilename))
|
||||||
_, err = fsHandler.Stat(constants.ClusterIDsFilename)
|
_, err = fsHandler.Stat(constants.ClusterIDsFilename)
|
||||||
if !errors.Is(err, os.ErrNotExist) {
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
return fmt.Errorf("file %q still exists, please make sure to terminate your cluster before destroying your IAM configuration", clusterIDsPath(flags.workspace))
|
return fmt.Errorf("file %q still exists, please make sure to terminate your cluster before destroying your IAM configuration", c.pf.PrefixPath(constants.ClusterIDsFilename))
|
||||||
}
|
}
|
||||||
|
|
||||||
gcpFileExists := false
|
gcpFileExists := false
|
||||||
|
|
||||||
c.log.Debugf("Checking if %q exists", gcpServiceAccountKeyPath(flags.workspace))
|
c.log.Debugf("Checking if %q exists", c.pf.PrefixPath(constants.GCPServiceAccountKeyFilename))
|
||||||
_, err = fsHandler.Stat(gcpServiceAccountKeyFile)
|
_, err = fsHandler.Stat(constants.GCPServiceAccountKeyFilename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, os.ErrNotExist) {
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.log.Debugf("%q exists", gcpServiceAccountKeyPath(flags.workspace))
|
c.log.Debugf("%q exists", c.pf.PrefixPath(constants.GCPServiceAccountKeyFilename))
|
||||||
gcpFileExists = true
|
gcpFileExists = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +90,7 @@ func (c *destroyCmd) iamDestroy(cmd *cobra.Command, spinner spinnerInterf, destr
|
||||||
// Confirmation
|
// Confirmation
|
||||||
confirmString := "Do you really want to destroy your IAM configuration? Note that this will remove all resources in the resource group."
|
confirmString := "Do you really want to destroy your IAM configuration? Note that this will remove all resources in the resource group."
|
||||||
if gcpFileExists {
|
if gcpFileExists {
|
||||||
confirmString += fmt.Sprintf("\nThis will also delete %q", gcpServiceAccountKeyPath(flags.workspace))
|
confirmString += fmt.Sprintf("\nThis will also delete %q", c.pf.PrefixPath(constants.GCPServiceAccountKeyFilename))
|
||||||
}
|
}
|
||||||
ok, err := askToConfirm(cmd, confirmString)
|
ok, err := askToConfirm(cmd, confirmString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -101,8 +103,8 @@ func (c *destroyCmd) iamDestroy(cmd *cobra.Command, spinner spinnerInterf, destr
|
||||||
}
|
}
|
||||||
|
|
||||||
if gcpFileExists {
|
if gcpFileExists {
|
||||||
c.log.Debugf("Starting to delete %q", gcpServiceAccountKeyPath(flags.workspace))
|
c.log.Debugf("Starting to delete %q", c.pf.PrefixPath(constants.GCPServiceAccountKeyFilename))
|
||||||
proceed, err := c.deleteGCPServiceAccountKeyFile(cmd, destroyer, flags.workspace, fsHandler)
|
proceed, err := c.deleteGCPServiceAccountKeyFile(cmd, destroyer, fsHandler)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -125,11 +127,11 @@ func (c *destroyCmd) iamDestroy(cmd *cobra.Command, spinner spinnerInterf, destr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *destroyCmd) deleteGCPServiceAccountKeyFile(cmd *cobra.Command, destroyer iamDestroyer, workspace string, fsHandler file.Handler) (bool, error) {
|
func (c *destroyCmd) deleteGCPServiceAccountKeyFile(cmd *cobra.Command, destroyer iamDestroyer, fsHandler file.Handler) (bool, error) {
|
||||||
var fileSaKey gcpshared.ServiceAccountKey
|
var fileSaKey gcpshared.ServiceAccountKey
|
||||||
|
|
||||||
c.log.Debugf("Parsing %q", gcpServiceAccountKeyPath(workspace))
|
c.log.Debugf("Parsing %q", c.pf.PrefixPath(constants.GCPServiceAccountKeyFilename))
|
||||||
if err := fsHandler.ReadJSON(gcpServiceAccountKeyFile, &fileSaKey); err != nil {
|
if err := fsHandler.ReadJSON(constants.GCPServiceAccountKeyFilename, &fileSaKey); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,21 +143,20 @@ func (c *destroyCmd) deleteGCPServiceAccountKeyFile(cmd *cobra.Command, destroye
|
||||||
|
|
||||||
c.log.Debugf("Checking if keys are the same")
|
c.log.Debugf("Checking if keys are the same")
|
||||||
if tfSaKey != fileSaKey {
|
if tfSaKey != fileSaKey {
|
||||||
cmd.Printf("The key in %q don't match up with your Terraform state. %q will not be deleted.\n", gcpServiceAccountKeyPath(workspace), gcpServiceAccountKeyPath(workspace))
|
cmd.Printf("The key in %q don't match up with your Terraform state. %q will not be deleted.\n", c.pf.PrefixPath(constants.GCPServiceAccountKeyFilename), c.pf.PrefixPath(constants.GCPServiceAccountKeyFilename))
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := fsHandler.Remove(gcpServiceAccountKeyFile); err != nil {
|
if err := fsHandler.Remove(constants.GCPServiceAccountKeyFilename); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log.Debugf("Successfully deleted %q", gcpServiceAccountKeyPath(workspace))
|
c.log.Debugf("Successfully deleted %q", c.pf.PrefixPath(constants.GCPServiceAccountKeyFilename))
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type destroyFlags struct {
|
type destroyFlags struct {
|
||||||
yes bool
|
yes bool
|
||||||
workspace string
|
|
||||||
tfLogLevel terraform.LogLevel
|
tfLogLevel terraform.LogLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,11 +168,12 @@ func (c *destroyCmd) parseDestroyFlags(cmd *cobra.Command) (destroyFlags, error)
|
||||||
}
|
}
|
||||||
c.log.Debugf("Yes flag is %t", yes)
|
c.log.Debugf("Yes flag is %t", yes)
|
||||||
|
|
||||||
workspace, err := cmd.Flags().GetString("workspace")
|
workDir, err := cmd.Flags().GetString("workspace")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return destroyFlags{}, fmt.Errorf("parsing workspace string: %w", err)
|
return destroyFlags{}, fmt.Errorf("parsing workspace string: %w", err)
|
||||||
}
|
}
|
||||||
c.log.Debugf("Workspace set to %q", workspace)
|
c.log.Debugf("Workspace set to %q", workDir)
|
||||||
|
c.pf = pathprefix.New(workDir)
|
||||||
|
|
||||||
logLevelString, err := cmd.Flags().GetString("tf-log")
|
logLevelString, err := cmd.Flags().GetString("tf-log")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -181,11 +183,10 @@ func (c *destroyCmd) parseDestroyFlags(cmd *cobra.Command) (destroyFlags, error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return destroyFlags{}, fmt.Errorf("parsing Terraform log level %s: %w", logLevelString, err)
|
return destroyFlags{}, fmt.Errorf("parsing Terraform log level %s: %w", logLevelString, err)
|
||||||
}
|
}
|
||||||
c.log.Debugf("Terraform logs will be written into %s at level %s", terraformLogPath(workspace), logLevel.String())
|
c.log.Debugf("Terraform logs will be written into %s at level %s", c.pf.PrefixPath(constants.TerraformWorkingDir), logLevel.String())
|
||||||
|
|
||||||
return destroyFlags{
|
return destroyFlags{
|
||||||
tfLogLevel: logLevel,
|
tfLogLevel: logLevel,
|
||||||
workspace: workspace,
|
|
||||||
yes: yes,
|
yes: yes,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ func TestIAMDestroy(t *testing.T) {
|
||||||
|
|
||||||
newFsExists := func() file.Handler {
|
newFsExists := func() file.Handler {
|
||||||
fh := file.NewHandler(afero.NewMemMapFs())
|
fh := file.NewHandler(afero.NewMemMapFs())
|
||||||
require.NoError(fh.Write(gcpServiceAccountKeyFile, []byte("{}")))
|
require.NoError(fh.Write(constants.GCPServiceAccountKeyFilename, []byte("{}")))
|
||||||
return fh
|
return fh
|
||||||
}
|
}
|
||||||
newFsMissing := func() file.Handler {
|
newFsMissing := func() file.Handler {
|
||||||
|
@ -147,12 +147,12 @@ func TestDeleteGCPServiceAccountKeyFile(t *testing.T) {
|
||||||
|
|
||||||
newFs := func() file.Handler {
|
newFs := func() file.Handler {
|
||||||
fs := file.NewHandler(afero.NewMemMapFs())
|
fs := file.NewHandler(afero.NewMemMapFs())
|
||||||
require.NoError(fs.Write(gcpServiceAccountKeyFile, []byte(gcpFile)))
|
require.NoError(fs.Write(constants.GCPServiceAccountKeyFilename, []byte(gcpFile)))
|
||||||
return fs
|
return fs
|
||||||
}
|
}
|
||||||
newFsInvalidJSON := func() file.Handler {
|
newFsInvalidJSON := func() file.Handler {
|
||||||
fh := file.NewHandler(afero.NewMemMapFs())
|
fh := file.NewHandler(afero.NewMemMapFs())
|
||||||
require.NoError(fh.Write(gcpServiceAccountKeyFile, []byte("asdf")))
|
require.NoError(fh.Write(constants.GCPServiceAccountKeyFilename, []byte("asdf")))
|
||||||
return fh
|
return fh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ func TestDeleteGCPServiceAccountKeyFile(t *testing.T) {
|
||||||
|
|
||||||
c := &destroyCmd{log: logger.NewTest(t)}
|
c := &destroyCmd{log: logger.NewTest(t)}
|
||||||
|
|
||||||
proceed, err := c.deleteGCPServiceAccountKeyFile(cmd, tc.destroyer, "", tc.fsHandler)
|
proceed, err := c.deleteGCPServiceAccountKeyFile(cmd, tc.destroyer, tc.fsHandler)
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -37,6 +37,7 @@ import (
|
||||||
"github.com/edgelesssys/constellation/v2/bootstrapper/initproto"
|
"github.com/edgelesssys/constellation/v2/bootstrapper/initproto"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/cmd/pathprefix"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/azureshared"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/azureshared"
|
||||||
|
@ -79,6 +80,7 @@ type initCmd struct {
|
||||||
fileHandler file.Handler
|
fileHandler file.Handler
|
||||||
helmInstaller initializer
|
helmInstaller initializer
|
||||||
clusterShower clusterShower
|
clusterShower clusterShower
|
||||||
|
pf pathprefix.PathPrefixer
|
||||||
}
|
}
|
||||||
|
|
||||||
type clusterShower interface {
|
type clusterShower interface {
|
||||||
|
@ -143,7 +145,7 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator atls.V
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i.log.Debugf("Using flags: %+v", flags)
|
i.log.Debugf("Using flags: %+v", flags)
|
||||||
i.log.Debugf("Loading configuration file from %q", configPath(flags.workspace))
|
i.log.Debugf("Loading configuration file from %q", i.pf.PrefixPath(constants.ConfigFilename))
|
||||||
conf, err := config.New(i.fileHandler, constants.ConfigFilename, configFetcher, flags.force)
|
conf, err := config.New(i.fileHandler, constants.ConfigFilename, configFetcher, flags.force)
|
||||||
var configValidationErr *config.ValidationError
|
var configValidationErr *config.ValidationError
|
||||||
if errors.As(err, &configValidationErr) {
|
if errors.As(err, &configValidationErr) {
|
||||||
|
@ -193,14 +195,14 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator atls.V
|
||||||
return fmt.Errorf("creating new validator: %w", err)
|
return fmt.Errorf("creating new validator: %w", err)
|
||||||
}
|
}
|
||||||
i.log.Debugf("Created a new validator")
|
i.log.Debugf("Created a new validator")
|
||||||
serviceAccURI, err := i.getMarshaledServiceAccountURI(provider, conf, flags.workspace)
|
serviceAccURI, err := i.getMarshaledServiceAccountURI(provider, conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i.log.Debugf("Successfully marshaled service account URI")
|
i.log.Debugf("Successfully marshaled service account URI")
|
||||||
|
|
||||||
i.log.Debugf("Generating master secret")
|
i.log.Debugf("Generating master secret")
|
||||||
masterSecret, err := i.generateMasterSecret(cmd.OutOrStdout(), flags.workspace)
|
masterSecret, err := i.generateMasterSecret(cmd.OutOrStdout())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("generating master secret: %w", err)
|
return fmt.Errorf("generating master secret: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -246,7 +248,7 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator atls.V
|
||||||
idFile.CloudProvider = provider
|
idFile.CloudProvider = provider
|
||||||
|
|
||||||
bufferedOutput := &bytes.Buffer{}
|
bufferedOutput := &bytes.Buffer{}
|
||||||
if err := i.writeOutput(idFile, resp, flags.mergeConfigs, bufferedOutput, flags.workspace); err != nil {
|
if err := i.writeOutput(idFile, resp, flags.mergeConfigs, bufferedOutput); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,8 +396,7 @@ func (d *initDoer) handleGRPCStateChanges(ctx context.Context, wg *sync.WaitGrou
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *initCmd) writeOutput(
|
func (i *initCmd) writeOutput(
|
||||||
idFile clusterid.File, initResp *initproto.InitSuccessResponse,
|
idFile clusterid.File, initResp *initproto.InitSuccessResponse, mergeConfig bool, wr io.Writer,
|
||||||
mergeConfig bool, wr io.Writer, workspace string,
|
|
||||||
) error {
|
) error {
|
||||||
fmt.Fprint(wr, "Your Constellation cluster was successfully initialized.\n\n")
|
fmt.Fprint(wr, "Your Constellation cluster was successfully initialized.\n\n")
|
||||||
|
|
||||||
|
@ -406,14 +407,14 @@ func (i *initCmd) writeOutput(
|
||||||
tw := tabwriter.NewWriter(wr, 0, 0, 2, ' ', 0)
|
tw := tabwriter.NewWriter(wr, 0, 0, 2, ' ', 0)
|
||||||
// writeRow(tw, "Constellation cluster's owner identifier", ownerID)
|
// writeRow(tw, "Constellation cluster's owner identifier", ownerID)
|
||||||
writeRow(tw, "Constellation cluster identifier", clusterID)
|
writeRow(tw, "Constellation cluster identifier", clusterID)
|
||||||
writeRow(tw, "Kubernetes configuration", adminConfPath(workspace))
|
writeRow(tw, "Kubernetes configuration", i.pf.PrefixPath(constants.AdminConfFilename))
|
||||||
tw.Flush()
|
tw.Flush()
|
||||||
fmt.Fprintln(wr)
|
fmt.Fprintln(wr)
|
||||||
|
|
||||||
if err := i.fileHandler.Write(constants.AdminConfFilename, initResp.GetKubeconfig(), file.OptNone); err != nil {
|
if err := i.fileHandler.Write(constants.AdminConfFilename, initResp.GetKubeconfig(), file.OptNone); err != nil {
|
||||||
return fmt.Errorf("writing kubeconfig: %w", err)
|
return fmt.Errorf("writing kubeconfig: %w", err)
|
||||||
}
|
}
|
||||||
i.log.Debugf("Kubeconfig written to %s", adminConfPath(workspace))
|
i.log.Debugf("Kubeconfig written to %s", i.pf.PrefixPath(constants.AdminConfFilename))
|
||||||
|
|
||||||
if mergeConfig {
|
if mergeConfig {
|
||||||
if err := i.merger.mergeConfigs(constants.AdminConfFilename, i.fileHandler); err != nil {
|
if err := i.merger.mergeConfigs(constants.AdminConfFilename, i.fileHandler); err != nil {
|
||||||
|
@ -430,11 +431,17 @@ func (i *initCmd) writeOutput(
|
||||||
if err := i.fileHandler.WriteJSON(constants.ClusterIDsFilename, idFile, file.OptOverwrite); err != nil {
|
if err := i.fileHandler.WriteJSON(constants.ClusterIDsFilename, idFile, file.OptOverwrite); err != nil {
|
||||||
return fmt.Errorf("writing Constellation ID file: %w", err)
|
return fmt.Errorf("writing Constellation ID file: %w", err)
|
||||||
}
|
}
|
||||||
i.log.Debugf("Constellation ID file written to %s", clusterIDsPath(workspace))
|
i.log.Debugf("Constellation ID file written to %s", i.pf.PrefixPath(constants.ClusterIDsFilename))
|
||||||
|
|
||||||
if !mergeConfig {
|
if !mergeConfig {
|
||||||
fmt.Fprintln(wr, "You can now connect to your cluster by executing:")
|
fmt.Fprintln(wr, "You can now connect to your cluster by executing:")
|
||||||
fmt.Fprintf(wr, "\texport KUBECONFIG=\"$PWD/%s\"\n", adminConfPath(workspace))
|
|
||||||
|
exportPath, err := filepath.Abs(i.pf.PrefixPath(constants.AdminConfFilename))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("getting absolute path to kubeconfig: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(wr, "\texport KUBECONFIG=%q\n", exportPath)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintln(wr, "Constellation kubeconfig merged with default config.")
|
fmt.Fprintln(wr, "Constellation kubeconfig merged with default config.")
|
||||||
|
|
||||||
|
@ -469,11 +476,12 @@ func (i *initCmd) evalFlagArgs(cmd *cobra.Command) (initFlags, error) {
|
||||||
helmWaitMode = helm.WaitModeNone
|
helmWaitMode = helm.WaitModeNone
|
||||||
}
|
}
|
||||||
i.log.Debugf("Helm wait flag is %t", skipHelmWait)
|
i.log.Debugf("Helm wait flag is %t", skipHelmWait)
|
||||||
workspace, err := cmd.Flags().GetString("workspace")
|
workDir, err := cmd.Flags().GetString("workspace")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return initFlags{}, fmt.Errorf("parsing config path flag: %w", err)
|
return initFlags{}, fmt.Errorf("parsing config path flag: %w", err)
|
||||||
}
|
}
|
||||||
i.log.Debugf("Configuration path flag is %q", configPath)
|
i.pf = pathprefix.New(workDir)
|
||||||
|
|
||||||
mergeConfigs, err := cmd.Flags().GetBool("merge-kubeconfig")
|
mergeConfigs, err := cmd.Flags().GetBool("merge-kubeconfig")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return initFlags{}, fmt.Errorf("parsing merge-kubeconfig flag: %w", err)
|
return initFlags{}, fmt.Errorf("parsing merge-kubeconfig flag: %w", err)
|
||||||
|
@ -487,7 +495,6 @@ func (i *initCmd) evalFlagArgs(cmd *cobra.Command) (initFlags, error) {
|
||||||
i.log.Debugf("force flag is %t", force)
|
i.log.Debugf("force flag is %t", force)
|
||||||
|
|
||||||
return initFlags{
|
return initFlags{
|
||||||
workspace: workspace,
|
|
||||||
conformance: conformance,
|
conformance: conformance,
|
||||||
helmWaitMode: helmWaitMode,
|
helmWaitMode: helmWaitMode,
|
||||||
force: force,
|
force: force,
|
||||||
|
@ -497,7 +504,6 @@ func (i *initCmd) evalFlagArgs(cmd *cobra.Command) (initFlags, error) {
|
||||||
|
|
||||||
// initFlags are the resulting values of flag preprocessing.
|
// initFlags are the resulting values of flag preprocessing.
|
||||||
type initFlags struct {
|
type initFlags struct {
|
||||||
workspace string
|
|
||||||
conformance bool
|
conformance bool
|
||||||
helmWaitMode helm.WaitMode
|
helmWaitMode helm.WaitMode
|
||||||
force bool
|
force bool
|
||||||
|
@ -505,7 +511,7 @@ type initFlags struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// readOrGenerateMasterSecret reads a base64 encoded master secret from file or generates a new 32 byte secret.
|
// readOrGenerateMasterSecret reads a base64 encoded master secret from file or generates a new 32 byte secret.
|
||||||
func (i *initCmd) generateMasterSecret(outWriter io.Writer, workspace string) (uri.MasterSecret, error) {
|
func (i *initCmd) generateMasterSecret(outWriter io.Writer) (uri.MasterSecret, error) {
|
||||||
// No file given, generate a new secret, and save it to disk
|
// No file given, generate a new secret, and save it to disk
|
||||||
i.log.Debugf("Generating new master secret")
|
i.log.Debugf("Generating new master secret")
|
||||||
key, err := crypto.GenerateRandomBytes(crypto.MasterSecretLengthDefault)
|
key, err := crypto.GenerateRandomBytes(crypto.MasterSecretLengthDefault)
|
||||||
|
@ -524,21 +530,21 @@ func (i *initCmd) generateMasterSecret(outWriter io.Writer, workspace string) (u
|
||||||
if err := i.fileHandler.WriteJSON(constants.MasterSecretFilename, secret, file.OptNone); err != nil {
|
if err := i.fileHandler.WriteJSON(constants.MasterSecretFilename, secret, file.OptNone); err != nil {
|
||||||
return uri.MasterSecret{}, err
|
return uri.MasterSecret{}, err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(outWriter, "Your Constellation master secret was successfully written to %q\n", masterSecretPath(workspace))
|
fmt.Fprintf(outWriter, "Your Constellation master secret was successfully written to %q\n", i.pf.PrefixPath(constants.MasterSecretFilename))
|
||||||
return secret, nil
|
return secret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *initCmd) getMarshaledServiceAccountURI(provider cloudprovider.Provider, config *config.Config, workspace string,
|
func (i *initCmd) getMarshaledServiceAccountURI(provider cloudprovider.Provider, config *config.Config,
|
||||||
) (string, error) {
|
) (string, error) {
|
||||||
i.log.Debugf("Getting service account URI")
|
i.log.Debugf("Getting service account URI")
|
||||||
switch provider {
|
switch provider {
|
||||||
case cloudprovider.GCP:
|
case cloudprovider.GCP:
|
||||||
i.log.Debugf("Handling case for GCP")
|
i.log.Debugf("Handling case for GCP")
|
||||||
i.log.Debugf("GCP service account key path %s", filepath.Join(workspace, config.Provider.GCP.ServiceAccountKeyPath))
|
i.log.Debugf("GCP service account key path %s", i.pf.PrefixPath(config.Provider.GCP.ServiceAccountKeyPath))
|
||||||
|
|
||||||
var key gcpshared.ServiceAccountKey
|
var key gcpshared.ServiceAccountKey
|
||||||
if err := i.fileHandler.ReadJSON(config.Provider.GCP.ServiceAccountKeyPath, &key); err != nil {
|
if err := i.fileHandler.ReadJSON(config.Provider.GCP.ServiceAccountKeyPath, &key); err != nil {
|
||||||
return "", fmt.Errorf("reading service account key from path %q: %w", filepath.Join(workspace, config.Provider.GCP.ServiceAccountKeyPath), err)
|
return "", fmt.Errorf("reading service account key from path %q: %w", i.pf.PrefixPath(config.Provider.GCP.ServiceAccountKeyPath), err)
|
||||||
}
|
}
|
||||||
i.log.Debugf("Read GCP service account key from path")
|
i.log.Debugf("Read GCP service account key from path")
|
||||||
return key.ToCloudServiceAccountURI(), nil
|
return key.ToCloudServiceAccountURI(), nil
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/bootstrapper/initproto"
|
"github.com/edgelesssys/constellation/v2/bootstrapper/initproto"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/cmd/pathprefix"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/atls"
|
"github.com/edgelesssys/constellation/v2/internal/atls"
|
||||||
|
@ -302,7 +303,7 @@ func TestWriteOutput(t *testing.T) {
|
||||||
IP: "cluster-ip",
|
IP: "cluster-ip",
|
||||||
}
|
}
|
||||||
i := newInitCmd(nil, nil, fileHandler, nil, &stubMerger{}, logger.NewTest(t))
|
i := newInitCmd(nil, nil, fileHandler, nil, &stubMerger{}, logger.NewTest(t))
|
||||||
err := i.writeOutput(idFile, resp.GetInitSuccess(), false, &out, "")
|
err := i.writeOutput(idFile, resp.GetInitSuccess(), false, &out)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
// assert.Contains(out.String(), ownerID)
|
// assert.Contains(out.String(), ownerID)
|
||||||
assert.Contains(out.String(), clusterID)
|
assert.Contains(out.String(), clusterID)
|
||||||
|
@ -323,17 +324,19 @@ func TestWriteOutput(t *testing.T) {
|
||||||
require.NoError(afs.Remove(constants.AdminConfFilename))
|
require.NoError(afs.Remove(constants.AdminConfFilename))
|
||||||
|
|
||||||
// test custom workspace
|
// test custom workspace
|
||||||
err = i.writeOutput(idFile, resp.GetInitSuccess(), true, &out, "some/path")
|
i.pf = pathprefix.New("/some/path")
|
||||||
|
err = i.writeOutput(idFile, resp.GetInitSuccess(), true, &out)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
// assert.Contains(out.String(), ownerID)
|
// assert.Contains(out.String(), ownerID)
|
||||||
assert.Contains(out.String(), clusterID)
|
assert.Contains(out.String(), clusterID)
|
||||||
assert.Contains(out.String(), adminConfPath("some/path"))
|
assert.Contains(out.String(), i.pf.PrefixPath(constants.AdminConfFilename))
|
||||||
out.Reset()
|
out.Reset()
|
||||||
// File is written to current working dir, we simply pass the workspace for generating readable user output
|
// File is written to current working dir, we simply pass the workspace for generating readable user output
|
||||||
require.NoError(afs.Remove(constants.AdminConfFilename))
|
require.NoError(afs.Remove(constants.AdminConfFilename))
|
||||||
|
i.pf = pathprefix.PathPrefixer{}
|
||||||
|
|
||||||
// test config merging
|
// test config merging
|
||||||
err = i.writeOutput(idFile, resp.GetInitSuccess(), true, &out, "")
|
err = i.writeOutput(idFile, resp.GetInitSuccess(), true, &out)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
// assert.Contains(out.String(), ownerID)
|
// assert.Contains(out.String(), ownerID)
|
||||||
assert.Contains(out.String(), clusterID)
|
assert.Contains(out.String(), clusterID)
|
||||||
|
@ -345,7 +348,7 @@ func TestWriteOutput(t *testing.T) {
|
||||||
|
|
||||||
// test config merging with env vars set
|
// test config merging with env vars set
|
||||||
i.merger = &stubMerger{envVar: "/some/path/to/kubeconfig"}
|
i.merger = &stubMerger{envVar: "/some/path/to/kubeconfig"}
|
||||||
err = i.writeOutput(idFile, resp.GetInitSuccess(), true, &out, "")
|
err = i.writeOutput(idFile, resp.GetInitSuccess(), true, &out)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
// assert.Contains(out.String(), ownerID)
|
// assert.Contains(out.String(), ownerID)
|
||||||
assert.Contains(out.String(), clusterID)
|
assert.Contains(out.String(), clusterID)
|
||||||
|
@ -393,7 +396,7 @@ func TestGenerateMasterSecret(t *testing.T) {
|
||||||
|
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
i := newInitCmd(nil, nil, fileHandler, nil, nil, logger.NewTest(t))
|
i := newInitCmd(nil, nil, fileHandler, nil, nil, logger.NewTest(t))
|
||||||
secret, err := i.generateMasterSecret(&out, "")
|
secret, err := i.generateMasterSecret(&out)
|
||||||
|
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/cmd/pathprefix"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/featureset"
|
"github.com/edgelesssys/constellation/v2/cli/internal/featureset"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/libvirt"
|
"github.com/edgelesssys/constellation/v2/cli/internal/libvirt"
|
||||||
|
@ -229,16 +230,16 @@ type upFlags struct {
|
||||||
|
|
||||||
func (m *miniUpCmd) parseUpFlags(cmd *cobra.Command) (upFlags, error) {
|
func (m *miniUpCmd) parseUpFlags(cmd *cobra.Command) (upFlags, error) {
|
||||||
m.log.Debugf("Preparing configuration")
|
m.log.Debugf("Preparing configuration")
|
||||||
workspace, err := cmd.Flags().GetString("workspace")
|
workDir, err := cmd.Flags().GetString("workspace")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return upFlags{}, fmt.Errorf("parsing config string: %w", err)
|
return upFlags{}, fmt.Errorf("parsing config string: %w", err)
|
||||||
}
|
}
|
||||||
m.log.Debugf("Configuration path is %q", configPath)
|
m.log.Debugf("Workspace set to %q", workDir)
|
||||||
force, err := cmd.Flags().GetBool("force")
|
force, err := cmd.Flags().GetBool("force")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return upFlags{}, fmt.Errorf("parsing force bool: %w", err)
|
return upFlags{}, fmt.Errorf("parsing force bool: %w", err)
|
||||||
}
|
}
|
||||||
m.log.Debugf("force flag is %q", configPath)
|
m.log.Debugf("force flag is %q", force)
|
||||||
|
|
||||||
logLevelString, err := cmd.Flags().GetString("tf-log")
|
logLevelString, err := cmd.Flags().GetString("tf-log")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -248,7 +249,7 @@ func (m *miniUpCmd) parseUpFlags(cmd *cobra.Command) (upFlags, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return upFlags{}, fmt.Errorf("parsing Terraform log level %s: %w", logLevelString, err)
|
return upFlags{}, fmt.Errorf("parsing Terraform log level %s: %w", logLevelString, err)
|
||||||
}
|
}
|
||||||
m.log.Debugf("Terraform logs will be written into %s at level %s", terraformLogPath(workspace), logLevel.String())
|
m.log.Debugf("Terraform logs will be written into %s at level %s", pathprefix.New(workDir).PrefixPath(constants.TerraformLogFile), logLevel.String())
|
||||||
|
|
||||||
return upFlags{
|
return upFlags{
|
||||||
force: force,
|
force: force,
|
||||||
|
|
16
cli/internal/cmd/pathprefix/BUILD.bazel
Normal file
16
cli/internal/cmd/pathprefix/BUILD.bazel
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "workspace",
|
||||||
|
srcs = ["workspace.go"],
|
||||||
|
importpath = "github.com/edgelesssys/constellation/v2/cli/internal/cmd/workspace",
|
||||||
|
visibility = ["//cli:__subpackages__"],
|
||||||
|
deps = ["//internal/constants"],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "pathprefix",
|
||||||
|
srcs = ["pathprefix.go"],
|
||||||
|
importpath = "github.com/edgelesssys/constellation/v2/cli/internal/cmd/pathprefix",
|
||||||
|
visibility = ["//cli:__subpackages__"],
|
||||||
|
)
|
38
cli/internal/cmd/pathprefix/pathprefix.go
Normal file
38
cli/internal/cmd/pathprefix/pathprefix.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package pathprefix is used to print correct filepaths for a configured workspace.
|
||||||
|
|
||||||
|
The default workspace is the current working directory.
|
||||||
|
Users may override the default workspace using the --workspace flag.
|
||||||
|
|
||||||
|
The functions defined here should be used when printing any filepath to the user,
|
||||||
|
as they might otherwise be incorrect if the user has changed the workspace.
|
||||||
|
|
||||||
|
The prefixer MUST not be used when accessing files, as the workspace is changed
|
||||||
|
using os.Chdir() before the command is executed.
|
||||||
|
*/
|
||||||
|
package pathprefix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PathPrefixer is used to prefix paths with the configured workspace.
|
||||||
|
type PathPrefixer struct {
|
||||||
|
workspace string
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a new PathPrefixer.
|
||||||
|
func New(workspace string) PathPrefixer {
|
||||||
|
return PathPrefixer{workspace: workspace}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrefixPath prefixes the given path with the configured workspace.
|
||||||
|
func (p PathPrefixer) PrefixPath(path string) string {
|
||||||
|
return filepath.Clean(filepath.Join(p.workspace, path))
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ import (
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/cmd/pathprefix"
|
||||||
"github.com/edgelesssys/constellation/v2/disk-mapper/recoverproto"
|
"github.com/edgelesssys/constellation/v2/disk-mapper/recoverproto"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/atls"
|
"github.com/edgelesssys/constellation/v2/internal/atls"
|
||||||
|
@ -50,6 +51,7 @@ func NewRecoverCmd() *cobra.Command {
|
||||||
type recoverCmd struct {
|
type recoverCmd struct {
|
||||||
log debugLog
|
log debugLog
|
||||||
configFetcher attestationconfigapi.Fetcher
|
configFetcher attestationconfigapi.Fetcher
|
||||||
|
pf pathprefix.PathPrefixer
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRecover(cmd *cobra.Command, _ []string) error {
|
func runRecover(cmd *cobra.Command, _ []string) error {
|
||||||
|
@ -77,12 +79,12 @@ func (r *recoverCmd) recover(
|
||||||
r.log.Debugf("Using flags: %+v", flags)
|
r.log.Debugf("Using flags: %+v", flags)
|
||||||
|
|
||||||
var masterSecret uri.MasterSecret
|
var masterSecret uri.MasterSecret
|
||||||
r.log.Debugf("Loading master secret file from %s", masterSecretPath(flags.workspace))
|
r.log.Debugf("Loading master secret file from %s", r.pf.PrefixPath(constants.MasterSecretFilename))
|
||||||
if err := fileHandler.ReadJSON(constants.MasterSecretFilename, &masterSecret); err != nil {
|
if err := fileHandler.ReadJSON(constants.MasterSecretFilename, &masterSecret); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
r.log.Debugf("Loading configuration file from %q", configPath(flags.workspace))
|
r.log.Debugf("Loading configuration file from %q", r.pf.PrefixPath(constants.ConfigFilename))
|
||||||
conf, err := config.New(fileHandler, constants.ConfigFilename, r.configFetcher, flags.force)
|
conf, err := config.New(fileHandler, constants.ConfigFilename, r.configFetcher, flags.force)
|
||||||
var configValidationErr *config.ValidationError
|
var configValidationErr *config.ValidationError
|
||||||
if errors.As(err, &configValidationErr) {
|
if errors.As(err, &configValidationErr) {
|
||||||
|
@ -210,18 +212,18 @@ func (d *recoverDoer) setURIs(kmsURI, storageURI string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type recoverFlags struct {
|
type recoverFlags struct {
|
||||||
endpoint string
|
endpoint string
|
||||||
workspace string
|
maaURL string
|
||||||
maaURL string
|
force bool
|
||||||
force bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *recoverCmd) parseRecoverFlags(cmd *cobra.Command, fileHandler file.Handler) (recoverFlags, error) {
|
func (r *recoverCmd) parseRecoverFlags(cmd *cobra.Command, fileHandler file.Handler) (recoverFlags, error) {
|
||||||
workspace, err := cmd.Flags().GetString("workspace")
|
workDir, err := cmd.Flags().GetString("workspace")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return recoverFlags{}, fmt.Errorf("parsing config path argument: %w", err)
|
return recoverFlags{}, fmt.Errorf("parsing config path argument: %w", err)
|
||||||
}
|
}
|
||||||
r.log.Debugf("Workspace set to %q", workspace)
|
r.log.Debugf("Workspace set to %q", workDir)
|
||||||
|
r.pf = pathprefix.New(workDir)
|
||||||
|
|
||||||
var idFile clusterid.File
|
var idFile clusterid.File
|
||||||
if err := fileHandler.ReadJSON(constants.ClusterIDsFilename, &idFile); err != nil && !errors.Is(err, afero.ErrFileNotFound) {
|
if err := fileHandler.ReadJSON(constants.ClusterIDsFilename, &idFile); err != nil && !errors.Is(err, afero.ErrFileNotFound) {
|
||||||
|
@ -248,10 +250,9 @@ func (r *recoverCmd) parseRecoverFlags(cmd *cobra.Command, fileHandler file.Hand
|
||||||
}
|
}
|
||||||
|
|
||||||
return recoverFlags{
|
return recoverFlags{
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
workspace: workspace,
|
maaURL: idFile.AttestationURL,
|
||||||
maaURL: idFile.AttestationURL,
|
force: force,
|
||||||
force: force,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -208,8 +208,7 @@ func TestParseRecoverFlags(t *testing.T) {
|
||||||
"all args set": {
|
"all args set": {
|
||||||
args: []string{"-e", "192.0.2.42:2", "--workspace", "./constellation-workspace"},
|
args: []string{"-e", "192.0.2.42:2", "--workspace", "./constellation-workspace"},
|
||||||
wantFlags: recoverFlags{
|
wantFlags: recoverFlags{
|
||||||
endpoint: "192.0.2.42:2",
|
endpoint: "192.0.2.42:2",
|
||||||
workspace: "./constellation-workspace",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
"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/cli/internal/terraform"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
|
@ -53,6 +54,7 @@ func terminate(cmd *cobra.Command, terminator cloudTerminator, fileHandler file.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("parsing flags: %w", err)
|
return fmt.Errorf("parsing flags: %w", err)
|
||||||
}
|
}
|
||||||
|
pf := pathprefix.New(flags.workspace)
|
||||||
|
|
||||||
if !flags.yes {
|
if !flags.yes {
|
||||||
cmd.Println("You are about to terminate a Constellation cluster.")
|
cmd.Println("You are about to terminate a Constellation cluster.")
|
||||||
|
@ -79,11 +81,11 @@ func terminate(cmd *cobra.Command, terminator cloudTerminator, fileHandler file.
|
||||||
|
|
||||||
var removeErr error
|
var removeErr error
|
||||||
if err := fileHandler.Remove(constants.AdminConfFilename); err != nil && !errors.Is(err, fs.ErrNotExist) {
|
if err := fileHandler.Remove(constants.AdminConfFilename); err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||||
removeErr = errors.Join(err, fmt.Errorf("failed to remove file: '%s', please remove it manually", adminConfPath(flags.workspace)))
|
removeErr = errors.Join(err, fmt.Errorf("failed to remove file: '%s', please remove it manually", pf.PrefixPath(constants.AdminConfFilename)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := fileHandler.Remove(constants.ClusterIDsFilename); err != nil && !errors.Is(err, fs.ErrNotExist) {
|
if err := fileHandler.Remove(constants.ClusterIDsFilename); err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||||
removeErr = errors.Join(err, fmt.Errorf("failed to remove file: '%s', please remove it manually", clusterIDsPath(flags.workspace)))
|
removeErr = errors.Join(err, fmt.Errorf("failed to remove file: '%s', please remove it manually", pf.PrefixPath(constants.ClusterIDsFilename)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return removeErr
|
return removeErr
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/cmd/pathprefix"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/kubernetes"
|
"github.com/edgelesssys/constellation/v2/cli/internal/kubernetes"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
||||||
|
@ -284,7 +285,7 @@ func (u *upgradeApplyCmd) migrateTerraform(
|
||||||
|
|
||||||
cmd.Printf("Terraform migrations applied successfully and output written to: %s\n"+
|
cmd.Printf("Terraform migrations applied successfully and output written to: %s\n"+
|
||||||
"A backup of the pre-upgrade state has been written to: %s\n",
|
"A backup of the pre-upgrade state has been written to: %s\n",
|
||||||
clusterIDsPath(flags.workspace), filepath.Join(opts.UpgradeWorkspace, u.upgrader.GetUpgradeID(), constants.TerraformUpgradeBackupDir))
|
flags.pf.PrefixPath(constants.ClusterIDsFilename), flags.pf.PrefixPath(filepath.Join(opts.UpgradeWorkspace, u.upgrader.GetUpgradeID(), constants.TerraformUpgradeBackupDir)))
|
||||||
} else {
|
} else {
|
||||||
u.log.Debugf("No Terraform diff detected")
|
u.log.Debugf("No Terraform diff detected")
|
||||||
}
|
}
|
||||||
|
@ -377,7 +378,7 @@ func (u *upgradeApplyCmd) handleServiceUpgrade(cmd *cobra.Command, conf *config.
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseUpgradeApplyFlags(cmd *cobra.Command) (upgradeApplyFlags, error) {
|
func parseUpgradeApplyFlags(cmd *cobra.Command) (upgradeApplyFlags, error) {
|
||||||
workspace, err := cmd.Flags().GetString("workspace")
|
workDir, err := cmd.Flags().GetString("workspace")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return upgradeApplyFlags{}, err
|
return upgradeApplyFlags{}, err
|
||||||
}
|
}
|
||||||
|
@ -407,7 +408,7 @@ func parseUpgradeApplyFlags(cmd *cobra.Command) (upgradeApplyFlags, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return upgradeApplyFlags{
|
return upgradeApplyFlags{
|
||||||
workspace: workspace,
|
pf: pathprefix.New(workDir),
|
||||||
yes: yes,
|
yes: yes,
|
||||||
upgradeTimeout: timeout,
|
upgradeTimeout: timeout,
|
||||||
force: force,
|
force: force,
|
||||||
|
@ -429,7 +430,7 @@ func mergeClusterIDFile(clusterIDPath string, newIDFile clusterid.File, fileHand
|
||||||
}
|
}
|
||||||
|
|
||||||
type upgradeApplyFlags struct {
|
type upgradeApplyFlags struct {
|
||||||
workspace string
|
pf pathprefix.PathPrefixer
|
||||||
yes bool
|
yes bool
|
||||||
upgradeTimeout time.Duration
|
upgradeTimeout time.Duration
|
||||||
force bool
|
force bool
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/cmd/pathprefix"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/atls"
|
"github.com/edgelesssys/constellation/v2/internal/atls"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
|
@ -89,7 +90,7 @@ func (c *verifyCmd) verify(cmd *cobra.Command, fileHandler file.Handler, verifyC
|
||||||
}
|
}
|
||||||
c.log.Debugf("Using flags: %+v", flags)
|
c.log.Debugf("Using flags: %+v", flags)
|
||||||
|
|
||||||
c.log.Debugf("Loading configuration file from %q", configPath(flags.workspace))
|
c.log.Debugf("Loading configuration file from %q", flags.pf.PrefixPath(constants.ConfigFilename))
|
||||||
conf, err := config.New(fileHandler, constants.ConfigFilename, configFetcher, flags.force)
|
conf, err := config.New(fileHandler, constants.ConfigFilename, configFetcher, flags.force)
|
||||||
var configValidationErr *config.ValidationError
|
var configValidationErr *config.ValidationError
|
||||||
if errors.As(err, &configValidationErr) {
|
if errors.As(err, &configValidationErr) {
|
||||||
|
@ -149,11 +150,12 @@ func (c *verifyCmd) verify(cmd *cobra.Command, fileHandler file.Handler, verifyC
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *verifyCmd) parseVerifyFlags(cmd *cobra.Command, fileHandler file.Handler) (verifyFlags, error) {
|
func (c *verifyCmd) parseVerifyFlags(cmd *cobra.Command, fileHandler file.Handler) (verifyFlags, error) {
|
||||||
workspace, err := cmd.Flags().GetString("workspace")
|
workDir, err := cmd.Flags().GetString("workspace")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return verifyFlags{}, fmt.Errorf("parsing config path argument: %w", err)
|
return verifyFlags{}, fmt.Errorf("parsing config path argument: %w", err)
|
||||||
}
|
}
|
||||||
c.log.Debugf("Flag 'workspace' set to %q", workspace)
|
c.log.Debugf("Flag 'workspace' set to %q", workDir)
|
||||||
|
pf := pathprefix.New(workDir)
|
||||||
|
|
||||||
ownerID := ""
|
ownerID := ""
|
||||||
clusterID, err := cmd.Flags().GetString("cluster-id")
|
clusterID, err := cmd.Flags().GetString("cluster-id")
|
||||||
|
@ -189,13 +191,13 @@ func (c *verifyCmd) parseVerifyFlags(cmd *cobra.Command, fileHandler file.Handle
|
||||||
emptyEndpoint := endpoint == ""
|
emptyEndpoint := endpoint == ""
|
||||||
emptyIDs := ownerID == "" && clusterID == ""
|
emptyIDs := ownerID == "" && clusterID == ""
|
||||||
if emptyEndpoint || emptyIDs {
|
if emptyEndpoint || emptyIDs {
|
||||||
c.log.Debugf("Trying to supplement empty flag values from %q", clusterIDsPath(workspace))
|
c.log.Debugf("Trying to supplement empty flag values from %q", pf.PrefixPath(constants.ClusterIDsFilename))
|
||||||
if emptyEndpoint {
|
if emptyEndpoint {
|
||||||
cmd.Printf("Using endpoint from %q. Specify --node-endpoint to override this.\n", clusterIDsPath(workspace))
|
cmd.Printf("Using endpoint from %q. Specify --node-endpoint to override this.\n", pf.PrefixPath(constants.ClusterIDsFilename))
|
||||||
endpoint = idFile.IP
|
endpoint = idFile.IP
|
||||||
}
|
}
|
||||||
if emptyIDs {
|
if emptyIDs {
|
||||||
cmd.Printf("Using ID from %q. Specify --cluster-id to override this.\n", clusterIDsPath(workspace))
|
cmd.Printf("Using ID from %q. Specify --cluster-id to override this.\n", pf.PrefixPath(constants.ClusterIDsFilename))
|
||||||
ownerID = idFile.OwnerID
|
ownerID = idFile.OwnerID
|
||||||
clusterID = idFile.ClusterID
|
clusterID = idFile.ClusterID
|
||||||
}
|
}
|
||||||
|
@ -212,7 +214,7 @@ func (c *verifyCmd) parseVerifyFlags(cmd *cobra.Command, fileHandler file.Handle
|
||||||
|
|
||||||
return verifyFlags{
|
return verifyFlags{
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
workspace: workspace,
|
pf: pf,
|
||||||
ownerID: ownerID,
|
ownerID: ownerID,
|
||||||
clusterID: clusterID,
|
clusterID: clusterID,
|
||||||
maaURL: idFile.AttestationURL,
|
maaURL: idFile.AttestationURL,
|
||||||
|
@ -225,10 +227,10 @@ type verifyFlags struct {
|
||||||
endpoint string
|
endpoint string
|
||||||
ownerID string
|
ownerID string
|
||||||
clusterID string
|
clusterID string
|
||||||
workspace string
|
|
||||||
maaURL string
|
maaURL string
|
||||||
rawOutput bool
|
rawOutput bool
|
||||||
force bool
|
force bool
|
||||||
|
pf pathprefix.PathPrefixer
|
||||||
}
|
}
|
||||||
|
|
||||||
func addPortIfMissing(endpoint string, defaultPort int) (string, error) {
|
func addPortIfMissing(endpoint string, defaultPort int) (string, error) {
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) Edgeless Systems GmbH
|
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Users may override the default workspace using the --workspace flag.
|
|
||||||
// The default workspace is the current working directory.
|
|
||||||
// The following functions return paths relative to the set workspace,
|
|
||||||
// and should be used when printing the path to the user.
|
|
||||||
// The MUST not be used when accessing files, as the workspace is changed
|
|
||||||
// using os.Chdir() before the command is executed.
|
|
||||||
|
|
||||||
func adminConfPath(workspace string) string {
|
|
||||||
return filepath.Join(workspace, constants.AdminConfFilename)
|
|
||||||
}
|
|
||||||
|
|
||||||
func configPath(workspace string) string {
|
|
||||||
return filepath.Join(workspace, constants.ConfigFilename)
|
|
||||||
}
|
|
||||||
|
|
||||||
func clusterIDsPath(workspace string) string {
|
|
||||||
return filepath.Join(workspace, constants.ClusterIDsFilename)
|
|
||||||
}
|
|
||||||
|
|
||||||
func masterSecretPath(workspace string) string {
|
|
||||||
return filepath.Join(workspace, constants.MasterSecretFilename)
|
|
||||||
}
|
|
||||||
|
|
||||||
func terraformClusterWorkspace(workspace string) string {
|
|
||||||
return filepath.Join(workspace, constants.TerraformWorkingDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
func terraformIAMWorkspace(workspace string) string {
|
|
||||||
return filepath.Join(workspace, constants.TerraformIAMWorkingDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
func terraformLogPath(workspace string) string {
|
|
||||||
return filepath.Join(workspace, constants.TerraformLogFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
const gcpServiceAccountKeyFile = "gcpServiceAccountKey.json"
|
|
||||||
|
|
||||||
func gcpServiceAccountKeyPath(workspace string) string {
|
|
||||||
return filepath.Join(workspace, gcpServiceAccountKeyFile)
|
|
||||||
}
|
|
|
@ -88,6 +88,8 @@ const (
|
||||||
TerraformWorkingDir = "constellation-terraform"
|
TerraformWorkingDir = "constellation-terraform"
|
||||||
// TerraformIAMWorkingDir is the directory name for the Terraform IAM Client workspace.
|
// TerraformIAMWorkingDir is the directory name for the Terraform IAM Client workspace.
|
||||||
TerraformIAMWorkingDir = "constellation-iam-terraform"
|
TerraformIAMWorkingDir = "constellation-iam-terraform"
|
||||||
|
// GCPServiceAccountKeyFilename is the file name for the GCP service account key file.
|
||||||
|
GCPServiceAccountKeyFilename = "gcpServiceAccountKey.json"
|
||||||
// ErrorLog file which contains server errors during init.
|
// ErrorLog file which contains server errors during init.
|
||||||
ErrorLog = "constellation-cluster.log"
|
ErrorLog = "constellation-cluster.log"
|
||||||
// ControlPlaneAdminConfFilename filepath to control plane kubernetes admin config.
|
// ControlPlaneAdminConfFilename filepath to control plane kubernetes admin config.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue