diff --git a/CMakeLists.txt b/CMakeLists.txt index b0b82afe9..9b12ed8ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,7 @@ add_dependencies(coordinator nitro) add_custom_target(cli ALL ${CMAKE_COMMAND} -E env CGO_CFLAGS=${NITRO_CFLAGS} ${CMAKE_COMMAND} -E env CGO_LDFLAGS=${NITRO_LDFLAGS} - go build -o ${CMAKE_BINARY_DIR}/constellation -buildvcs=false -tags=aws,gcp -ldflags "-buildid='' -X github.com/edgelesssys/constellation/cli/defaults.Version=${PROJECT_VERSION}" + go build -o ${CMAKE_BINARY_DIR}/constellation -buildvcs=false -tags=aws,gcp -ldflags "-buildid='' -X github.com/edgelesssys/constellation/internal/constants.CliVersion=${PROJECT_VERSION}" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/cli) add_dependencies(cli nitro) diff --git a/cli/cmd/create.go b/cli/cmd/create.go index c916c5303..fe97110fd 100644 --- a/cli/cmd/create.go +++ b/cli/cmd/create.go @@ -6,7 +6,7 @@ import ( "io/fs" "github.com/edgelesssys/constellation/cli/file" - "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/spf13/cobra" ) @@ -26,15 +26,15 @@ func newCreateCmd() *cobra.Command { } // checkDirClean checks if files of a previous Constellation are left in the current working dir. -func checkDirClean(fileHandler file.Handler, config *config.Config) error { - if _, err := fileHandler.Stat(*config.StatePath); !errors.Is(err, fs.ErrNotExist) { - return fmt.Errorf("file '%s' already exists in working directory, run 'constellation terminate' before creating a new one", *config.StatePath) +func checkDirClean(fileHandler file.Handler) error { + if _, err := fileHandler.Stat(constants.StateFilename); !errors.Is(err, fs.ErrNotExist) { + return fmt.Errorf("file '%s' already exists in working directory, run 'constellation terminate' before creating a new one", constants.StateFilename) } - if _, err := fileHandler.Stat(*config.AdminConfPath); !errors.Is(err, fs.ErrNotExist) { - return fmt.Errorf("file '%s' already exists in working directory, run 'constellation terminate' before creating a new one", *config.AdminConfPath) + 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", constants.AdminConfFilename) } - if _, err := fileHandler.Stat(*config.MasterSecretPath); !errors.Is(err, fs.ErrNotExist) { - return fmt.Errorf("file '%s' already exists in working directory, clean it up first", *config.MasterSecretPath) + if _, err := fileHandler.Stat(constants.MasterSecretFilename); !errors.Is(err, fs.ErrNotExist) { + return fmt.Errorf("file '%s' already exists in working directory, clean it up first", constants.MasterSecretFilename) } return nil diff --git a/cli/cmd/create_aws.go b/cli/cmd/create_aws.go index cbc165f1e..b2ef2e0a4 100644 --- a/cli/cmd/create_aws.go +++ b/cli/cmd/create_aws.go @@ -13,6 +13,7 @@ import ( "github.com/edgelesssys/constellation/cli/ec2/client" "github.com/edgelesssys/constellation/cli/file" "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" ) func newCreateAWSCmd() *cobra.Command { @@ -23,7 +24,7 @@ func newCreateAWSCmd() *cobra.Command { Example: "aws 1 4 2xlarge", Args: cobra.MatchAll( cobra.ExactArgs(3), - isValidAWSCoordinatorCount(0), + isValidAWSCoordinatorCount(0, 1), isIntGreaterZeroArg(1), isEC2InstanceType(2), ), @@ -64,7 +65,7 @@ func runCreateAWS(cmd *cobra.Command, args []string) error { // After the instances are running, they are tagged with the default tags. // On success, the state of the client is saved to the state file. func createAWS(cmd *cobra.Command, cl ec2client, fileHandler file.Handler, config *config.Config, size, name string, count int) (retErr error) { - if err := checkDirClean(fileHandler, config); err != nil { + if err := checkDirClean(fileHandler); err != nil { return err } @@ -112,7 +113,7 @@ func createAWS(cmd *cobra.Command, cl ec2client, fileHandler file.Handler, confi if err != nil { return err } - if err := fileHandler.WriteJSON(*config.StatePath, stat, file.OptNone); err != nil { + if err := fileHandler.WriteJSON(constants.StateFilename, stat, file.OptNone); err != nil { return err } diff --git a/cli/cmd/create_aws_test.go b/cli/cmd/create_aws_test.go index b71aadcaa..20745e034 100644 --- a/cli/cmd/create_aws_test.go +++ b/cli/cmd/create_aws_test.go @@ -9,6 +9,7 @@ import ( "github.com/edgelesssys/constellation/cli/ec2" "github.com/edgelesssys/constellation/cli/file" "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/edgelesssys/constellation/internal/state" "github.com/spf13/afero" "github.com/spf13/cobra" @@ -138,7 +139,7 @@ func TestCreateAWS(t *testing.T) { fs := afero.NewMemMapFs() fileHandler := file.NewHandler(fs) if tc.existingState != nil { - require.NoError(fileHandler.WriteJSON(*config.StatePath, *tc.existingState, file.OptNone)) + require.NoError(fileHandler.WriteJSON(constants.StateFilename, *tc.existingState, file.OptNone)) } err := createAWS(cmd, tc.client, fileHandler, config, "xlarge", "name", 3) @@ -152,7 +153,7 @@ func TestCreateAWS(t *testing.T) { } else { assert.NoError(err) var stat state.ConstellationState - err := fileHandler.ReadJSON(*config.StatePath, &stat) + err := fileHandler.ReadJSON(constants.StateFilename, &stat) assert.NoError(err) assert.Equal(tc.stateExpected, stat) } diff --git a/cli/cmd/create_azure.go b/cli/cmd/create_azure.go index 6296ec75a..e994168af 100644 --- a/cli/cmd/create_azure.go +++ b/cli/cmd/create_azure.go @@ -10,6 +10,7 @@ import ( "github.com/edgelesssys/constellation/cli/azure/client" "github.com/edgelesssys/constellation/cli/file" "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/spf13/afero" "github.com/spf13/cobra" ) @@ -71,7 +72,7 @@ func runCreateAzure(cmd *cobra.Command, args []string) error { } func createAzure(cmd *cobra.Command, cl azureclient, fileHandler file.Handler, config *config.Config, size string, countCoordinators, countNodes int) (retErr error) { - if err := checkDirClean(fileHandler, config); err != nil { + if err := checkDirClean(fileHandler); err != nil { return err } @@ -120,7 +121,7 @@ func createAzure(cmd *cobra.Command, cl azureclient, fileHandler file.Handler, c if err != nil { return err } - if err := fileHandler.WriteJSON(*config.StatePath, stat, file.OptNone); err != nil { + if err := fileHandler.WriteJSON(constants.StateFilename, stat, file.OptNone); err != nil { return err } diff --git a/cli/cmd/create_azure_test.go b/cli/cmd/create_azure_test.go index 38921c947..65eab66a6 100644 --- a/cli/cmd/create_azure_test.go +++ b/cli/cmd/create_azure_test.go @@ -9,6 +9,7 @@ import ( "github.com/edgelesssys/constellation/cli/cloudprovider" "github.com/edgelesssys/constellation/cli/file" "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/edgelesssys/constellation/internal/state" "github.com/spf13/afero" "github.com/spf13/cobra" @@ -155,7 +156,7 @@ func TestCreateAzure(t *testing.T) { fs := afero.NewMemMapFs() fileHandler := file.NewHandler(fs) if tc.existingState != nil { - require.NoError(fileHandler.WriteJSON(*config.StatePath, *tc.existingState, file.OptNone)) + require.NoError(fileHandler.WriteJSON(constants.StateFilename, *tc.existingState, file.OptNone)) } err := createAzure(cmd, tc.client, fileHandler, config, "Standard_D2s_v3", 3, 2) @@ -168,7 +169,7 @@ func TestCreateAzure(t *testing.T) { } else { assert.NoError(err) var state state.ConstellationState - err := fileHandler.ReadJSON(*config.StatePath, &state) + err := fileHandler.ReadJSON(constants.StateFilename, &state) assert.NoError(err) assert.Equal(tc.stateExpected, state) } diff --git a/cli/cmd/create_gcp.go b/cli/cmd/create_gcp.go index a971a0fb0..d8cc0ff16 100644 --- a/cli/cmd/create_gcp.go +++ b/cli/cmd/create_gcp.go @@ -10,6 +10,7 @@ import ( "github.com/edgelesssys/constellation/cli/gcp" "github.com/edgelesssys/constellation/cli/gcp/client" "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/spf13/afero" "github.com/spf13/cobra" ) @@ -65,7 +66,7 @@ func runCreateGCP(cmd *cobra.Command, args []string) error { } func createGCP(cmd *cobra.Command, cl gcpclient, fileHandler file.Handler, config *config.Config, size string, countCoordinators, countNodes int) (retErr error) { - if err := checkDirClean(fileHandler, config); err != nil { + if err := checkDirClean(fileHandler); err != nil { return err } @@ -114,7 +115,7 @@ func createGCP(cmd *cobra.Command, cl gcpclient, fileHandler file.Handler, confi return err } - if err := fileHandler.WriteJSON(*config.StatePath, stat, file.OptNone); err != nil { + if err := fileHandler.WriteJSON(constants.StateFilename, stat, file.OptNone); err != nil { return err } diff --git a/cli/cmd/create_gcp_test.go b/cli/cmd/create_gcp_test.go index 0c8f6ece0..aa5fd7e52 100644 --- a/cli/cmd/create_gcp_test.go +++ b/cli/cmd/create_gcp_test.go @@ -9,6 +9,7 @@ import ( "github.com/edgelesssys/constellation/cli/file" "github.com/edgelesssys/constellation/cli/gcp" "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/edgelesssys/constellation/internal/state" "github.com/spf13/afero" "github.com/spf13/cobra" @@ -153,7 +154,7 @@ func TestCreateGCP(t *testing.T) { fs := afero.NewMemMapFs() fileHandler := file.NewHandler(fs) if tc.existingState != nil { - require.NoError(fileHandler.WriteJSON(*config.StatePath, *tc.existingState, file.OptNone)) + require.NoError(fileHandler.WriteJSON(constants.StateFilename, *tc.existingState, file.OptNone)) } err := createGCP(cmd, tc.client, fileHandler, config, "n2d-standard-2", 3, 2) @@ -168,7 +169,7 @@ func TestCreateGCP(t *testing.T) { } else { assert.NoError(err) var stat state.ConstellationState - err := fileHandler.ReadJSON(*config.StatePath, &stat) + err := fileHandler.ReadJSON(constants.StateFilename, &stat) assert.NoError(err) assert.Equal(tc.stateExpected, stat) } diff --git a/cli/cmd/create_test.go b/cli/cmd/create_test.go index 2baef702f..d56307a00 100644 --- a/cli/cmd/create_test.go +++ b/cli/cmd/create_test.go @@ -4,15 +4,13 @@ import ( "testing" "github.com/edgelesssys/constellation/cli/file" - "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestCheckDirClean(t *testing.T) { - config := config.Default() - testCases := map[string]struct { fileHandler file.Handler existingFiles []string @@ -23,22 +21,22 @@ func TestCheckDirClean(t *testing.T) { }, "adminconf exists": { fileHandler: file.NewHandler(afero.NewMemMapFs()), - existingFiles: []string{*config.AdminConfPath}, + existingFiles: []string{constants.AdminConfFilename}, wantErr: true, }, "master secret exists": { fileHandler: file.NewHandler(afero.NewMemMapFs()), - existingFiles: []string{*config.MasterSecretPath}, + existingFiles: []string{constants.MasterSecretFilename}, wantErr: true, }, "state file exists": { fileHandler: file.NewHandler(afero.NewMemMapFs()), - existingFiles: []string{*config.StatePath}, + existingFiles: []string{constants.StateFilename}, wantErr: true, }, "multiple exist": { fileHandler: file.NewHandler(afero.NewMemMapFs()), - existingFiles: []string{*config.AdminConfPath, *config.MasterSecretPath, *config.StatePath}, + existingFiles: []string{constants.AdminConfFilename, constants.MasterSecretFilename, constants.StateFilename}, wantErr: true, }, } @@ -52,7 +50,7 @@ func TestCheckDirClean(t *testing.T) { require.NoError(tc.fileHandler.Write(f, []byte{1, 2, 3}, file.OptNone)) } - err := checkDirClean(tc.fileHandler, config) + err := checkDirClean(tc.fileHandler) if tc.wantErr { assert.Error(err) diff --git a/cli/cmd/init.go b/cli/cmd/init.go index 0deaf6791..b9c1297d1 100644 --- a/cli/cmd/init.go +++ b/cli/cmd/init.go @@ -19,6 +19,7 @@ import ( coordinatorstate "github.com/edgelesssys/constellation/coordinator/state" "github.com/edgelesssys/constellation/coordinator/util" "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/edgelesssys/constellation/internal/state" "github.com/kr/text" wgquick "github.com/nmiculinic/wg-quick-go" @@ -72,13 +73,13 @@ func runInitialize(cmd *cobra.Command, args []string) error { func initialize(ctx context.Context, cmd *cobra.Command, protCl protoClient, serviceAccountCr serviceAccountCreator, fileHandler file.Handler, config *config.Config, waiter statusWaiter, vpnHandler vpnHandler, ) error { - flagArgs, err := evalFlagArgs(cmd, fileHandler, config) + flagArgs, err := evalFlagArgs(cmd, fileHandler) if err != nil { return err } var stat state.ConstellationState - err = fileHandler.ReadJSON(*config.StatePath, &stat) + err = fileHandler.ReadJSON(constants.StateFilename, &stat) if errors.Is(err, fs.ErrNotExist) { return fmt.Errorf("nothing to initialize: %w", err) } else if err != nil { @@ -101,7 +102,7 @@ func initialize(ctx context.Context, cmd *cobra.Command, protCl protoClient, ser if err != nil { return err } - if err := fileHandler.WriteJSON(*config.StatePath, stat, file.OptOverwrite); err != nil { + if err := fileHandler.WriteJSON(constants.StateFilename, stat, file.OptOverwrite); err != nil { return err } @@ -134,7 +135,7 @@ func initialize(ctx context.Context, cmd *cobra.Command, protCl protoClient, ser return err } - err = result.writeOutput(cmd.OutOrStdout(), fileHandler, config) + err = result.writeOutput(cmd.OutOrStdout(), fileHandler) if err != nil { return err } @@ -144,7 +145,7 @@ func initialize(ctx context.Context, cmd *cobra.Command, protCl protoClient, ser return err } - if err := writeWGQuickFile(fileHandler, config, vpnHandler, vpnConfig); err != nil { + if err := writeWGQuickFile(fileHandler, vpnHandler, vpnConfig); err != nil { return fmt.Errorf("write wg-quick file: %w", err) } @@ -223,15 +224,15 @@ type activationResult struct { } // writeWGQuickFile writes the wg-quick file to the default path. -func writeWGQuickFile(fileHandler file.Handler, config *config.Config, vpnHandler vpnHandler, vpnConfig *wgquick.Config) error { +func writeWGQuickFile(fileHandler file.Handler, vpnHandler vpnHandler, vpnConfig *wgquick.Config) error { data, err := vpnHandler.Marshal(vpnConfig) if err != nil { return err } - return fileHandler.Write(*config.WGQuickConfigPath, data, file.OptNone) + return fileHandler.Write(constants.WGQuickConfigFilename, data, file.OptNone) } -func (r activationResult) writeOutput(wr io.Writer, fileHandler file.Handler, config *config.Config) error { +func (r activationResult) writeOutput(wr io.Writer, fileHandler file.Handler) error { fmt.Fprint(wr, "Your Constellation was successfully initialized.\n\n") tw := tabwriter.NewWriter(wr, 0, 0, 2, ' ', 0) @@ -240,18 +241,18 @@ func (r activationResult) writeOutput(wr io.Writer, fileHandler file.Handler, co writeRow(tw, "Coordinator's public key", r.coordinatorPubKey) writeRow(tw, "Constellation's owner identifier", r.ownerID) writeRow(tw, "Constellation's unique identifier", r.clusterID) - writeRow(tw, "WireGuard configuration file", *config.WGQuickConfigPath) - writeRow(tw, "Kubernetes configuration", *config.AdminConfPath) + writeRow(tw, "WireGuard configuration file", constants.WGQuickConfigFilename) + writeRow(tw, "Kubernetes configuration", constants.AdminConfFilename) tw.Flush() fmt.Fprintln(wr) - if err := fileHandler.Write(*config.AdminConfPath, []byte(r.kubeconfig), file.OptNone); err != nil { + if err := fileHandler.Write(constants.AdminConfFilename, []byte(r.kubeconfig), file.OptNone); err != nil { return fmt.Errorf("write kubeconfig: %w", err) } fmt.Fprintln(wr, "You can now connect to your Constellation by executing:") - fmt.Fprintf(wr, "\twg-quick up ./%s\n", *config.WGQuickConfigPath) - fmt.Fprintf(wr, "\texport KUBECONFIG=\"$PWD/%s\"\n", *config.AdminConfPath) + fmt.Fprintf(wr, "\twg-quick up ./%s\n", constants.WGQuickConfigFilename) + fmt.Fprintf(wr, "\texport KUBECONFIG=\"$PWD/%s\"\n", constants.AdminConfFilename) return nil } @@ -261,7 +262,7 @@ func writeRow(wr io.Writer, col1 string, col2 string) { // evalFlagArgs gets the flag values and does preprocessing of these values like // reading the content from file path flags and deriving other values from flag combinations. -func evalFlagArgs(cmd *cobra.Command, fileHandler file.Handler, config *config.Config) (flagArgs, error) { +func evalFlagArgs(cmd *cobra.Command, fileHandler file.Handler) (flagArgs, error) { userPrivKeyPath, err := cmd.Flags().GetString("privatekey") if err != nil { return flagArgs{}, err @@ -278,7 +279,7 @@ func evalFlagArgs(cmd *cobra.Command, fileHandler file.Handler, config *config.C if err != nil { return flagArgs{}, err } - masterSecret, err := readOrGeneratedMasterSecret(cmd.OutOrStdout(), fileHandler, masterSecretPath, config) + masterSecret, err := readOrGeneratedMasterSecret(cmd.OutOrStdout(), fileHandler, masterSecretPath) if err != nil { return flagArgs{}, err } @@ -338,7 +339,7 @@ func ipsToEndpoints(ips []string, port string) []string { } // readOrGeneratedMasterSecret reads a base64 encoded master secret from file or generates a new 32 byte secret. -func readOrGeneratedMasterSecret(w io.Writer, fileHandler file.Handler, filename string, config *config.Config) ([]byte, error) { +func readOrGeneratedMasterSecret(w io.Writer, fileHandler file.Handler, filename string) ([]byte, error) { if filename != "" { // Try to read the base64 secret from file encodedSecret, err := fileHandler.Read(filename) @@ -360,10 +361,10 @@ func readOrGeneratedMasterSecret(w io.Writer, fileHandler file.Handler, filename if err != nil { return nil, err } - if err := fileHandler.Write(*config.MasterSecretPath, []byte(base64.StdEncoding.EncodeToString(masterSecret)), file.OptNone); err != nil { + if err := fileHandler.Write(constants.MasterSecretFilename, []byte(base64.StdEncoding.EncodeToString(masterSecret)), file.OptNone); err != nil { return nil, err } - fmt.Fprintf(w, "Your Constellation master secret was successfully written to ./%s\n", *config.MasterSecretPath) + fmt.Fprintf(w, "Your Constellation master secret was successfully written to ./%s\n", constants.MasterSecretFilename) return masterSecret, nil } diff --git a/cli/cmd/init_test.go b/cli/cmd/init_test.go index b21a5bd93..7fe991410 100644 --- a/cli/cmd/init_test.go +++ b/cli/cmd/init_test.go @@ -15,6 +15,7 @@ import ( "github.com/edgelesssys/constellation/cli/file" "github.com/edgelesssys/constellation/cli/gcp" "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/edgelesssys/constellation/internal/state" wgquick "github.com/nmiculinic/wg-quick-go" "github.com/spf13/afero" @@ -336,7 +337,7 @@ func TestInitialize(t *testing.T) { cmd.SetErr(&errOut) fs := afero.NewMemMapFs() fileHandler := file.NewHandler(fs) - require.NoError(fileHandler.WriteJSON(*config.StatePath, tc.existingState, file.OptNone)) + require.NoError(fileHandler.WriteJSON(constants.StateFilename, tc.existingState, file.OptNone)) // Write key file to filesystem and set path in flag. require.NoError(afero.Afero{Fs: fs}.WriteFile("privK", []byte(tc.privKey), 0o600)) @@ -376,16 +377,15 @@ func TestWriteOutput(t *testing.T) { var out bytes.Buffer testFs := afero.NewMemMapFs() fileHandler := file.NewHandler(testFs) - config := config.Default() - err := result.writeOutput(&out, fileHandler, config) + err := result.writeOutput(&out, fileHandler) assert.NoError(err) assert.Contains(out.String(), result.clientVpnIP) assert.Contains(out.String(), result.coordinatorPubIP) assert.Contains(out.String(), result.coordinatorPubKey) afs := afero.Afero{Fs: testFs} - adminConf, err := afs.ReadFile(*config.AdminConfPath) + adminConf, err := afs.ReadFile(constants.AdminConfFilename) assert.NoError(err) assert.Equal(result.kubeconfig, string(adminConf)) } @@ -522,14 +522,13 @@ func TestReadOrGeneratedMasterSecret(t *testing.T) { require := require.New(t) fileHandler := file.NewHandler(tc.fs()) - config := config.Default() if tc.createFile { require.NoError(fileHandler.Write(tc.filename, []byte(tc.filecontent), file.OptNone)) } var out bytes.Buffer - secret, err := readOrGeneratedMasterSecret(&out, fileHandler, tc.filename, config) + secret, err := readOrGeneratedMasterSecret(&out, fileHandler, tc.filename) if tc.errExpected { assert.Error(err) @@ -537,7 +536,7 @@ func TestReadOrGeneratedMasterSecret(t *testing.T) { assert.NoError(err) if tc.filename == "" { - require.Contains(out.String(), *config.MasterSecretPath) + require.Contains(out.String(), constants.MasterSecretFilename) filename := strings.Split(out.String(), "./") tc.filename = strings.Trim(filename[1], "\n") } @@ -697,7 +696,7 @@ func TestAutoscaleFlag(t *testing.T) { fs := afero.NewMemMapFs() fileHandler := file.NewHandler(fs) vpnHandler := stubVPNHandler{} - require.NoError(fileHandler.WriteJSON(*config.StatePath, tc.existingState, file.OptNone)) + require.NoError(fileHandler.WriteJSON(constants.StateFilename, tc.existingState, file.OptNone)) // Write key file to filesystem and set path in flag. require.NoError(afero.Afero{Fs: fs}.WriteFile("privK", []byte(tc.privKey), 0o600)) @@ -719,25 +718,21 @@ func TestAutoscaleFlag(t *testing.T) { func TestWriteWGQuickFile(t *testing.T) { testCases := map[string]struct { fileHandler file.Handler - config *config.Config vpnHandler *stubVPNHandler vpnConfig *wgquick.Config wantErr bool }{ "write wg quick file": { fileHandler: file.NewHandler(afero.NewMemMapFs()), - config: &config.Config{WGQuickConfigPath: func(s string) *string { return &s }("a.conf")}, vpnHandler: &stubVPNHandler{marshalRes: "config"}, }, "marshal failed": { fileHandler: file.NewHandler(afero.NewMemMapFs()), - config: &config.Config{WGQuickConfigPath: func(s string) *string { return &s }("a.conf")}, vpnHandler: &stubVPNHandler{marshalErr: errors.New("some err")}, wantErr: true, }, "write fails": { fileHandler: file.NewHandler(afero.NewReadOnlyFs(afero.NewMemMapFs())), - config: &config.Config{WGQuickConfigPath: func(s string) *string { return &s }("a.conf")}, vpnHandler: &stubVPNHandler{marshalRes: "config"}, wantErr: true, }, @@ -747,13 +742,13 @@ func TestWriteWGQuickFile(t *testing.T) { t.Run(name, func(t *testing.T) { assert := assert.New(t) - err := writeWGQuickFile(tc.fileHandler, tc.config, tc.vpnHandler, tc.vpnConfig) + err := writeWGQuickFile(tc.fileHandler, tc.vpnHandler, tc.vpnConfig) if tc.wantErr { assert.Error(err) } else { assert.NoError(err) - file, err := tc.fileHandler.Read(*tc.config.WGQuickConfigPath) + file, err := tc.fileHandler.Read(constants.WGQuickConfigFilename) assert.NoError(err) assert.Contains(string(file), tc.vpnHandler.marshalRes) } diff --git a/cli/cmd/terminate.go b/cli/cmd/terminate.go index 8a36643d1..33eb60331 100644 --- a/cli/cmd/terminate.go +++ b/cli/cmd/terminate.go @@ -14,6 +14,7 @@ import ( "github.com/edgelesssys/constellation/cli/file" gcp "github.com/edgelesssys/constellation/cli/gcp/client" "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/edgelesssys/constellation/internal/state" ) @@ -44,7 +45,7 @@ func runTerminate(cmd *cobra.Command, args []string) error { func terminate(cmd *cobra.Command, fileHandler file.Handler, config *config.Config) error { var stat state.ConstellationState - if err := fileHandler.ReadJSON(*config.StatePath, &stat); err != nil { + if err := fileHandler.ReadJSON(constants.StateFilename, &stat); err != nil { return err } @@ -83,16 +84,16 @@ func terminate(cmd *cobra.Command, fileHandler file.Handler, config *config.Conf cmd.Println("Your Constellation was terminated successfully.") var retErr error - if err := fileHandler.Remove(*config.StatePath); err != nil { - retErr = multierr.Append(err, fmt.Errorf("failed to remove file '%s', please remove manually", *config.StatePath)) + if err := fileHandler.Remove(constants.StateFilename); err != nil { + retErr = multierr.Append(err, fmt.Errorf("failed to remove file '%s', please remove manually", constants.StateFilename)) } - if err := fileHandler.Remove(*config.AdminConfPath); err != nil && !errors.Is(err, fs.ErrNotExist) { - retErr = multierr.Append(err, fmt.Errorf("failed to remove file '%s', please remove manually", *config.AdminConfPath)) + if err := fileHandler.Remove(constants.AdminConfFilename); err != nil && !errors.Is(err, fs.ErrNotExist) { + retErr = multierr.Append(err, fmt.Errorf("failed to remove file '%s', please remove manually", constants.AdminConfFilename)) } - if err := fileHandler.Remove(*config.WGQuickConfigPath); err != nil && !errors.Is(err, fs.ErrNotExist) { - retErr = multierr.Append(err, fmt.Errorf("failed to remove file '%s', please remove manually", *config.WGQuickConfigPath)) + if err := fileHandler.Remove(constants.WGQuickConfigFilename); err != nil && !errors.Is(err, fs.ErrNotExist) { + retErr = multierr.Append(err, fmt.Errorf("failed to remove file '%s', please remove manually", constants.WGQuickConfigFilename)) } return retErr diff --git a/cli/cmd/version.go b/cli/cmd/version.go index 808568ce8..66a806840 100644 --- a/cli/cmd/version.go +++ b/cli/cmd/version.go @@ -1,7 +1,7 @@ package cmd import ( - "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/spf13/cobra" ) @@ -12,7 +12,7 @@ func newVersionCmd() *cobra.Command { Long: `Display version of this CLI`, Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - cmd.Printf("CLI Version: v%s \n", config.Version) + cmd.Printf("CLI Version: v%s \n", constants.CliVersion) }, } return cmd diff --git a/cli/cmd/version_test.go b/cli/cmd/version_test.go index ffb39a71e..abb8f3e3c 100644 --- a/cli/cmd/version_test.go +++ b/cli/cmd/version_test.go @@ -5,7 +5,7 @@ import ( "io" "testing" - "github.com/edgelesssys/constellation/internal/config" + "github.com/edgelesssys/constellation/internal/constants" "github.com/stretchr/testify/assert" ) @@ -21,5 +21,5 @@ func TestVersionCmd(t *testing.T) { s, err := io.ReadAll(b) assert.NoError(err) - assert.Contains(string(s), config.Version) + assert.Contains(string(s), constants.CliVersion) } diff --git a/debugd/cdbg/cmd/deploy.go b/debugd/cdbg/cmd/deploy.go index 885df646c..0439c6253 100644 --- a/debugd/cdbg/cmd/deploy.go +++ b/debugd/cdbg/cmd/deploy.go @@ -16,6 +16,7 @@ import ( depl "github.com/edgelesssys/constellation/debugd/debugd/deploy" pb "github.com/edgelesssys/constellation/debugd/service" "github.com/edgelesssys/constellation/debugd/ssh" + "github.com/edgelesssys/constellation/internal/constants" statec "github.com/edgelesssys/constellation/internal/state" "github.com/spf13/afero" "github.com/spf13/cobra" @@ -66,7 +67,7 @@ func deploy(cmd *cobra.Command, fileHandler file.Handler, config *config.CDBGCon ips = overrideIPs } else { var stat statec.ConstellationState - err := fileHandler.ReadJSON(*config.StatePath, &stat) + err := fileHandler.ReadJSON(constants.StateFilename, &stat) if errors.Is(err, fs.ErrNotExist) { log.Println("Unable to load statefile. Maybe you forgot to run \"constellation create ...\" first?") return fmt.Errorf("loading statefile failed: %w", err) diff --git a/internal/config/config.go b/internal/config/config.go index 1fd42426d..a8be4e7cf 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -11,13 +11,11 @@ import ( "github.com/edgelesssys/constellation/cli/file" gcpClient "github.com/edgelesssys/constellation/cli/gcp/client" "github.com/edgelesssys/constellation/coordinator/attestation/vtpm" + "github.com/edgelesssys/constellation/internal/constants" "google.golang.org/protobuf/proto" ) var ( - // Version is the CLI Version. Left as a separate variable to allow override during build. - Version = "0.0.0" - // gcpPCRs is a map of the expected PCR values for a GCP Constellation node. // TODO: Get a full list once we have stable releases. gcpPCRs = map[uint32][]byte{ @@ -34,22 +32,10 @@ var ( } ) -const ( - coordinatorPort = 9000 - enclaveSSHPort = 2222 - sshPort = 22 - wireguardPort = 51820 - nvmeOverTCPPort = 8009 -) - // Config defines a configuration used by the CLI. // All fields in this struct and its child structs have pointer types // to ensure the default values of the actual type is not confused with an omitted value. type Config struct { - StatePath *string `json:"statepath,omitempty"` - AdminConfPath *string `json:"adminconfpath,omitempty"` - MasterSecretPath *string `json:"mastersecretpath,omitempty"` - WGQuickConfigPath *string `json:"wgquickconfigpath,omitempty"` CoordinatorPort *string `json:"coordinatorport,omitempty"` AutoscalingNodeGroupsMin *int `json:"autoscalingnodegroupsmin,omitempty"` AutoscalingNodeGroupsMax *int `json:"autoscalingnodegroupsmax,omitempty"` @@ -60,11 +46,7 @@ type Config struct { // Default returns a struct with the default config. func Default() *Config { return &Config{ - StatePath: proto.String("constellation-state.json"), - AdminConfPath: proto.String("constellation-admin.conf"), - MasterSecretPath: proto.String("constellation-mastersecret.base64"), - WGQuickConfigPath: proto.String("wg0.conf"), - CoordinatorPort: proto.String(strconv.Itoa(coordinatorPort)), + CoordinatorPort: proto.String(strconv.Itoa(constants.CoordinatorPort)), AutoscalingNodeGroupsMin: intPtr(1), AutoscalingNodeGroupsMax: intPtr(10), StateDiskSizeGB: intPtr(30), @@ -87,37 +69,40 @@ func Default() *Config { Description: "Coordinator default port", Protocol: "TCP", IPRange: "0.0.0.0/0", - Port: coordinatorPort, + Port: constants.CoordinatorPort, }, { Description: "Enclave SSH", Protocol: "TCP", IPRange: "0.0.0.0/0", - Port: enclaveSSHPort, + Port: constants.EnclaveSSHPort, }, { Description: "WireGuard default port", Protocol: "UDP", IPRange: "0.0.0.0/0", - Port: wireguardPort, + Port: constants.WireguardPort, }, { Description: "SSH", Protocol: "TCP", IPRange: "0.0.0.0/0", - Port: sshPort, + Port: constants.SSHPort, }, { Description: "NVMe over TCP", Protocol: "TCP", IPRange: "0.0.0.0/0", - Port: nvmeOverTCPPort, + Port: constants.NVMEOverTCPPort, }, }, }, }, Azure: &AzureConfig{ - Image: proto.String("/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/CONSTELLATION-IMAGES/providers/Microsoft.Compute/galleries/Constellation/images/constellation-coreos/versions/0.0.1649852687"), + SubscriptionID: proto.String("0d202bbb-4fa7-4af8-8125-58c269a05435"), + TenantID: proto.String("adb650a8-5da3-4b15-b4b0-3daf65ff7626"), + Location: proto.String("North Europe"), + Image: proto.String("/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/CONSTELLATION-IMAGES/providers/Microsoft.Compute/galleries/Constellation/images/constellation-coreos/versions/0.0.1649852687"), NetworkSecurityGroupInput: &azureClient.NetworkSecurityGroupInput{ Ingress: cloudtypes.Firewall{ { @@ -125,21 +110,21 @@ func Default() *Config { Description: "Coordinator default port", Protocol: "tcp", IPRange: "0.0.0.0/0", - Port: coordinatorPort, + Port: constants.CoordinatorPort, }, { Name: "wireguard", Description: "WireGuard default port", Protocol: "udp", IPRange: "0.0.0.0/0", - Port: wireguardPort, + Port: constants.WireguardPort, }, { Name: "ssh", Description: "SSH", Protocol: "tcp", IPRange: "0.0.0.0/0", - Port: sshPort, + Port: constants.SSHPort, }, }, }, @@ -147,26 +132,29 @@ func Default() *Config { UserAssignedIdentity: proto.String("/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.ManagedIdentity/userAssignedIdentities/constellation-dev-identity"), }, GCP: &GCPConfig{ - Image: proto.String("constellation-coreos-1649852687"), + Project: proto.String("constellation-331613"), + Region: proto.String("europe-west3"), + Zone: proto.String("europe-west3-b"), + Image: proto.String("constellation-coreos-1649852687"), FirewallInput: &gcpClient.FirewallInput{ Ingress: cloudtypes.Firewall{ { Name: "coordinator", Description: "Coordinator default port", Protocol: "tcp", - Port: coordinatorPort, + Port: constants.CoordinatorPort, }, { Name: "wireguard", Description: "WireGuard default port", Protocol: "udp", - Port: wireguardPort, + Port: constants.WireguardPort, }, { Name: "ssh", Description: "SSH", Protocol: "tcp", - Port: sshPort, + Port: constants.SSHPort, }, }, }, @@ -218,6 +206,9 @@ type EC2Config struct { // AzureConfig are Azure specific configuration values used by the CLI. type AzureConfig struct { + SubscriptionID *string `json:"subscription,omitempty"` // TODO: This will be user input + TenantID *string `json:"tenant,omitempty"` // TODO: This will be user input + Location *string `json:"location,omitempty"` // TODO: This will be user input Image *string `json:"image,omitempty"` NetworkSecurityGroupInput *azureClient.NetworkSecurityGroupInput `json:"networksecuritygroupinput,omitempty"` PCRs *map[uint32][]byte `json:"pcrs,omitempty"` @@ -226,6 +217,9 @@ type AzureConfig struct { // GCPConfig are GCP specific configuration values used by the CLI. type GCPConfig struct { + Project *string `json:"project,omitempty"` // TODO: This will be user input + Region *string `json:"region,omitempty"` // TODO: This will be user input + Zone *string `json:"zone,omitempty"` // TODO: This will be user input Image *string `json:"image,omitempty"` FirewallInput *gcpClient.FirewallInput `json:"firewallinput,omitempty"` VPCsInput *gcpClient.VPCsInput `json:"vpcsinput,omitempty"` diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 2cd0dad8c..6d11b90ad 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -49,9 +49,9 @@ func TestFromFile(t *testing.T) { wantErr bool }{ "overwrite fields": { - from: &Config{StatePath: proto.String("test")}, + from: &Config{CoordinatorPort: proto.String("1000")}, configName: configName, - wantResultMutator: func(c *Config) { c.StatePath = proto.String("test") }, + wantResultMutator: func(c *Config) { c.CoordinatorPort = proto.String("1000") }, }, "overwrite slices": { from: &Config{Provider: someProviderConfig}, @@ -87,9 +87,6 @@ func TestFromFile(t *testing.T) { require.NoError(err) wantResult := Default() tc.wantResultMutator(wantResult) - assert.EqualValues(wantResult.StatePath, result.StatePath) - assert.EqualValues(wantResult.AdminConfPath, result.AdminConfPath) - assert.EqualValues(wantResult.MasterSecretPath, result.MasterSecretPath) assert.EqualValues(wantResult.CoordinatorPort, result.CoordinatorPort) assert.EqualValues(wantResult.AutoscalingNodeGroupsMin, result.AutoscalingNodeGroupsMin) assert.EqualValues(wantResult.AutoscalingNodeGroupsMax, result.AutoscalingNodeGroupsMax) diff --git a/internal/constants/constants.go b/internal/constants/constants.go new file mode 100644 index 000000000..27f3f395e --- /dev/null +++ b/internal/constants/constants.go @@ -0,0 +1,29 @@ +/* +Package constants contains the constants used by Constellation. +Constants should never be overwritable by command line flags or configuration files. +*/ +package constants + +const ( + // + // Ports. + // + + CoordinatorPort = 9000 + EnclaveSSHPort = 2222 + SSHPort = 22 + WireguardPort = 51820 + NVMEOverTCPPort = 8009 + + // + // Filenames. + // + + StateFilename = "constellation-state.json" + AdminConfFilename = "constellation-admin.conf" + MasterSecretFilename = "constellation-mastersecret.base64" + WGQuickConfigFilename = "wg0.conf" +) + +// CliVersion is the version of the CLI. Left as a separate variable to allow override during build. +var CliVersion = "0.0.0"