mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-04-20 07:25:51 -04:00
s3 draft working
fix tests with DefaultWithPanic()
This commit is contained in:
parent
934722ae76
commit
0f942bafca
@ -41,18 +41,18 @@ func TestCreator(t *testing.T) {
|
||||
"gcp": {
|
||||
tfClient: &stubTerraformClient{ip: ip},
|
||||
provider: cloudprovider.GCP,
|
||||
config: config.Default(),
|
||||
config: config.DefaultWithPanic(),
|
||||
},
|
||||
"gcp newTerraformClient error": {
|
||||
newTfClientErr: someErr,
|
||||
provider: cloudprovider.GCP,
|
||||
config: config.Default(),
|
||||
config: config.DefaultWithPanic(),
|
||||
wantErr: true,
|
||||
},
|
||||
"gcp create cluster error": {
|
||||
tfClient: &stubTerraformClient{createClusterErr: someErr},
|
||||
provider: cloudprovider.GCP,
|
||||
config: config.Default(),
|
||||
config: config.DefaultWithPanic(),
|
||||
wantErr: true,
|
||||
wantRollback: true,
|
||||
wantTerraformRollback: true,
|
||||
@ -61,7 +61,7 @@ func TestCreator(t *testing.T) {
|
||||
tfClient: &stubTerraformClient{ip: ip},
|
||||
provider: cloudprovider.Azure,
|
||||
config: func() *config.Config {
|
||||
cfg := config.Default()
|
||||
cfg := config.DefaultWithPanic()
|
||||
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
return cfg
|
||||
}(),
|
||||
@ -71,7 +71,7 @@ func TestCreator(t *testing.T) {
|
||||
tfClient: &stubTerraformClient{ip: ip},
|
||||
provider: cloudprovider.Azure,
|
||||
config: func() *config.Config {
|
||||
cfg := config.Default()
|
||||
cfg := config.DefaultWithPanic()
|
||||
cfg.Attestation = config.AttestationConfig{
|
||||
AzureTrustedLaunch: &config.AzureTrustedLaunch{},
|
||||
}
|
||||
@ -83,7 +83,7 @@ func TestCreator(t *testing.T) {
|
||||
tfClient: &stubTerraformClient{ip: ip},
|
||||
provider: cloudprovider.Azure,
|
||||
config: func() *config.Config {
|
||||
cfg := config.Default()
|
||||
cfg := config.DefaultWithPanic()
|
||||
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
return cfg
|
||||
}(),
|
||||
@ -94,7 +94,7 @@ func TestCreator(t *testing.T) {
|
||||
newTfClientErr: someErr,
|
||||
provider: cloudprovider.Azure,
|
||||
config: func() *config.Config {
|
||||
cfg := config.Default()
|
||||
cfg := config.DefaultWithPanic()
|
||||
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
return cfg
|
||||
}(),
|
||||
@ -105,7 +105,7 @@ func TestCreator(t *testing.T) {
|
||||
tfClient: &stubTerraformClient{createClusterErr: someErr},
|
||||
provider: cloudprovider.Azure,
|
||||
config: func() *config.Config {
|
||||
cfg := config.Default()
|
||||
cfg := config.DefaultWithPanic()
|
||||
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
return cfg
|
||||
}(),
|
||||
@ -119,7 +119,7 @@ func TestCreator(t *testing.T) {
|
||||
libvirt: &stubLibvirtRunner{},
|
||||
provider: cloudprovider.OpenStack,
|
||||
config: func() *config.Config {
|
||||
cfg := config.Default()
|
||||
cfg := config.DefaultWithPanic()
|
||||
cfg.Provider.OpenStack.Cloud = "testcloud"
|
||||
return cfg
|
||||
}(),
|
||||
@ -128,7 +128,7 @@ func TestCreator(t *testing.T) {
|
||||
tfClient: &stubTerraformClient{ip: ip},
|
||||
libvirt: &stubLibvirtRunner{},
|
||||
provider: cloudprovider.OpenStack,
|
||||
config: config.Default(),
|
||||
config: config.DefaultWithPanic(),
|
||||
wantErr: true,
|
||||
},
|
||||
"openstack newTerraformClient error": {
|
||||
@ -136,7 +136,7 @@ func TestCreator(t *testing.T) {
|
||||
libvirt: &stubLibvirtRunner{},
|
||||
provider: cloudprovider.OpenStack,
|
||||
config: func() *config.Config {
|
||||
cfg := config.Default()
|
||||
cfg := config.DefaultWithPanic()
|
||||
cfg.Provider.OpenStack.Cloud = "testcloud"
|
||||
return cfg
|
||||
}(),
|
||||
@ -147,7 +147,7 @@ func TestCreator(t *testing.T) {
|
||||
libvirt: &stubLibvirtRunner{},
|
||||
provider: cloudprovider.OpenStack,
|
||||
config: func() *config.Config {
|
||||
cfg := config.Default()
|
||||
cfg := config.DefaultWithPanic()
|
||||
cfg.Provider.OpenStack.Cloud = "testcloud"
|
||||
return cfg
|
||||
}(),
|
||||
@ -159,21 +159,21 @@ func TestCreator(t *testing.T) {
|
||||
tfClient: &stubTerraformClient{ip: ip},
|
||||
libvirt: &stubLibvirtRunner{},
|
||||
provider: cloudprovider.QEMU,
|
||||
config: config.Default(),
|
||||
config: config.DefaultWithPanic(),
|
||||
wantErr: failOnNonAMD64,
|
||||
},
|
||||
"qemu newTerraformClient error": {
|
||||
newTfClientErr: someErr,
|
||||
libvirt: &stubLibvirtRunner{},
|
||||
provider: cloudprovider.QEMU,
|
||||
config: config.Default(),
|
||||
config: config.DefaultWithPanic(),
|
||||
wantErr: true,
|
||||
},
|
||||
"qemu create cluster error": {
|
||||
tfClient: &stubTerraformClient{createClusterErr: someErr},
|
||||
libvirt: &stubLibvirtRunner{},
|
||||
provider: cloudprovider.QEMU,
|
||||
config: config.Default(),
|
||||
config: config.DefaultWithPanic(),
|
||||
wantErr: true,
|
||||
wantRollback: !failOnNonAMD64, // if we run on non-AMD64/linux, we don't get to a point where rollback is needed
|
||||
wantTerraformRollback: true,
|
||||
@ -182,14 +182,14 @@ func TestCreator(t *testing.T) {
|
||||
tfClient: &stubTerraformClient{ip: ip},
|
||||
libvirt: &stubLibvirtRunner{startErr: someErr},
|
||||
provider: cloudprovider.QEMU,
|
||||
config: config.Default(),
|
||||
config: config.DefaultWithPanic(),
|
||||
wantRollback: !failOnNonAMD64,
|
||||
wantTerraformRollback: false,
|
||||
wantErr: true,
|
||||
},
|
||||
"unknown provider": {
|
||||
provider: cloudprovider.Unknown,
|
||||
config: config.Default(),
|
||||
config: config.DefaultWithPanic(),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ func TestConfigFetchMeasurements(t *testing.T) {
|
||||
cmd.Flags().Bool("force", true, "") // register persistent flag manually
|
||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
||||
|
||||
gcpConfig := defaultConfigWithExpectedMeasurements(t, config.Default(), cloudprovider.GCP)
|
||||
gcpConfig := defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), cloudprovider.GCP)
|
||||
gcpConfig.Image = "v999.999.999"
|
||||
|
||||
err := fileHandler.WriteYAML(constants.ConfigFilename, gcpConfig, file.OptMkdirAll)
|
||||
|
@ -36,7 +36,7 @@ func newConfigGenerateCmd() *cobra.Command {
|
||||
RunE: runConfigGenerate,
|
||||
}
|
||||
cmd.Flags().StringP("file", "f", constants.ConfigFilename, "path to output file, or '-' for stdout")
|
||||
cmd.Flags().StringP("kubernetes", "k", semver.MajorMinor(config.Default().KubernetesVersion), "Kubernetes version to use in format MAJOR.MINOR")
|
||||
cmd.Flags().StringP("kubernetes", "k", semver.MajorMinor(config.DefaultWithPanic().KubernetesVersion), "Kubernetes version to use in format MAJOR.MINOR")
|
||||
cmd.Flags().StringP("attestation", "a", "", fmt.Sprintf("attestation variant to use %s. If not specified, the default for the cloud provider is used", printFormattedSlice(variant.GetAvailableAttestationTypes())))
|
||||
|
||||
return cmd
|
||||
@ -103,7 +103,10 @@ func (cg *configGenerateCmd) configGenerate(cmd *cobra.Command, fileHandler file
|
||||
|
||||
// createConfig creates a config file for the given provider.
|
||||
func createConfigWithAttestationType(provider cloudprovider.Provider, attestationVariant variant.Variant) (*config.Config, error) {
|
||||
conf := config.Default()
|
||||
conf, err := config.Default()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating default config: %w", err)
|
||||
}
|
||||
conf.RemoveProviderExcept(provider)
|
||||
|
||||
// set a lower default for QEMU's state disk
|
||||
|
@ -79,7 +79,7 @@ func TestConfigGenerateDefault(t *testing.T) {
|
||||
var readConfig config.Config
|
||||
err := fileHandler.ReadYAML(constants.ConfigFilename, &readConfig)
|
||||
assert.NoError(err)
|
||||
assert.Equal(*config.Default(), readConfig)
|
||||
assert.Equal(*config.DefaultWithPanic(), readConfig)
|
||||
}
|
||||
|
||||
func TestConfigGenerateDefaultGCPSpecific(t *testing.T) {
|
||||
@ -89,7 +89,7 @@ func TestConfigGenerateDefaultGCPSpecific(t *testing.T) {
|
||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
||||
cmd := newConfigGenerateCmd()
|
||||
|
||||
wantConf := config.Default()
|
||||
wantConf := config.DefaultWithPanic()
|
||||
wantConf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
||||
|
||||
cg := &configGenerateCmd{log: logger.NewTest(t)}
|
||||
@ -140,7 +140,7 @@ func TestConfigGenerateStdOut(t *testing.T) {
|
||||
var readConfig config.Config
|
||||
require.NoError(yaml.NewDecoder(&outBuffer).Decode(&readConfig))
|
||||
|
||||
assert.Equal(*config.Default(), readConfig)
|
||||
assert.Equal(*config.DefaultWithPanic(), readConfig)
|
||||
}
|
||||
|
||||
func TestNoValidProviderAttestationCombination(t *testing.T) {
|
||||
@ -163,7 +163,7 @@ func TestNoValidProviderAttestationCombination(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidProviderAttestationCombination(t *testing.T) {
|
||||
defaultAttestation := config.Default().Attestation
|
||||
defaultAttestation := config.DefaultWithPanic().Attestation
|
||||
tests := []struct {
|
||||
provider cloudprovider.Provider
|
||||
attestation variant.Variant
|
||||
@ -213,7 +213,7 @@ func TestValidProviderAttestationCombination(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAttestationArgument(t *testing.T) {
|
||||
defaultAttestation := config.Default().Attestation
|
||||
defaultAttestation := config.DefaultWithPanic().Attestation
|
||||
tests := []struct {
|
||||
name string
|
||||
provider cloudprovider.Provider
|
||||
|
@ -27,7 +27,7 @@ func TestCreate(t *testing.T) {
|
||||
fsWithDefaultConfig := func(require *require.Assertions, provider cloudprovider.Provider) afero.Fs {
|
||||
fs := afero.NewMemMapFs()
|
||||
file := file.NewHandler(fs)
|
||||
require.NoError(file.WriteYAML(constants.ConfigFilename, defaultConfigWithExpectedMeasurements(t, config.Default(), provider)))
|
||||
require.NoError(file.WriteYAML(constants.ConfigFilename, defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), provider)))
|
||||
return fs
|
||||
}
|
||||
idFile := clusterid.File{IP: "192.0.2.1"}
|
||||
@ -114,7 +114,7 @@ func TestCreate(t *testing.T) {
|
||||
fs := afero.NewMemMapFs()
|
||||
fileHandler := file.NewHandler(fs)
|
||||
require.NoError(fileHandler.Write(constants.AdminConfFilename, []byte{1}, file.OptNone))
|
||||
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, defaultConfigWithExpectedMeasurements(t, config.Default(), csp)))
|
||||
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), csp)))
|
||||
return fs
|
||||
},
|
||||
creator: &stubCloudCreator{},
|
||||
@ -129,7 +129,7 @@ func TestCreate(t *testing.T) {
|
||||
fs := afero.NewMemMapFs()
|
||||
fileHandler := file.NewHandler(fs)
|
||||
require.NoError(fileHandler.Write(constants.MasterSecretFilename, []byte{1}, file.OptNone))
|
||||
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, defaultConfigWithExpectedMeasurements(t, config.Default(), csp)))
|
||||
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), csp)))
|
||||
return fs
|
||||
},
|
||||
creator: &stubCloudCreator{},
|
||||
@ -162,7 +162,7 @@ func TestCreate(t *testing.T) {
|
||||
setupFs: func(require *require.Assertions, csp cloudprovider.Provider) afero.Fs {
|
||||
fs := afero.NewMemMapFs()
|
||||
fileHandler := file.NewHandler(fs)
|
||||
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, defaultConfigWithExpectedMeasurements(t, config.Default(), csp)))
|
||||
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), csp)))
|
||||
return afero.NewReadOnlyFs(fs)
|
||||
},
|
||||
creator: &stubCloudCreator{},
|
||||
|
@ -60,7 +60,7 @@ func newIAMCreateCmd() *cobra.Command {
|
||||
|
||||
cmd.PersistentFlags().BoolP("yes", "y", false, "create the IAM configuration without further confirmation")
|
||||
cmd.PersistentFlags().Bool("generate-config", false, "automatically generate a configuration file and fill in the required fields")
|
||||
cmd.PersistentFlags().StringP("kubernetes", "k", semver.MajorMinor(config.Default().KubernetesVersion), "Kubernetes version to use in format MAJOR.MINOR - only usable in combination with --generate-config")
|
||||
cmd.PersistentFlags().StringP("kubernetes", "k", semver.MajorMinor(config.DefaultWithPanic().KubernetesVersion), "Kubernetes version to use in format MAJOR.MINOR - only usable in combination with --generate-config")
|
||||
|
||||
cmd.AddCommand(newIAMCreateAWSCmd())
|
||||
cmd.AddCommand(newIAMCreateAzureCmd())
|
||||
|
@ -275,7 +275,7 @@ func TestIAMCreateAWS(t *testing.T) {
|
||||
// register persistent flags manually
|
||||
cmd.Flags().String("config", constants.ConfigFilename, "")
|
||||
cmd.Flags().Bool("generate-config", false, "")
|
||||
cmd.Flags().String("kubernetes", semver.MajorMinor(config.Default().KubernetesVersion), "")
|
||||
cmd.Flags().String("kubernetes", semver.MajorMinor(config.DefaultWithPanic().KubernetesVersion), "")
|
||||
cmd.Flags().Bool("yes", false, "")
|
||||
cmd.Flags().String("name", "constell", "")
|
||||
cmd.Flags().String("tf-log", "NONE", "")
|
||||
@ -554,7 +554,7 @@ func TestIAMCreateAzure(t *testing.T) {
|
||||
// register persistent flags manually
|
||||
cmd.Flags().String("config", constants.ConfigFilename, "")
|
||||
cmd.Flags().Bool("generate-config", false, "")
|
||||
cmd.Flags().String("kubernetes", semver.MajorMinor(config.Default().KubernetesVersion), "")
|
||||
cmd.Flags().String("kubernetes", semver.MajorMinor(config.DefaultWithPanic().KubernetesVersion), "")
|
||||
cmd.Flags().Bool("yes", false, "")
|
||||
cmd.Flags().String("name", "constell", "")
|
||||
cmd.Flags().String("tf-log", "NONE", "")
|
||||
@ -861,7 +861,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||
// register persistent flags manually
|
||||
cmd.Flags().String("config", constants.ConfigFilename, "")
|
||||
cmd.Flags().Bool("generate-config", false, "")
|
||||
cmd.Flags().String("kubernetes", semver.MajorMinor(config.Default().KubernetesVersion), "")
|
||||
cmd.Flags().String("kubernetes", semver.MajorMinor(config.DefaultWithPanic().KubernetesVersion), "")
|
||||
cmd.Flags().Bool("yes", false, "")
|
||||
cmd.Flags().String("name", "constell", "")
|
||||
cmd.Flags().String("tf-log", "NONE", "")
|
||||
|
@ -156,7 +156,7 @@ func TestInitialize(t *testing.T) {
|
||||
// File system preparation
|
||||
fs := afero.NewMemMapFs()
|
||||
fileHandler := file.NewHandler(fs)
|
||||
config := defaultConfigWithExpectedMeasurements(t, config.Default(), tc.provider)
|
||||
config := defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), tc.provider)
|
||||
if tc.configMutator != nil {
|
||||
tc.configMutator(config)
|
||||
}
|
||||
@ -427,7 +427,7 @@ func TestAttestation(t *testing.T) {
|
||||
fileHandler := file.NewHandler(fs)
|
||||
require.NoError(fileHandler.WriteJSON(constants.ClusterIDsFileName, existingIDFile, file.OptNone))
|
||||
|
||||
cfg := config.Default()
|
||||
cfg := config.DefaultWithPanic()
|
||||
cfg.Image = "image"
|
||||
cfg.RemoveProviderAndAttestationExcept(cloudprovider.QEMU)
|
||||
cfg.Attestation.QEMUVTPM.Measurements[0] = measurements.WithAllBytes(0x00, measurements.Enforce, measurements.PCRMeasurementLength)
|
||||
|
@ -214,7 +214,10 @@ func (m *miniUpCmd) prepareConfig(cmd *cobra.Command, fileHandler file.Handler,
|
||||
}
|
||||
}
|
||||
|
||||
config := config.Default()
|
||||
config, err := config.Default()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Name = constants.MiniConstellationUID
|
||||
config.RemoveProviderAndAttestationExcept(cloudprovider.QEMU)
|
||||
config.StateDiskSizeGB = 8
|
||||
|
@ -153,7 +153,7 @@ func TestRecover(t *testing.T) {
|
||||
fs := afero.NewMemMapFs()
|
||||
fileHandler := file.NewHandler(fs)
|
||||
|
||||
config := defaultConfigWithExpectedMeasurements(t, config.Default(), cloudprovider.GCP)
|
||||
config := defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), cloudprovider.GCP)
|
||||
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, config))
|
||||
|
||||
require.NoError(fileHandler.WriteJSON(
|
||||
|
@ -30,6 +30,8 @@ import (
|
||||
|
||||
func TestUpgradeApply(t *testing.T) {
|
||||
someErr := errors.New("some error")
|
||||
azureSEVSNP, err := config.DefaultForAzureSEVSNP()
|
||||
require.NoError(t, err)
|
||||
testCases := map[string]struct {
|
||||
upgrader stubUpgrader
|
||||
fetcher stubImageFetcher
|
||||
@ -38,12 +40,12 @@ func TestUpgradeApply(t *testing.T) {
|
||||
stdin string
|
||||
}{
|
||||
"success": {
|
||||
upgrader: stubUpgrader{currentConfig: config.DefaultForAzureSEVSNP()},
|
||||
upgrader: stubUpgrader{currentConfig: azureSEVSNP},
|
||||
yesFlag: true,
|
||||
},
|
||||
"nodeVersion some error": {
|
||||
upgrader: stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
currentConfig: azureSEVSNP,
|
||||
nodeVersionErr: someErr,
|
||||
},
|
||||
wantErr: true,
|
||||
@ -51,14 +53,14 @@ func TestUpgradeApply(t *testing.T) {
|
||||
},
|
||||
"nodeVersion in progress error": {
|
||||
upgrader: stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
currentConfig: azureSEVSNP,
|
||||
nodeVersionErr: kubernetes.ErrInProgress,
|
||||
},
|
||||
yesFlag: true,
|
||||
},
|
||||
"helm other error": {
|
||||
upgrader: stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
currentConfig: azureSEVSNP,
|
||||
helmErr: someErr,
|
||||
},
|
||||
wantErr: true,
|
||||
@ -67,7 +69,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||
},
|
||||
"check terraform error": {
|
||||
upgrader: stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
currentConfig: azureSEVSNP,
|
||||
checkTerraformErr: someErr,
|
||||
},
|
||||
fetcher: stubImageFetcher{},
|
||||
@ -76,7 +78,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||
},
|
||||
"abort": {
|
||||
upgrader: stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
currentConfig: azureSEVSNP,
|
||||
terraformDiff: true,
|
||||
},
|
||||
fetcher: stubImageFetcher{},
|
||||
@ -85,7 +87,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||
},
|
||||
"clean terraform error": {
|
||||
upgrader: stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
currentConfig: azureSEVSNP,
|
||||
cleanTerraformErr: someErr,
|
||||
terraformDiff: true,
|
||||
},
|
||||
@ -95,7 +97,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||
},
|
||||
"plan terraform error": {
|
||||
upgrader: stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
currentConfig: azureSEVSNP,
|
||||
planTerraformErr: someErr,
|
||||
},
|
||||
fetcher: stubImageFetcher{},
|
||||
@ -104,7 +106,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||
},
|
||||
"apply terraform error": {
|
||||
upgrader: stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
currentConfig: azureSEVSNP,
|
||||
applyTerraformErr: someErr,
|
||||
terraformDiff: true,
|
||||
},
|
||||
@ -114,7 +116,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||
},
|
||||
"fetch reference error": {
|
||||
upgrader: stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
currentConfig: azureSEVSNP,
|
||||
},
|
||||
fetcher: stubImageFetcher{fetchReferenceErr: someErr},
|
||||
wantErr: true,
|
||||
@ -138,7 +140,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||
}
|
||||
|
||||
handler := file.NewHandler(afero.NewMemMapFs())
|
||||
cfg := defaultConfigWithExpectedMeasurements(t, config.Default(), cloudprovider.Azure)
|
||||
cfg := defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), cloudprovider.Azure)
|
||||
require.NoError(handler.WriteYAML(constants.ConfigFilename, cfg))
|
||||
require.NoError(handler.WriteJSON(constants.ClusterIDsFileName, clusterid.File{}))
|
||||
|
||||
|
@ -261,7 +261,7 @@ func TestUpgradeCheck(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
||||
cfg := defaultConfigWithExpectedMeasurements(t, config.Default(), tc.csp)
|
||||
cfg := defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), tc.csp)
|
||||
require.NoError(fileHandler.WriteYAML(tc.flags.configPath, cfg))
|
||||
|
||||
checkCmd := upgradeCheckCmd{
|
||||
|
@ -183,7 +183,7 @@ func TestVerify(t *testing.T) {
|
||||
}
|
||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
||||
|
||||
config := defaultConfigWithExpectedMeasurements(t, config.Default(), tc.provider)
|
||||
config := defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), tc.provider)
|
||||
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, config))
|
||||
if tc.idFile != nil {
|
||||
require.NoError(fileHandler.WriteJSON(constants.ClusterIDsFileName, tc.idFile, file.OptNone))
|
||||
|
@ -88,7 +88,7 @@ func TestUpgradeRelease(t *testing.T) {
|
||||
|
||||
chart, err := loadChartsDir(helmFS, certManagerInfo.path)
|
||||
require.NoError(err)
|
||||
err = client.upgradeRelease(context.Background(), 0, config.Default(), chart, tc.allowDestructive)
|
||||
err = client.upgradeRelease(context.Background(), 0, config.DefaultWithPanic(), chart, tc.allowDestructive)
|
||||
if tc.wantError {
|
||||
tc.assertCorrectError(t, err)
|
||||
return
|
||||
|
@ -46,7 +46,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||
}{
|
||||
"success": {
|
||||
conf: func() *config.Config {
|
||||
conf := config.Default()
|
||||
conf := config.DefaultWithPanic()
|
||||
conf.Image = "v1.2.3"
|
||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
||||
return conf
|
||||
@ -62,7 +62,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||
},
|
||||
"only k8s upgrade": {
|
||||
conf: func() *config.Config {
|
||||
conf := config.Default()
|
||||
conf := config.DefaultWithPanic()
|
||||
conf.Image = "v1.2.2"
|
||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
||||
return conf
|
||||
@ -83,7 +83,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||
},
|
||||
"only image upgrade": {
|
||||
conf: func() *config.Config {
|
||||
conf := config.Default()
|
||||
conf := config.DefaultWithPanic()
|
||||
conf.Image = "v1.2.3"
|
||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[0]
|
||||
return conf
|
||||
@ -104,7 +104,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||
},
|
||||
"not an upgrade": {
|
||||
conf: func() *config.Config {
|
||||
conf := config.Default()
|
||||
conf := config.DefaultWithPanic()
|
||||
conf.Image = "v1.2.2"
|
||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[0]
|
||||
return conf
|
||||
@ -120,7 +120,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||
},
|
||||
"upgrade in progress": {
|
||||
conf: func() *config.Config {
|
||||
conf := config.Default()
|
||||
conf := config.DefaultWithPanic()
|
||||
conf.Image = "v1.2.3"
|
||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
||||
return conf
|
||||
@ -139,7 +139,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||
},
|
||||
"get error": {
|
||||
conf: func() *config.Config {
|
||||
conf := config.Default()
|
||||
conf := config.DefaultWithPanic()
|
||||
conf.Image = "v1.2.3"
|
||||
return conf
|
||||
}(),
|
||||
@ -151,7 +151,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||
},
|
||||
"image too new valid k8s": {
|
||||
conf: func() *config.Config {
|
||||
conf := config.Default()
|
||||
conf := config.DefaultWithPanic()
|
||||
conf.Image = "v1.4.2"
|
||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
||||
return conf
|
||||
@ -173,7 +173,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||
},
|
||||
"apply returns bad object": {
|
||||
conf: func() *config.Config {
|
||||
conf := config.Default()
|
||||
conf := config.DefaultWithPanic()
|
||||
conf.Image = "v1.2.3"
|
||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
||||
return conf
|
||||
|
@ -213,7 +213,7 @@ func TestTrustedKeyFromSNP(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
cfg := config.DefaultForAzureSEVSNP()
|
||||
cfg, err := config.DefaultForAzureSEVSNP()
|
||||
cfg.FirmwareSignerConfig = config.SNPFirmwareSignerConfig{
|
||||
AcceptedKeyDigests: tc.idkeydigests,
|
||||
EnforcementPolicy: tc.enforceIDKeyDigest,
|
||||
@ -348,7 +348,10 @@ func TestNewSNPReportFromBytes(t *testing.T) {
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
cfg, err := config.DefaultForAzureSEVSNP()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
@ -363,7 +366,6 @@ func TestNewSNPReportFromBytes(t *testing.T) {
|
||||
assert.NotNil(report)
|
||||
assert.Equal(hex.EncodeToString(report.IDKeyDigest[:]), "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1")
|
||||
// This is a canary for us: If this fails in the future we possibly downgraded a SVN.
|
||||
cfg := config.DefaultForAzureSEVSNP()
|
||||
assert.True(report.LaunchTCB.isVersion(cfg.BootloaderVersion, cfg.TEEVersion, cfg.SNPVersion, cfg.MicrocodeVersion))
|
||||
}
|
||||
})
|
||||
|
@ -39,7 +39,10 @@ import (
|
||||
// TODO(v2.8 | AB#3130): Update tool to use variant.Variant instead of cloudprovider.Provider
|
||||
|
||||
func main() {
|
||||
defaultConf := config.Default()
|
||||
defaultConf, err := config.Default()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("Generating measurements for %s\n", defaultConf.Image)
|
||||
|
||||
const filePath = "./measurements_enterprise.go"
|
||||
|
29
internal/attestationapi/BUILD.bazel
Normal file
29
internal/attestationapi/BUILD.bazel
Normal file
@ -0,0 +1,29 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
load("//bazel/go:go_test.bzl", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "attestationapi",
|
||||
srcs = ["attestationapi.go"],
|
||||
importpath = "github.com/edgelesssys/constellation/v2/internal/attestationapi",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/kms/storage",
|
||||
"//internal/kms/storage/awss3",
|
||||
"//internal/kms/uri",
|
||||
"//internal/variant",
|
||||
"//internal/versionsapi",
|
||||
"//internal/versionsapi/fetcher",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "attestationapi_test",
|
||||
srcs = ["attestationapi_test.go"],
|
||||
deps = [
|
||||
":attestationapi",
|
||||
"//internal/kms/uri",
|
||||
"//internal/variant",
|
||||
"@com_github_stretchr_testify//assert",
|
||||
"@com_github_stretchr_testify//require",
|
||||
],
|
||||
)
|
149
internal/attestationapi/attestationapi.go
Normal file
149
internal/attestationapi/attestationapi.go
Normal file
@ -0,0 +1,149 @@
|
||||
package attestationapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/kms/storage"
|
||||
"github.com/edgelesssys/constellation/v2/internal/kms/storage/awss3"
|
||||
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
|
||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi/fetcher"
|
||||
)
|
||||
|
||||
const (
|
||||
Bootloader Type = "bootloader" // Bootloader is the version of the Azure SEVSNP bootloader.
|
||||
TEE Type = "tee" // TEE is the version of the Azure SEVSNP TEE.
|
||||
SNP Type = "snp" // SNP is the version of the Azure SEVSNP SNP.
|
||||
Microcode Type = "microcode" // Microcode is the version of the Azure SEVSNP microcode.
|
||||
)
|
||||
|
||||
// AttestationPath is the path to the attestation versions.
|
||||
const AttestationPath = "constellation/v1/attestation"
|
||||
|
||||
// AzureSEVSNP is the latest version of each component of the Azure SEVSNP.
|
||||
// used for testing only
|
||||
var AzureSEVSNP = versionsapi.AzureSEVSNPVersion{
|
||||
Bootloader: 2,
|
||||
TEE: 0,
|
||||
SNP: 6,
|
||||
Microcode: 93,
|
||||
}
|
||||
|
||||
// Type is the type of the version to be requested.
|
||||
type Type (string)
|
||||
|
||||
// AttestationVersionRepo manages (modifies) the version information for the attestation variants.
|
||||
type AttestationVersionRepo struct {
|
||||
*awss3.Storage
|
||||
}
|
||||
|
||||
// NewAttestationVersionRepo returns a new AttestationVersionRepo.
|
||||
func NewAttestationVersionRepo(ctx context.Context, cfg uri.AWSS3Config) (*AttestationVersionRepo, error) {
|
||||
s3, err := awss3.New(ctx, cfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create s3 storage: %w", err)
|
||||
}
|
||||
return &AttestationVersionRepo{s3}, nil
|
||||
}
|
||||
|
||||
// UploadAzureSEVSNP uploads the latest version numbers of the Azure SEVSNP.
|
||||
func (a AttestationVersionRepo) UploadAzureSEVSNP(ctx context.Context, versions versionsapi.AzureSEVSNPVersion, date time.Time) error {
|
||||
bt, err := json.Marshal(versions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
variant := variant.AzureSEVSNP{}
|
||||
fname := date.Format("2006-01-02-15-04") + ".json"
|
||||
|
||||
err = a.Put(ctx, fmt.Sprintf("%s/%s/%s", AttestationPath, variant.String(), fname), bt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return a.addVersionToList(ctx, variant, fname)
|
||||
}
|
||||
|
||||
func (a AttestationVersionRepo) addVersionToList(ctx context.Context, attestation variant.Variant, fname string) error {
|
||||
versions := []string{}
|
||||
key := path.Join(AttestationPath, attestation.String(), "list")
|
||||
bt, err := a.Get(ctx, key)
|
||||
if err == nil {
|
||||
if err := json.Unmarshal(bt, &versions); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if !errors.Is(err, storage.ErrDEKUnset) {
|
||||
return err
|
||||
}
|
||||
versions = append(versions, fname)
|
||||
versions = variant.RemoveDuplicate(versions)
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(versions)))
|
||||
json, err := json.Marshal(versions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return a.Put(ctx, key, json)
|
||||
}
|
||||
|
||||
// List returns the list of versions for the given attestation type.
|
||||
func (a AttestationVersionRepo) List(ctx context.Context, attestation variant.Variant) ([]string, error) {
|
||||
key := path.Join(AttestationPath, attestation.String(), "list")
|
||||
bt, err := a.Get(ctx, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var versions []string
|
||||
if err := json.Unmarshal(bt, &versions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return versions, nil
|
||||
}
|
||||
|
||||
// DeleteList empties the list of versions for the given attestation type.
|
||||
func (a AttestationVersionRepo) DeleteList(ctx context.Context, attestation variant.Variant) error {
|
||||
versions := []string{}
|
||||
bt, err := json.Marshal(&versions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return a.Put(ctx, path.Join(AttestationPath, attestation.String(), "list"), bt)
|
||||
}
|
||||
|
||||
func GetVersionByType(res versionsapi.AzureSEVSNPVersion, t Type) uint8 {
|
||||
switch t {
|
||||
case Bootloader:
|
||||
return res.Bootloader
|
||||
case TEE:
|
||||
return res.TEE
|
||||
case SNP:
|
||||
return res.SNP
|
||||
case Microcode:
|
||||
return res.Microcode
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
// GetAzureSEVSNPVersion returns the requested version of the given type.
|
||||
func GetAzureSEVSNPVersion(ctx context.Context) (res versionsapi.AzureSEVSNPVersion, err error) {
|
||||
var versions versionsapi.AzureSEVSNPVersionList
|
||||
fetcher := fetcher.NewFetcher()
|
||||
versions, err = fetcher.FetchAttestationList(ctx, versions)
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("failed fetching versions list: %w", err)
|
||||
}
|
||||
if len(versions) < 1 {
|
||||
return res, errors.New("no versions found in /list")
|
||||
}
|
||||
get := versionsapi.AzureSEVSNPVersionGet{Version: versions[0]} // get latest version (as sorted reversely alphanumerically)
|
||||
get, err = fetcher.FetchAttestationVersion(ctx, get)
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("failed fetching version: %w", err)
|
||||
}
|
||||
return get.AzureSEVSNPVersion, nil
|
||||
}
|
77
internal/attestationapi/attestationapi_test.go
Normal file
77
internal/attestationapi/attestationapi_test.go
Normal file
@ -0,0 +1,77 @@
|
||||
package attestationapi_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestationapi"
|
||||
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
|
||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
awsRegion = flag.String("aws-region", "us-east-1", "Region to use for AWS tests. Required for AWS KMS test.")
|
||||
awsAccessKeyID = flag.String("aws-access-key-id", "", "ID of the Access key to use for AWS tests. Required for AWS KMS and storage test.")
|
||||
awsAccessKey = flag.String("aws-access-key", "", "Access key to use for AWS tests. Required for AWS KMS and storage test.")
|
||||
awsBucket = flag.String("aws-bucket", "", "Name of the S3 bucket to use for AWS storage test. Required for AWS storage test.")
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
flag.Parse()
|
||||
if *awsAccessKey == "" || *awsAccessKeyID == "" || *awsBucket == "" || *awsRegion == "" {
|
||||
flag.Usage()
|
||||
panic("Required flags not set: --aws-access-key, --aws-access-key-id, --aws-bucket, --aws-region")
|
||||
}
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
var cfg = uri.AWSS3Config{
|
||||
Bucket: *awsBucket,
|
||||
AccessKeyID: *awsAccessKeyID,
|
||||
AccessKey: *awsAccessKey,
|
||||
Region: *awsRegion,
|
||||
}
|
||||
|
||||
func TestUploadAzureSEVSNPVersions(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
sut, err := attestationapi.NewAttestationVersionRepo(ctx, cfg)
|
||||
require.NoError(t, err)
|
||||
d := time.Date(2021, 1, 1, 1, 1, 1, 1, time.UTC)
|
||||
require.NoError(t, sut.UploadAzureSEVSNP(ctx, attestationapi.AzureSEVSNP, d))
|
||||
}
|
||||
|
||||
func TestListVersions(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
sut, err := attestationapi.NewAttestationVersionRepo(ctx, cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = sut.DeleteList(ctx, variant.AzureSEVSNP{})
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := sut.List(ctx, variant.AzureSEVSNP{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{}, res)
|
||||
|
||||
d := time.Date(2021, 1, 1, 1, 1, 1, 1, time.UTC)
|
||||
err = sut.UploadAzureSEVSNP(ctx, attestationapi.AzureSEVSNP, d)
|
||||
require.NoError(t, err)
|
||||
res, err = sut.List(ctx, variant.AzureSEVSNP{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{"2021-01-01-01-01.json"}, res)
|
||||
|
||||
err = sut.DeleteList(ctx, variant.AzureSEVSNP{})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestGetVersion(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
res, err := attestationapi.GetAzureSEVSNPVersion(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, uint8(2), res.Bootloader)
|
||||
}
|
@ -20,6 +20,7 @@ go_library(
|
||||
deps = [
|
||||
"//internal/attestation/idkeydigest",
|
||||
"//internal/attestation/measurements",
|
||||
"//internal/attestationapi",
|
||||
"//internal/cloud/cloudprovider",
|
||||
"//internal/compatibility",
|
||||
"//internal/config/imageversion",
|
||||
|
@ -23,6 +23,8 @@ import (
|
||||
var testCertPEM = `-----BEGIN CERTIFICATE-----\nMIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC\nBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS\nBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg\nQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp\nY2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy\nMTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS\nBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j\nZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG\n9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg\nW41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta\n1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2\nSzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0\n60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05\ngmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg\nbKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs\n+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi\nQi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ\neTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18\nfHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j\nWhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI\nrFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG\nKWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG\nSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI\nAWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel\nETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw\nSTjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK\ndHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq\nzT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp\nKGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e\npmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq\nHnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh\n3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn\nJZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH\nCViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4\nAFZEAwoKCQ==\n-----END CERTIFICATE-----\n`
|
||||
|
||||
func TestUnmarshalAttestationConfig(t *testing.T) {
|
||||
azureSEVSNP, err := DefaultForAzureSEVSNP()
|
||||
require.NoError(t, err)
|
||||
testCases := map[string]struct {
|
||||
cfg AttestationCfg
|
||||
}{
|
||||
@ -30,7 +32,7 @@ func TestUnmarshalAttestationConfig(t *testing.T) {
|
||||
cfg: &AWSNitroTPM{Measurements: measurements.DefaultsFor(cloudprovider.AWS, variant.AWSNitroTPM{})},
|
||||
},
|
||||
"AzureSEVSNP": {
|
||||
cfg: DefaultForAzureSEVSNP(),
|
||||
cfg: azureSEVSNP,
|
||||
},
|
||||
"AzureTrustedLaunch": {
|
||||
cfg: &AzureTrustedLaunch{Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureTrustedLaunch{})},
|
||||
|
@ -8,16 +8,19 @@ package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestationapi"
|
||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||
"github.com/edgelesssys/constellation/v2/internal/config/snpversion"
|
||||
"github.com/edgelesssys/constellation/v2/internal/config/version"
|
||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
||||
)
|
||||
|
||||
// AzureSEVSNP is the configuration for Azure SEV-SNP attestation.
|
||||
@ -47,20 +50,26 @@ type AzureSEVSNP struct {
|
||||
|
||||
// DefaultForAzureSEVSNP returns the default configuration for Azure SEV-SNP attestation.
|
||||
// Version numbers are hard coded and should be updated with each new release.
|
||||
func DefaultForAzureSEVSNP() *AzureSEVSNP {
|
||||
func DefaultForAzureSEVSNP() (*AzureSEVSNP, error) {
|
||||
ctx := context.Background()
|
||||
version, err := attestationapi.GetAzureSEVSNPVersion(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &AzureSEVSNP{
|
||||
Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureSEVSNP{}),
|
||||
BootloaderVersion: snpversion.GetLatest(snpversion.Bootloader),
|
||||
TEEVersion: snpversion.GetLatest(snpversion.TEE),
|
||||
SNPVersion: snpversion.GetLatest(snpversion.SNP),
|
||||
MicrocodeVersion: snpversion.GetLatest(snpversion.Microcode),
|
||||
BootloaderVersion: version.Bootloader,
|
||||
TEEVersion: version.TEE,
|
||||
SNPVersion: version.SNP,
|
||||
MicrocodeVersion: version.Microcode,
|
||||
FirmwareSignerConfig: SNPFirmwareSignerConfig{
|
||||
AcceptedKeyDigests: idkeydigest.DefaultList(),
|
||||
EnforcementPolicy: idkeydigest.MAAFallback,
|
||||
},
|
||||
// AMD root key. Received from the AMD Key Distribution System API (KDS).
|
||||
AMDRootKey: mustParsePEM(`-----BEGIN CERTIFICATE-----\nMIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC\nBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS\nBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg\nQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp\nY2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy\nMTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS\nBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j\nZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG\n9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg\nW41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta\n1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2\nSzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0\n60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05\ngmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg\nbKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs\n+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi\nQi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ\neTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18\nfHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j\nWhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI\nrFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG\nKWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG\nSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI\nAWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel\nETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw\nSTjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK\ndHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq\nzT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp\nKGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e\npmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq\nHnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh\n3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn\nJZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH\nCViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4\nAFZEAwoKCQ==\n-----END CERTIFICATE-----\n`),
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetVariant returns azure-sev-snp as the variant.
|
||||
@ -97,25 +106,49 @@ func (c AzureSEVSNP) EqualTo(old AttestationCfg) (bool, error) {
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements a custom unmarshaler to support setting "latest" as version.
|
||||
func (c *AzureSEVSNP) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
func (a *AzureSEVSNP) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
aux := &fusedAzureSEVSNP{
|
||||
auxAzureSEVSNP: (*auxAzureSEVSNP)(c),
|
||||
auxAzureSEVSNP: (*auxAzureSEVSNP)(a),
|
||||
}
|
||||
if err := unmarshal(aux); err != nil {
|
||||
return fmt.Errorf("unmarshal AzureSEVSNP: %w", err)
|
||||
}
|
||||
c = (*AzureSEVSNP)(aux.auxAzureSEVSNP)
|
||||
a = (*AzureSEVSNP)(aux.auxAzureSEVSNP)
|
||||
|
||||
for _, versionType := range []snpversion.Type{snpversion.Bootloader, snpversion.TEE, snpversion.SNP, snpversion.Microcode} {
|
||||
if !convertLatestToNumber(c, versionType, aux) {
|
||||
if err := convertStringToUint(c, versionType, aux); err != nil {
|
||||
return fmt.Errorf("convert %s version to number: %w", versionType, err)
|
||||
versions, err := attestationapi.GetAzureSEVSNPVersion(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get AzureSEVSNP versions: %w", err)
|
||||
}
|
||||
for _, versionType := range []attestationapi.Type{attestationapi.Bootloader, attestationapi.TEE, attestationapi.SNP, attestationapi.Microcode} {
|
||||
if !convertLatestToNumber(a, versions, versionType, aux) {
|
||||
if err := convertStringToUint(a, versionType, aux); err != nil {
|
||||
return fmt.Errorf("failed to convert %s version to number: %w", versionType, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getUintAndStringPtrToVersion(c *AzureSEVSNP, versionType attestationapi.Type, aux *fusedAzureSEVSNP) (*uint8, *string) {
|
||||
var v *uint8
|
||||
var stringV *string
|
||||
switch versionType {
|
||||
case attestationapi.Bootloader:
|
||||
v = &c.BootloaderVersion
|
||||
stringV = &aux.BootloaderVersion
|
||||
case attestationapi.TEE:
|
||||
v = &c.TEEVersion
|
||||
stringV = &aux.TEEVersion
|
||||
case attestationapi.SNP:
|
||||
v = &c.SNPVersion
|
||||
stringV = &aux.SNPVersion
|
||||
case attestationapi.Microcode:
|
||||
v = &c.MicrocodeVersion
|
||||
stringV = &aux.MicrocodeVersion
|
||||
}
|
||||
return v, stringV
|
||||
}
|
||||
|
||||
// AzureTrustedLaunch is the configuration for Azure Trusted Launch attestation.
|
||||
type AzureTrustedLaunch struct {
|
||||
// description: |
|
||||
@ -180,13 +213,13 @@ type fusedAzureSEVSNP struct {
|
||||
// Lowest acceptable bootloader version.
|
||||
BootloaderVersion string `yaml:"bootloaderVersion"`
|
||||
// description: |
|
||||
// Lowest acceptable bootloader version.
|
||||
// Lowest acceptable TEE version.
|
||||
TEEVersion string `yaml:"teeVersion"`
|
||||
// description: |
|
||||
// Lowest acceptable bootloader version.
|
||||
// Lowest acceptable SEV-SNP version.
|
||||
SNPVersion string `yaml:"snpVersion"`
|
||||
// description: |
|
||||
// Lowest acceptable bootloader version.
|
||||
// Lowest acceptable microcode version.
|
||||
MicrocodeVersion string `yaml:"microcodeVersion"`
|
||||
}
|
||||
|
||||
@ -201,29 +234,11 @@ func convertStringToUint(c *AzureSEVSNP, versionType snpversion.Type, aux *fused
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertLatestToNumber(c *AzureSEVSNP, versionType snpversion.Type, aux *fusedAzureSEVSNP) bool {
|
||||
func convertLatestToNumber(c *AzureSEVSNP, versions versionsapi.AzureSEVSNPVersion, versionType version.Type, aux *fusedAzureSEVSNP) bool {
|
||||
v, stringV := getUintAndStringPtrToVersion(c, versionType, aux)
|
||||
if strings.ToLower(*stringV) == "latest" {
|
||||
*v = snpversion.GetLatest(versionType)
|
||||
*v = attestationapi.GetVersionByType(versions, versionType)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getUintAndStringPtrToVersion(c *AzureSEVSNP, versionType version.Type, aux *fusedAzureSEVSNP) (versionUint *uint8, versionString *string) {
|
||||
switch versionType {
|
||||
case version.Bootloader:
|
||||
versionUint = &c.BootloaderVersion
|
||||
versionString = &aux.BootloaderVersion
|
||||
case version.TEE:
|
||||
versionUint = &c.TEEVersion
|
||||
versionString = &aux.TEEVersion
|
||||
case version.SNP:
|
||||
versionUint = &c.SNPVersion
|
||||
versionString = &aux.SNPVersion
|
||||
case version.Microcode:
|
||||
versionUint = &c.MicrocodeVersion
|
||||
versionString = &aux.MicrocodeVersion
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -297,7 +297,11 @@ type AttestationConfig struct {
|
||||
}
|
||||
|
||||
// Default returns a struct with the default config.
|
||||
func Default() *Config {
|
||||
func Default() (*Config, error) {
|
||||
azureSEVSNP, err := DefaultForAzureSEVSNP()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Config{
|
||||
Version: Version3,
|
||||
Image: defaultImage,
|
||||
@ -357,12 +361,21 @@ func Default() *Config {
|
||||
// AWS will have aws-sev-snp as attestation variant
|
||||
Attestation: AttestationConfig{
|
||||
AWSNitroTPM: &AWSNitroTPM{Measurements: measurements.DefaultsFor(cloudprovider.AWS, variant.AWSNitroTPM{})},
|
||||
AzureSEVSNP: DefaultForAzureSEVSNP(),
|
||||
AzureSEVSNP: azureSEVSNP,
|
||||
AzureTrustedLaunch: &AzureTrustedLaunch{Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureTrustedLaunch{})},
|
||||
GCPSEVES: &GCPSEVES{Measurements: measurements.DefaultsFor(cloudprovider.GCP, variant.GCPSEVES{})},
|
||||
QEMUVTPM: &QEMUVTPM{Measurements: measurements.DefaultsFor(cloudprovider.QEMU, variant.QEMUVTPM{})},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DefaultWithPanic returns a struct with the default config.
|
||||
func DefaultWithPanic() *Config {
|
||||
conf, err := Default()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return conf
|
||||
}
|
||||
|
||||
// fromFile returns config file with `name` read from `fileHandler` by parsing
|
||||
@ -404,7 +417,11 @@ func New(fileHandler file.Handler, name string, force bool) (*Config, error) {
|
||||
// Backwards compatibility: configs without the field `microserviceVersion` are valid in version 2.6.
|
||||
// In case the field is not set in an old config we prefill it with the default value.
|
||||
if c.MicroserviceVersion == "" {
|
||||
c.MicroserviceVersion = Default().MicroserviceVersion
|
||||
azureSEVSNP, err := Default()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.MicroserviceVersion = azureSEVSNP.MicroserviceVersion
|
||||
}
|
||||
|
||||
return c, c.Validate(force)
|
||||
|
@ -33,7 +33,7 @@ func TestMain(m *testing.M) {
|
||||
|
||||
func TestDefaultConfig(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
def := Default()
|
||||
def := DefaultWithPanic()
|
||||
assert.NotNil(def)
|
||||
}
|
||||
|
||||
@ -46,11 +46,11 @@ func TestSettingLatestAsVersion(t *testing.T) {
|
||||
}{
|
||||
"mix of latest and uint as version value": {
|
||||
config: func() map[string]interface{} {
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
// modify versions as string
|
||||
m := getConfigAsMap(conf, t)
|
||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["microcodeVersion"] = "latest"
|
||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["teeVersion"] = "latest"
|
||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["teeVersion"] = "Latest"
|
||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["snpVersion"] = "latest"
|
||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["bootloaderVersion"] = 1
|
||||
return m
|
||||
@ -58,14 +58,15 @@ func TestSettingLatestAsVersion(t *testing.T) {
|
||||
|
||||
configName: constants.ConfigFilename,
|
||||
wantResult: func() *Config {
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.Attestation.AzureSEVSNP.BootloaderVersion = 1
|
||||
conf.Attestation.AzureSEVSNP.MicrocodeVersion = 93
|
||||
return conf
|
||||
}(),
|
||||
},
|
||||
"refuse invalid version value": {
|
||||
config: func() map[string]interface{} {
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
m := getConfigAsMap(conf, t)
|
||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["microcodeVersion"] = "1a"
|
||||
return m
|
||||
@ -115,14 +116,14 @@ func TestFromFile(t *testing.T) {
|
||||
wantErr bool
|
||||
}{
|
||||
"default config from default file": {
|
||||
config: Default(),
|
||||
config: DefaultWithPanic(),
|
||||
configName: constants.ConfigFilename,
|
||||
wantResult: Default(),
|
||||
wantResult: DefaultWithPanic(),
|
||||
},
|
||||
"default config from different path": {
|
||||
config: Default(),
|
||||
config: DefaultWithPanic(),
|
||||
configName: "other-config.yaml",
|
||||
wantResult: Default(),
|
||||
wantResult: DefaultWithPanic(),
|
||||
},
|
||||
"default config when path empty": {
|
||||
config: nil,
|
||||
@ -145,14 +146,14 @@ func TestFromFile(t *testing.T) {
|
||||
},
|
||||
"modify default config": {
|
||||
config: func() *Config {
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.Provider.GCP.Region = "eu-north1"
|
||||
conf.Provider.GCP.Zone = "eu-north1-a"
|
||||
return conf
|
||||
}(),
|
||||
configName: constants.ConfigFilename,
|
||||
wantResult: func() *Config {
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.Provider.GCP.Region = "eu-north1"
|
||||
conf.Provider.GCP.Zone = "eu-north1-a"
|
||||
return conf
|
||||
@ -191,7 +192,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
|
||||
}{
|
||||
"set env works": {
|
||||
confToWrite: func() *Config { // valid config with all, but clientSecretValue
|
||||
c := Default()
|
||||
c := DefaultWithPanic()
|
||||
c.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
c.Image = "v" + constants.VersionInfo()
|
||||
c.Provider.Azure.SubscriptionID = "f4278079-288c-4766-a98c-ab9d5dba01a5"
|
||||
@ -212,7 +213,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
|
||||
},
|
||||
"set env overwrites": {
|
||||
confToWrite: func() *Config {
|
||||
c := Default()
|
||||
c := DefaultWithPanic()
|
||||
c.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
c.Image = "v" + constants.VersionInfo()
|
||||
c.Provider.Azure.SubscriptionID = "f4278079-288c-4766-a98c-ab9d5dba01a5"
|
||||
@ -276,13 +277,13 @@ func TestValidate(t *testing.T) {
|
||||
wantErrCount int
|
||||
}{
|
||||
"default config is not valid": {
|
||||
cnf: Default(),
|
||||
cnf: DefaultWithPanic(),
|
||||
wantErr: true,
|
||||
wantErrCount: defaultErrCount,
|
||||
},
|
||||
"v0 is one error": {
|
||||
cnf: func() *Config {
|
||||
cnf := Default()
|
||||
cnf := DefaultWithPanic()
|
||||
cnf.Version = "v0"
|
||||
return cnf
|
||||
}(),
|
||||
@ -291,7 +292,7 @@ func TestValidate(t *testing.T) {
|
||||
},
|
||||
"v0 and negative state disk are two errors": {
|
||||
cnf: func() *Config {
|
||||
cnf := Default()
|
||||
cnf := DefaultWithPanic()
|
||||
cnf.Version = "v0"
|
||||
cnf.StateDiskSizeGB = -1
|
||||
return cnf
|
||||
@ -301,7 +302,7 @@ func TestValidate(t *testing.T) {
|
||||
},
|
||||
"default Azure config is not valid": {
|
||||
cnf: func() *Config {
|
||||
cnf := Default()
|
||||
cnf := DefaultWithPanic()
|
||||
cnf.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
return cnf
|
||||
}(),
|
||||
@ -310,7 +311,7 @@ func TestValidate(t *testing.T) {
|
||||
},
|
||||
"Azure config with all required fields is valid": {
|
||||
cnf: func() *Config {
|
||||
cnf := Default()
|
||||
cnf := DefaultWithPanic()
|
||||
cnf.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
cnf.Image = "v" + constants.VersionInfo()
|
||||
az := cnf.Provider.Azure
|
||||
@ -331,7 +332,7 @@ func TestValidate(t *testing.T) {
|
||||
},
|
||||
"default GCP config is not valid": {
|
||||
cnf: func() *Config {
|
||||
cnf := Default()
|
||||
cnf := DefaultWithPanic()
|
||||
cnf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
||||
return cnf
|
||||
}(),
|
||||
@ -340,7 +341,7 @@ func TestValidate(t *testing.T) {
|
||||
},
|
||||
"GCP config with all required fields is valid": {
|
||||
cnf: func() *Config {
|
||||
cnf := Default()
|
||||
cnf := DefaultWithPanic()
|
||||
cnf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
||||
cnf.Image = "v" + constants.VersionInfo()
|
||||
gcp := cnf.Provider.GCP
|
||||
@ -359,7 +360,7 @@ func TestValidate(t *testing.T) {
|
||||
// TODO: v2.7: remove this test as it should start breaking after v2.6 is released.
|
||||
"k8s vMAJOR.MINOR is valid in v2.7": {
|
||||
cnf: func() *Config {
|
||||
cnf := Default()
|
||||
cnf := DefaultWithPanic()
|
||||
cnf.KubernetesVersion = "v1.25"
|
||||
return cnf
|
||||
}(),
|
||||
@ -369,7 +370,7 @@ func TestValidate(t *testing.T) {
|
||||
// TODO: v2.7: remove this test as it should start breaking after v2.6 is released.
|
||||
"k8s MAJOR.MINOR is valid in v2.7": {
|
||||
cnf: func() *Config {
|
||||
cnf := Default()
|
||||
cnf := DefaultWithPanic()
|
||||
cnf.KubernetesVersion = "1.25"
|
||||
return cnf
|
||||
}(),
|
||||
@ -403,9 +404,9 @@ func TestHasProvider(t *testing.T) {
|
||||
assert.False((&Config{}).HasProvider(cloudprovider.Azure))
|
||||
assert.False((&Config{}).HasProvider(cloudprovider.GCP))
|
||||
assert.False((&Config{}).HasProvider(cloudprovider.QEMU))
|
||||
assert.False(Default().HasProvider(cloudprovider.Unknown))
|
||||
assert.True(Default().HasProvider(cloudprovider.Azure))
|
||||
assert.True(Default().HasProvider(cloudprovider.GCP))
|
||||
assert.False(DefaultWithPanic().HasProvider(cloudprovider.Unknown))
|
||||
assert.True(DefaultWithPanic().HasProvider(cloudprovider.Azure))
|
||||
assert.True(DefaultWithPanic().HasProvider(cloudprovider.GCP))
|
||||
cnfWithAzure := Config{Provider: ProviderConfig{Azure: &AzureConfig{}}}
|
||||
assert.False(cnfWithAzure.HasProvider(cloudprovider.Unknown))
|
||||
assert.True(cnfWithAzure.HasProvider(cloudprovider.Azure))
|
||||
@ -422,26 +423,26 @@ func TestConfigRemoveProviderExcept(t *testing.T) {
|
||||
}{
|
||||
"except aws": {
|
||||
removeExcept: cloudprovider.AWS,
|
||||
wantAWS: Default().Provider.AWS,
|
||||
wantAWS: DefaultWithPanic().Provider.AWS,
|
||||
},
|
||||
"except azure": {
|
||||
removeExcept: cloudprovider.Azure,
|
||||
wantAzure: Default().Provider.Azure,
|
||||
wantAzure: DefaultWithPanic().Provider.Azure,
|
||||
},
|
||||
"except gcp": {
|
||||
removeExcept: cloudprovider.GCP,
|
||||
wantGCP: Default().Provider.GCP,
|
||||
wantGCP: DefaultWithPanic().Provider.GCP,
|
||||
},
|
||||
"except qemu": {
|
||||
removeExcept: cloudprovider.QEMU,
|
||||
wantQEMU: Default().Provider.QEMU,
|
||||
wantQEMU: DefaultWithPanic().Provider.QEMU,
|
||||
},
|
||||
"unknown provider": {
|
||||
removeExcept: cloudprovider.Unknown,
|
||||
wantAWS: Default().Provider.AWS,
|
||||
wantAzure: Default().Provider.Azure,
|
||||
wantGCP: Default().Provider.GCP,
|
||||
wantQEMU: Default().Provider.QEMU,
|
||||
wantAWS: DefaultWithPanic().Provider.AWS,
|
||||
wantAzure: DefaultWithPanic().Provider.Azure,
|
||||
wantGCP: DefaultWithPanic().Provider.GCP,
|
||||
wantQEMU: DefaultWithPanic().Provider.QEMU,
|
||||
},
|
||||
}
|
||||
|
||||
@ -449,7 +450,7 @@ func TestConfigRemoveProviderExcept(t *testing.T) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.RemoveProviderAndAttestationExcept(tc.removeExcept)
|
||||
|
||||
assert.Equal(tc.wantAWS, conf.Provider.AWS)
|
||||
@ -481,7 +482,7 @@ func TestConfig_UpdateMeasurements(t *testing.T) {
|
||||
}
|
||||
|
||||
{ // AWS
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.RemoveProviderAndAttestationExcept(cloudprovider.AWS)
|
||||
for k := range conf.Attestation.AWSNitroTPM.Measurements {
|
||||
delete(conf.Attestation.AWSNitroTPM.Measurements, k)
|
||||
@ -490,7 +491,7 @@ func TestConfig_UpdateMeasurements(t *testing.T) {
|
||||
assert.Equal(newMeasurements, conf.Attestation.AWSNitroTPM.Measurements)
|
||||
}
|
||||
{ // Azure
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
for k := range conf.Attestation.AzureSEVSNP.Measurements {
|
||||
delete(conf.Attestation.AzureSEVSNP.Measurements, k)
|
||||
@ -499,7 +500,7 @@ func TestConfig_UpdateMeasurements(t *testing.T) {
|
||||
assert.Equal(newMeasurements, conf.Attestation.AzureSEVSNP.Measurements)
|
||||
}
|
||||
{ // GCP
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
||||
for k := range conf.Attestation.GCPSEVES.Measurements {
|
||||
delete(conf.Attestation.GCPSEVES.Measurements, k)
|
||||
@ -508,7 +509,7 @@ func TestConfig_UpdateMeasurements(t *testing.T) {
|
||||
assert.Equal(newMeasurements, conf.Attestation.GCPSEVES.Measurements)
|
||||
}
|
||||
{ // QEMU
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.RemoveProviderAndAttestationExcept(cloudprovider.QEMU)
|
||||
for k := range conf.Attestation.QEMUVTPM.Measurements {
|
||||
delete(conf.Attestation.QEMUVTPM.Measurements, k)
|
||||
@ -525,7 +526,7 @@ func TestConfig_IsReleaseImage(t *testing.T) {
|
||||
}{
|
||||
"release image v0.0.0": {
|
||||
conf: func() *Config {
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.Image = "v0.0.0"
|
||||
return conf
|
||||
}(),
|
||||
@ -533,7 +534,7 @@ func TestConfig_IsReleaseImage(t *testing.T) {
|
||||
},
|
||||
"branch image": {
|
||||
conf: func() *Config {
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.Image = "feat-x-vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef"
|
||||
return conf
|
||||
}(),
|
||||
@ -541,7 +542,7 @@ func TestConfig_IsReleaseImage(t *testing.T) {
|
||||
},
|
||||
"debug image": {
|
||||
conf: func() *Config {
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.Image = "debug-vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef"
|
||||
return conf
|
||||
}(),
|
||||
@ -687,11 +688,11 @@ func TestIsDebugCluster(t *testing.T) {
|
||||
expectedResult: false,
|
||||
},
|
||||
"default config": {
|
||||
config: Default(),
|
||||
config: DefaultWithPanic(),
|
||||
expectedResult: false,
|
||||
},
|
||||
"enabled": {
|
||||
config: Default(),
|
||||
config: DefaultWithPanic(),
|
||||
prepareConfig: func(conf *Config) {
|
||||
*conf.DebugCluster = true
|
||||
},
|
||||
@ -754,7 +755,7 @@ func TestValidateProvider(t *testing.T) {
|
||||
v := validator.New()
|
||||
trans := ut.New(en.New()).GetFallback()
|
||||
|
||||
conf := Default()
|
||||
conf := DefaultWithPanic()
|
||||
conf.Provider = tc.provider
|
||||
|
||||
v.RegisterStructValidation(validateProvider, ProviderConfig{})
|
||||
|
@ -242,7 +242,11 @@ func V2ToV3(path string, fileHandler file.Handler) error {
|
||||
Measurements: cfgV2.Provider.Azure.Measurements,
|
||||
}
|
||||
} else {
|
||||
cfgV3.Attestation.AzureSEVSNP = config.DefaultForAzureSEVSNP()
|
||||
azureSEVSNP, err := config.DefaultForAzureSEVSNP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfgV3.Attestation.AzureSEVSNP = azureSEVSNP
|
||||
cfgV3.Attestation.AzureSEVSNP.Measurements = cfgV2.Provider.Azure.Measurements
|
||||
cfgV3.Attestation.AzureSEVSNP.FirmwareSignerConfig = config.SNPFirmwareSignerConfig{
|
||||
AcceptedKeyDigests: cfgV2.Provider.Azure.IDKeyDigest,
|
||||
|
@ -1,8 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "version",
|
||||
srcs = ["version.go"],
|
||||
importpath = "github.com/edgelesssys/constellation/v2/internal/config/version",
|
||||
visibility = ["//:__subpackages__"],
|
||||
)
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package version
|
||||
|
||||
const (
|
||||
Bootloader Type = "bootloader" // Bootloader is the version of the Azure SEVSNP bootloader.
|
||||
TEE Type = "tee" // TEE is the version of the Azure SEVSNP TEE.
|
||||
SNP Type = "snp" // SNP is the version of the Azure SEVSNP SNP.
|
||||
Microcode Type = "microcode" // Microcode is the version of the Azure SEVSNP microcode.
|
||||
)
|
||||
|
||||
// Type is the type of the version to be requested.
|
||||
type Type (string)
|
||||
|
||||
// GetVersion returns the version of the given type.
|
||||
func GetVersion(t Type) uint8 {
|
||||
switch t {
|
||||
case Bootloader:
|
||||
return 2
|
||||
case TEE:
|
||||
return 0
|
||||
case SNP:
|
||||
return 6
|
||||
case Microcode:
|
||||
return 93
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
}
|
@ -82,7 +82,7 @@ func GetAvailableAttestationTypes() []Variant {
|
||||
for _, k := range keys {
|
||||
res = append(res, providerAttestationMapping[k]...)
|
||||
}
|
||||
return removeDuplicate(res)
|
||||
return RemoveDuplicate(res)
|
||||
}
|
||||
|
||||
// Getter returns an ASN.1 Object Identifier.
|
||||
@ -259,9 +259,10 @@ func (QEMUTDX) Equal(other Getter) bool {
|
||||
return other.OID().Equal(QEMUTDX{}.OID())
|
||||
}
|
||||
|
||||
func removeDuplicate(sliceList []Variant) []Variant {
|
||||
allKeys := make(map[Variant]bool)
|
||||
list := []Variant{}
|
||||
// RemoveDuplicate removes duplicate elements from a slice.
|
||||
func RemoveDuplicate[T comparable](sliceList []T) []T {
|
||||
allKeys := make(map[T]bool)
|
||||
list := []T{}
|
||||
for _, item := range sliceList {
|
||||
if _, value := allKeys[item]; !value {
|
||||
allKeys[item] = true
|
||||
|
@ -4,6 +4,7 @@ load("//bazel/go:go_test.bzl", "go_test")
|
||||
go_library(
|
||||
name = "versionsapi",
|
||||
srcs = [
|
||||
"attestation.go",
|
||||
"cliinfo.go",
|
||||
"imageinfo.go",
|
||||
"latest.go",
|
||||
@ -16,6 +17,7 @@ go_library(
|
||||
deps = [
|
||||
"//internal/cloud/cloudprovider",
|
||||
"//internal/constants",
|
||||
"//internal/variant",
|
||||
"@org_golang_x_mod//semver",
|
||||
],
|
||||
)
|
||||
|
74
internal/versionsapi/attestation.go
Normal file
74
internal/versionsapi/attestation.go
Normal file
@ -0,0 +1,74 @@
|
||||
package versionsapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||
)
|
||||
|
||||
// AttestationPath is the path to the attestation versions.
|
||||
const AttestationPath = "constellation/v1/attestation" // TODO already in attestationonapi but import cycle otherwise
|
||||
|
||||
// AzureSEVSNPVersion tracks the latest version of each component of the Azure SEVSNP.
|
||||
type AzureSEVSNPVersion struct {
|
||||
// Bootloader is the latest version of the Azure SEVSNP bootloader.
|
||||
Bootloader uint8 `json:"bootloader"`
|
||||
// TEE is the latest version of the Azure SEVSNP TEE.
|
||||
TEE uint8 `json:"tee"`
|
||||
// SNP is the latest version of the Azure SEVSNP SNP.
|
||||
SNP uint8 `json:"snp"`
|
||||
// Microcode is the latest version of the Azure SEVSNP microcode.
|
||||
Microcode uint8 `json:"microcode"`
|
||||
}
|
||||
|
||||
type AzureSEVSNPVersionGet struct {
|
||||
Version string `json:"-"`
|
||||
AzureSEVSNPVersion
|
||||
}
|
||||
|
||||
func (i AzureSEVSNPVersionGet) URL() (string, error) {
|
||||
url, err := url.Parse(constants.CDNRepositoryURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("parsing CDN URL: %w", err)
|
||||
}
|
||||
url.Path = i.JSONPath()
|
||||
return url.String(), nil
|
||||
}
|
||||
|
||||
func (i AzureSEVSNPVersionGet) JSONPath() string {
|
||||
return path.Join(AttestationPath, variant.AzureSEVSNP{}.String(), i.Version)
|
||||
}
|
||||
|
||||
func (i AzureSEVSNPVersionGet) ValidateRequest() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i AzureSEVSNPVersionGet) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type AzureSEVSNPVersionList ([]string)
|
||||
|
||||
func (i AzureSEVSNPVersionList) URL() (string, error) {
|
||||
url, err := url.Parse(constants.CDNRepositoryURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("parsing CDN URL: %w", err)
|
||||
}
|
||||
url.Path = i.JSONPath()
|
||||
return url.String(), nil
|
||||
}
|
||||
|
||||
func (i AzureSEVSNPVersionList) JSONPath() string {
|
||||
return path.Join(AttestationPath, variant.AzureSEVSNP{}.String(), "list")
|
||||
}
|
||||
|
||||
func (i AzureSEVSNPVersionList) ValidateRequest() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i AzureSEVSNPVersionList) Validate() error {
|
||||
return nil
|
||||
}
|
@ -54,6 +54,14 @@ func (f *Fetcher) FetchCLIInfo(ctx context.Context, cliInfo versionsapi.CLIInfo)
|
||||
return fetch(ctx, f.httpc, cliInfo)
|
||||
}
|
||||
|
||||
func (f *Fetcher) FetchAttestationList(ctx context.Context, attestation versionsapi.AzureSEVSNPVersionList) (versionsapi.AzureSEVSNPVersionList, error) {
|
||||
return fetch(ctx, f.httpc, attestation)
|
||||
}
|
||||
|
||||
func (f *Fetcher) FetchAttestationVersion(ctx context.Context, attestation versionsapi.AzureSEVSNPVersionGet) (versionsapi.AzureSEVSNPVersionGet, error) {
|
||||
return fetch(ctx, f.httpc, attestation)
|
||||
}
|
||||
|
||||
type apiObject interface {
|
||||
ValidateRequest() error
|
||||
Validate() error
|
||||
|
@ -38,6 +38,8 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
|
||||
func TestNewUpdateableValidator(t *testing.T) {
|
||||
azureSEVSNP, err := config.DefaultForAzureSEVSNP()
|
||||
require.NoError(t, err)
|
||||
testCases := map[string]struct {
|
||||
variant variant.Variant
|
||||
config config.AttestationCfg
|
||||
@ -45,7 +47,7 @@ func TestNewUpdateableValidator(t *testing.T) {
|
||||
}{
|
||||
"azure": {
|
||||
variant: variant.AzureSEVSNP{},
|
||||
config: config.DefaultForAzureSEVSNP(),
|
||||
config: azureSEVSNP,
|
||||
},
|
||||
"gcp": {
|
||||
variant: variant.GCPSEVES{},
|
||||
|
Loading…
x
Reference in New Issue
Block a user