diff --git a/cli/internal/cmd/miniup.go b/cli/internal/cmd/miniup.go index 815d03360..43ccd0de3 100644 --- a/cli/internal/cmd/miniup.go +++ b/cli/internal/cmd/miniup.go @@ -13,6 +13,7 @@ import ( "net" "github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd" + "github.com/edgelesssys/constellation/v2/cli/internal/featureset" "github.com/edgelesssys/constellation/v2/cli/internal/libvirt" "github.com/edgelesssys/constellation/v2/cli/internal/terraform" "github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi" @@ -142,17 +143,14 @@ func (m *miniUpCmd) prepareConfig(cmd *cobra.Command, fileHandler file.Handler, return nil, errors.New("not overwriting existing config") } } - - config := config.Default() - config.Name = constants.MiniConstellationUID - config.RemoveProviderAndAttestationExcept(cloudprovider.QEMU) - config.StateDiskSizeGB = 8 - - // only release images (e.g. v2.7.0) use the production NVRAM - if !config.IsReleaseImage() { - config.Provider.QEMU.NVRAM = "testing" + if !featureset.CanUseEmbeddedMeasurmentsAndImage { + cmd.PrintErrln("Generating a valid default config is not supported in the OSS build of the Constellation CLI. Consult the documentation for instructions on where to download the enterprise version.") + return nil, errors.New("cannot create a mini cluster without a config file in the OSS build") + } + config, err := config.MiniDefault() + if err != nil { + return nil, fmt.Errorf("mini default config is invalid: %v", err) } - m.log.Debugf("Prepared configuration") return config, fileHandler.WriteYAML(constants.ConfigFilename, config, file.OptOverwrite) diff --git a/cli/internal/featureset/featureset.go b/cli/internal/featureset/featureset.go index ae0c9f050..63e8a5996 100644 --- a/cli/internal/featureset/featureset.go +++ b/cli/internal/featureset/featureset.go @@ -20,6 +20,9 @@ const ( // CanFetchMeasurements returns whether the current build can fetch measurements. const CanFetchMeasurements = canFetchMeasurements +// CanUseEmbeddedMeasurmentsAndImage returns whether the current build can use embedded measurements and can provide a node image. +const CanUseEmbeddedMeasurmentsAndImage = canUseEmbeddedMeasurmentsAndImage + // CanUpgradeCheck returns whether the current build can check for upgrades. // This also includes fetching new measurements. const CanUpgradeCheck = canUpgradeCheck diff --git a/cli/internal/featureset/featureset_enterprise.go b/cli/internal/featureset/featureset_enterprise.go index cb1b0157f..3cd69c785 100644 --- a/cli/internal/featureset/featureset_enterprise.go +++ b/cli/internal/featureset/featureset_enterprise.go @@ -9,7 +9,8 @@ SPDX-License-Identifier: AGPL-3.0-only package featureset const ( - edition = EditionEnterprise - canFetchMeasurements = true - canUpgradeCheck = true + edition = EditionEnterprise + canFetchMeasurements = true + canUpgradeCheck = true + canUseEmbeddedMeasurmentsAndImage = true ) diff --git a/cli/internal/featureset/featureset_oss.go b/cli/internal/featureset/featureset_oss.go index 426be123f..2072641d3 100644 --- a/cli/internal/featureset/featureset_oss.go +++ b/cli/internal/featureset/featureset_oss.go @@ -9,7 +9,8 @@ SPDX-License-Identifier: AGPL-3.0-only package featureset const ( - edition = EditionOSS - canFetchMeasurements = false - canUpgradeCheck = false + edition = EditionOSS + canFetchMeasurements = false + canUpgradeCheck = false + canUseEmbeddedMeasurmentsAndImage = false ) diff --git a/internal/config/config.go b/internal/config/config.go index 537aeb9e4..27345f120 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -298,6 +298,7 @@ type AttestationConfig struct { } // Default returns a struct with the default config. +// IMPORTANT: Ensure that any state mutation is followed by a call to Validate() to ensure that the config is always in a valid state. Avoid usage outside of tests. func Default() *Config { return &Config{ Version: Version3, @@ -367,6 +368,19 @@ func Default() *Config { } } +// MiniDefault returns a default config for a mini cluster. +func MiniDefault() (*Config, error) { + config := Default() + config.Name = constants.MiniConstellationUID + config.RemoveProviderAndAttestationExcept(cloudprovider.QEMU) + config.StateDiskSizeGB = 8 + // only release images (e.g. v2.7.0) use the production NVRAM + if !config.IsReleaseImage() { + config.Provider.QEMU.NVRAM = "testing" + } + return config, config.Validate(false) +} + // fromFile returns config file with `name` read from `fileHandler` by parsing // it as YAML. You should prefer config.New to read env vars and validate // config in a consistent manner. diff --git a/internal/config/config_test.go b/internal/config/config_test.go index cbd666647..4c07fd747 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -376,6 +376,15 @@ func TestValidate(t *testing.T) { return cnf }(), }, + "miniup default config is not valid because image and measurements are missing in OSS": { + cnf: func() *Config { + config, _ := MiniDefault() + require.NotNil(t, config) + return config + }(), + wantErr: true, + wantErrCount: 2, + }, } for name, tc := range testCases { @@ -389,7 +398,7 @@ func TestValidate(t *testing.T) { assert.Error(err) var valErr *ValidationError require.ErrorAs(err, &valErr) - assert.Equal(tc.wantErrCount, valErr.messagesCount()) + assert.Equalf(tc.wantErrCount, valErr.messagesCount(), "Got unexpected error count: %d: %s", valErr.messagesCount(), valErr.LongMessage()) return } assert.NoError(err)