mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-06-10 15:42:44 -04:00
s3 draft working
fix tests with DefaultWithPanic()
This commit is contained in:
parent
934722ae76
commit
0f942bafca
33 changed files with 548 additions and 194 deletions
|
@ -41,18 +41,18 @@ func TestCreator(t *testing.T) {
|
||||||
"gcp": {
|
"gcp": {
|
||||||
tfClient: &stubTerraformClient{ip: ip},
|
tfClient: &stubTerraformClient{ip: ip},
|
||||||
provider: cloudprovider.GCP,
|
provider: cloudprovider.GCP,
|
||||||
config: config.Default(),
|
config: config.DefaultWithPanic(),
|
||||||
},
|
},
|
||||||
"gcp newTerraformClient error": {
|
"gcp newTerraformClient error": {
|
||||||
newTfClientErr: someErr,
|
newTfClientErr: someErr,
|
||||||
provider: cloudprovider.GCP,
|
provider: cloudprovider.GCP,
|
||||||
config: config.Default(),
|
config: config.DefaultWithPanic(),
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"gcp create cluster error": {
|
"gcp create cluster error": {
|
||||||
tfClient: &stubTerraformClient{createClusterErr: someErr},
|
tfClient: &stubTerraformClient{createClusterErr: someErr},
|
||||||
provider: cloudprovider.GCP,
|
provider: cloudprovider.GCP,
|
||||||
config: config.Default(),
|
config: config.DefaultWithPanic(),
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantRollback: true,
|
wantRollback: true,
|
||||||
wantTerraformRollback: true,
|
wantTerraformRollback: true,
|
||||||
|
@ -61,7 +61,7 @@ func TestCreator(t *testing.T) {
|
||||||
tfClient: &stubTerraformClient{ip: ip},
|
tfClient: &stubTerraformClient{ip: ip},
|
||||||
provider: cloudprovider.Azure,
|
provider: cloudprovider.Azure,
|
||||||
config: func() *config.Config {
|
config: func() *config.Config {
|
||||||
cfg := config.Default()
|
cfg := config.DefaultWithPanic()
|
||||||
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||||
return cfg
|
return cfg
|
||||||
}(),
|
}(),
|
||||||
|
@ -71,7 +71,7 @@ func TestCreator(t *testing.T) {
|
||||||
tfClient: &stubTerraformClient{ip: ip},
|
tfClient: &stubTerraformClient{ip: ip},
|
||||||
provider: cloudprovider.Azure,
|
provider: cloudprovider.Azure,
|
||||||
config: func() *config.Config {
|
config: func() *config.Config {
|
||||||
cfg := config.Default()
|
cfg := config.DefaultWithPanic()
|
||||||
cfg.Attestation = config.AttestationConfig{
|
cfg.Attestation = config.AttestationConfig{
|
||||||
AzureTrustedLaunch: &config.AzureTrustedLaunch{},
|
AzureTrustedLaunch: &config.AzureTrustedLaunch{},
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ func TestCreator(t *testing.T) {
|
||||||
tfClient: &stubTerraformClient{ip: ip},
|
tfClient: &stubTerraformClient{ip: ip},
|
||||||
provider: cloudprovider.Azure,
|
provider: cloudprovider.Azure,
|
||||||
config: func() *config.Config {
|
config: func() *config.Config {
|
||||||
cfg := config.Default()
|
cfg := config.DefaultWithPanic()
|
||||||
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||||
return cfg
|
return cfg
|
||||||
}(),
|
}(),
|
||||||
|
@ -94,7 +94,7 @@ func TestCreator(t *testing.T) {
|
||||||
newTfClientErr: someErr,
|
newTfClientErr: someErr,
|
||||||
provider: cloudprovider.Azure,
|
provider: cloudprovider.Azure,
|
||||||
config: func() *config.Config {
|
config: func() *config.Config {
|
||||||
cfg := config.Default()
|
cfg := config.DefaultWithPanic()
|
||||||
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||||
return cfg
|
return cfg
|
||||||
}(),
|
}(),
|
||||||
|
@ -105,7 +105,7 @@ func TestCreator(t *testing.T) {
|
||||||
tfClient: &stubTerraformClient{createClusterErr: someErr},
|
tfClient: &stubTerraformClient{createClusterErr: someErr},
|
||||||
provider: cloudprovider.Azure,
|
provider: cloudprovider.Azure,
|
||||||
config: func() *config.Config {
|
config: func() *config.Config {
|
||||||
cfg := config.Default()
|
cfg := config.DefaultWithPanic()
|
||||||
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
cfg.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||||
return cfg
|
return cfg
|
||||||
}(),
|
}(),
|
||||||
|
@ -119,7 +119,7 @@ func TestCreator(t *testing.T) {
|
||||||
libvirt: &stubLibvirtRunner{},
|
libvirt: &stubLibvirtRunner{},
|
||||||
provider: cloudprovider.OpenStack,
|
provider: cloudprovider.OpenStack,
|
||||||
config: func() *config.Config {
|
config: func() *config.Config {
|
||||||
cfg := config.Default()
|
cfg := config.DefaultWithPanic()
|
||||||
cfg.Provider.OpenStack.Cloud = "testcloud"
|
cfg.Provider.OpenStack.Cloud = "testcloud"
|
||||||
return cfg
|
return cfg
|
||||||
}(),
|
}(),
|
||||||
|
@ -128,7 +128,7 @@ func TestCreator(t *testing.T) {
|
||||||
tfClient: &stubTerraformClient{ip: ip},
|
tfClient: &stubTerraformClient{ip: ip},
|
||||||
libvirt: &stubLibvirtRunner{},
|
libvirt: &stubLibvirtRunner{},
|
||||||
provider: cloudprovider.OpenStack,
|
provider: cloudprovider.OpenStack,
|
||||||
config: config.Default(),
|
config: config.DefaultWithPanic(),
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"openstack newTerraformClient error": {
|
"openstack newTerraformClient error": {
|
||||||
|
@ -136,7 +136,7 @@ func TestCreator(t *testing.T) {
|
||||||
libvirt: &stubLibvirtRunner{},
|
libvirt: &stubLibvirtRunner{},
|
||||||
provider: cloudprovider.OpenStack,
|
provider: cloudprovider.OpenStack,
|
||||||
config: func() *config.Config {
|
config: func() *config.Config {
|
||||||
cfg := config.Default()
|
cfg := config.DefaultWithPanic()
|
||||||
cfg.Provider.OpenStack.Cloud = "testcloud"
|
cfg.Provider.OpenStack.Cloud = "testcloud"
|
||||||
return cfg
|
return cfg
|
||||||
}(),
|
}(),
|
||||||
|
@ -147,7 +147,7 @@ func TestCreator(t *testing.T) {
|
||||||
libvirt: &stubLibvirtRunner{},
|
libvirt: &stubLibvirtRunner{},
|
||||||
provider: cloudprovider.OpenStack,
|
provider: cloudprovider.OpenStack,
|
||||||
config: func() *config.Config {
|
config: func() *config.Config {
|
||||||
cfg := config.Default()
|
cfg := config.DefaultWithPanic()
|
||||||
cfg.Provider.OpenStack.Cloud = "testcloud"
|
cfg.Provider.OpenStack.Cloud = "testcloud"
|
||||||
return cfg
|
return cfg
|
||||||
}(),
|
}(),
|
||||||
|
@ -159,21 +159,21 @@ func TestCreator(t *testing.T) {
|
||||||
tfClient: &stubTerraformClient{ip: ip},
|
tfClient: &stubTerraformClient{ip: ip},
|
||||||
libvirt: &stubLibvirtRunner{},
|
libvirt: &stubLibvirtRunner{},
|
||||||
provider: cloudprovider.QEMU,
|
provider: cloudprovider.QEMU,
|
||||||
config: config.Default(),
|
config: config.DefaultWithPanic(),
|
||||||
wantErr: failOnNonAMD64,
|
wantErr: failOnNonAMD64,
|
||||||
},
|
},
|
||||||
"qemu newTerraformClient error": {
|
"qemu newTerraformClient error": {
|
||||||
newTfClientErr: someErr,
|
newTfClientErr: someErr,
|
||||||
libvirt: &stubLibvirtRunner{},
|
libvirt: &stubLibvirtRunner{},
|
||||||
provider: cloudprovider.QEMU,
|
provider: cloudprovider.QEMU,
|
||||||
config: config.Default(),
|
config: config.DefaultWithPanic(),
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"qemu create cluster error": {
|
"qemu create cluster error": {
|
||||||
tfClient: &stubTerraformClient{createClusterErr: someErr},
|
tfClient: &stubTerraformClient{createClusterErr: someErr},
|
||||||
libvirt: &stubLibvirtRunner{},
|
libvirt: &stubLibvirtRunner{},
|
||||||
provider: cloudprovider.QEMU,
|
provider: cloudprovider.QEMU,
|
||||||
config: config.Default(),
|
config: config.DefaultWithPanic(),
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantRollback: !failOnNonAMD64, // if we run on non-AMD64/linux, we don't get to a point where rollback is needed
|
wantRollback: !failOnNonAMD64, // if we run on non-AMD64/linux, we don't get to a point where rollback is needed
|
||||||
wantTerraformRollback: true,
|
wantTerraformRollback: true,
|
||||||
|
@ -182,14 +182,14 @@ func TestCreator(t *testing.T) {
|
||||||
tfClient: &stubTerraformClient{ip: ip},
|
tfClient: &stubTerraformClient{ip: ip},
|
||||||
libvirt: &stubLibvirtRunner{startErr: someErr},
|
libvirt: &stubLibvirtRunner{startErr: someErr},
|
||||||
provider: cloudprovider.QEMU,
|
provider: cloudprovider.QEMU,
|
||||||
config: config.Default(),
|
config: config.DefaultWithPanic(),
|
||||||
wantRollback: !failOnNonAMD64,
|
wantRollback: !failOnNonAMD64,
|
||||||
wantTerraformRollback: false,
|
wantTerraformRollback: false,
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"unknown provider": {
|
"unknown provider": {
|
||||||
provider: cloudprovider.Unknown,
|
provider: cloudprovider.Unknown,
|
||||||
config: config.Default(),
|
config: config.DefaultWithPanic(),
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,7 +250,7 @@ func TestConfigFetchMeasurements(t *testing.T) {
|
||||||
cmd.Flags().Bool("force", true, "") // register persistent flag manually
|
cmd.Flags().Bool("force", true, "") // register persistent flag manually
|
||||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
||||||
|
|
||||||
gcpConfig := defaultConfigWithExpectedMeasurements(t, config.Default(), cloudprovider.GCP)
|
gcpConfig := defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), cloudprovider.GCP)
|
||||||
gcpConfig.Image = "v999.999.999"
|
gcpConfig.Image = "v999.999.999"
|
||||||
|
|
||||||
err := fileHandler.WriteYAML(constants.ConfigFilename, gcpConfig, file.OptMkdirAll)
|
err := fileHandler.WriteYAML(constants.ConfigFilename, gcpConfig, file.OptMkdirAll)
|
||||||
|
|
|
@ -36,7 +36,7 @@ func newConfigGenerateCmd() *cobra.Command {
|
||||||
RunE: runConfigGenerate,
|
RunE: runConfigGenerate,
|
||||||
}
|
}
|
||||||
cmd.Flags().StringP("file", "f", constants.ConfigFilename, "path to output file, or '-' for stdout")
|
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())))
|
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
|
return cmd
|
||||||
|
@ -103,7 +103,10 @@ func (cg *configGenerateCmd) configGenerate(cmd *cobra.Command, fileHandler file
|
||||||
|
|
||||||
// createConfig creates a config file for the given provider.
|
// createConfig creates a config file for the given provider.
|
||||||
func createConfigWithAttestationType(provider cloudprovider.Provider, attestationVariant variant.Variant) (*config.Config, error) {
|
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)
|
conf.RemoveProviderExcept(provider)
|
||||||
|
|
||||||
// set a lower default for QEMU's state disk
|
// set a lower default for QEMU's state disk
|
||||||
|
|
|
@ -79,7 +79,7 @@ func TestConfigGenerateDefault(t *testing.T) {
|
||||||
var readConfig config.Config
|
var readConfig config.Config
|
||||||
err := fileHandler.ReadYAML(constants.ConfigFilename, &readConfig)
|
err := fileHandler.ReadYAML(constants.ConfigFilename, &readConfig)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Equal(*config.Default(), readConfig)
|
assert.Equal(*config.DefaultWithPanic(), readConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfigGenerateDefaultGCPSpecific(t *testing.T) {
|
func TestConfigGenerateDefaultGCPSpecific(t *testing.T) {
|
||||||
|
@ -89,7 +89,7 @@ func TestConfigGenerateDefaultGCPSpecific(t *testing.T) {
|
||||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
||||||
cmd := newConfigGenerateCmd()
|
cmd := newConfigGenerateCmd()
|
||||||
|
|
||||||
wantConf := config.Default()
|
wantConf := config.DefaultWithPanic()
|
||||||
wantConf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
wantConf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
||||||
|
|
||||||
cg := &configGenerateCmd{log: logger.NewTest(t)}
|
cg := &configGenerateCmd{log: logger.NewTest(t)}
|
||||||
|
@ -140,7 +140,7 @@ func TestConfigGenerateStdOut(t *testing.T) {
|
||||||
var readConfig config.Config
|
var readConfig config.Config
|
||||||
require.NoError(yaml.NewDecoder(&outBuffer).Decode(&readConfig))
|
require.NoError(yaml.NewDecoder(&outBuffer).Decode(&readConfig))
|
||||||
|
|
||||||
assert.Equal(*config.Default(), readConfig)
|
assert.Equal(*config.DefaultWithPanic(), readConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNoValidProviderAttestationCombination(t *testing.T) {
|
func TestNoValidProviderAttestationCombination(t *testing.T) {
|
||||||
|
@ -163,7 +163,7 @@ func TestNoValidProviderAttestationCombination(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidProviderAttestationCombination(t *testing.T) {
|
func TestValidProviderAttestationCombination(t *testing.T) {
|
||||||
defaultAttestation := config.Default().Attestation
|
defaultAttestation := config.DefaultWithPanic().Attestation
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
provider cloudprovider.Provider
|
provider cloudprovider.Provider
|
||||||
attestation variant.Variant
|
attestation variant.Variant
|
||||||
|
@ -213,7 +213,7 @@ func TestValidProviderAttestationCombination(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAttestationArgument(t *testing.T) {
|
func TestAttestationArgument(t *testing.T) {
|
||||||
defaultAttestation := config.Default().Attestation
|
defaultAttestation := config.DefaultWithPanic().Attestation
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
provider cloudprovider.Provider
|
provider cloudprovider.Provider
|
||||||
|
|
|
@ -27,7 +27,7 @@ func TestCreate(t *testing.T) {
|
||||||
fsWithDefaultConfig := func(require *require.Assertions, provider cloudprovider.Provider) afero.Fs {
|
fsWithDefaultConfig := func(require *require.Assertions, provider cloudprovider.Provider) afero.Fs {
|
||||||
fs := afero.NewMemMapFs()
|
fs := afero.NewMemMapFs()
|
||||||
file := file.NewHandler(fs)
|
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
|
return fs
|
||||||
}
|
}
|
||||||
idFile := clusterid.File{IP: "192.0.2.1"}
|
idFile := clusterid.File{IP: "192.0.2.1"}
|
||||||
|
@ -114,7 +114,7 @@ func TestCreate(t *testing.T) {
|
||||||
fs := afero.NewMemMapFs()
|
fs := afero.NewMemMapFs()
|
||||||
fileHandler := file.NewHandler(fs)
|
fileHandler := file.NewHandler(fs)
|
||||||
require.NoError(fileHandler.Write(constants.AdminConfFilename, []byte{1}, file.OptNone))
|
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
|
return fs
|
||||||
},
|
},
|
||||||
creator: &stubCloudCreator{},
|
creator: &stubCloudCreator{},
|
||||||
|
@ -129,7 +129,7 @@ func TestCreate(t *testing.T) {
|
||||||
fs := afero.NewMemMapFs()
|
fs := afero.NewMemMapFs()
|
||||||
fileHandler := file.NewHandler(fs)
|
fileHandler := file.NewHandler(fs)
|
||||||
require.NoError(fileHandler.Write(constants.MasterSecretFilename, []byte{1}, file.OptNone))
|
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
|
return fs
|
||||||
},
|
},
|
||||||
creator: &stubCloudCreator{},
|
creator: &stubCloudCreator{},
|
||||||
|
@ -162,7 +162,7 @@ func TestCreate(t *testing.T) {
|
||||||
setupFs: func(require *require.Assertions, csp cloudprovider.Provider) afero.Fs {
|
setupFs: func(require *require.Assertions, csp cloudprovider.Provider) afero.Fs {
|
||||||
fs := afero.NewMemMapFs()
|
fs := afero.NewMemMapFs()
|
||||||
fileHandler := file.NewHandler(fs)
|
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)
|
return afero.NewReadOnlyFs(fs)
|
||||||
},
|
},
|
||||||
creator: &stubCloudCreator{},
|
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().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().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(newIAMCreateAWSCmd())
|
||||||
cmd.AddCommand(newIAMCreateAzureCmd())
|
cmd.AddCommand(newIAMCreateAzureCmd())
|
||||||
|
|
|
@ -275,7 +275,7 @@ func TestIAMCreateAWS(t *testing.T) {
|
||||||
// register persistent flags manually
|
// register persistent flags manually
|
||||||
cmd.Flags().String("config", constants.ConfigFilename, "")
|
cmd.Flags().String("config", constants.ConfigFilename, "")
|
||||||
cmd.Flags().Bool("generate-config", false, "")
|
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().Bool("yes", false, "")
|
||||||
cmd.Flags().String("name", "constell", "")
|
cmd.Flags().String("name", "constell", "")
|
||||||
cmd.Flags().String("tf-log", "NONE", "")
|
cmd.Flags().String("tf-log", "NONE", "")
|
||||||
|
@ -554,7 +554,7 @@ func TestIAMCreateAzure(t *testing.T) {
|
||||||
// register persistent flags manually
|
// register persistent flags manually
|
||||||
cmd.Flags().String("config", constants.ConfigFilename, "")
|
cmd.Flags().String("config", constants.ConfigFilename, "")
|
||||||
cmd.Flags().Bool("generate-config", false, "")
|
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().Bool("yes", false, "")
|
||||||
cmd.Flags().String("name", "constell", "")
|
cmd.Flags().String("name", "constell", "")
|
||||||
cmd.Flags().String("tf-log", "NONE", "")
|
cmd.Flags().String("tf-log", "NONE", "")
|
||||||
|
@ -861,7 +861,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
// register persistent flags manually
|
// register persistent flags manually
|
||||||
cmd.Flags().String("config", constants.ConfigFilename, "")
|
cmd.Flags().String("config", constants.ConfigFilename, "")
|
||||||
cmd.Flags().Bool("generate-config", false, "")
|
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().Bool("yes", false, "")
|
||||||
cmd.Flags().String("name", "constell", "")
|
cmd.Flags().String("name", "constell", "")
|
||||||
cmd.Flags().String("tf-log", "NONE", "")
|
cmd.Flags().String("tf-log", "NONE", "")
|
||||||
|
|
|
@ -156,7 +156,7 @@ func TestInitialize(t *testing.T) {
|
||||||
// File system preparation
|
// File system preparation
|
||||||
fs := afero.NewMemMapFs()
|
fs := afero.NewMemMapFs()
|
||||||
fileHandler := file.NewHandler(fs)
|
fileHandler := file.NewHandler(fs)
|
||||||
config := defaultConfigWithExpectedMeasurements(t, config.Default(), tc.provider)
|
config := defaultConfigWithExpectedMeasurements(t, config.DefaultWithPanic(), tc.provider)
|
||||||
if tc.configMutator != nil {
|
if tc.configMutator != nil {
|
||||||
tc.configMutator(config)
|
tc.configMutator(config)
|
||||||
}
|
}
|
||||||
|
@ -427,7 +427,7 @@ func TestAttestation(t *testing.T) {
|
||||||
fileHandler := file.NewHandler(fs)
|
fileHandler := file.NewHandler(fs)
|
||||||
require.NoError(fileHandler.WriteJSON(constants.ClusterIDsFileName, existingIDFile, file.OptNone))
|
require.NoError(fileHandler.WriteJSON(constants.ClusterIDsFileName, existingIDFile, file.OptNone))
|
||||||
|
|
||||||
cfg := config.Default()
|
cfg := config.DefaultWithPanic()
|
||||||
cfg.Image = "image"
|
cfg.Image = "image"
|
||||||
cfg.RemoveProviderAndAttestationExcept(cloudprovider.QEMU)
|
cfg.RemoveProviderAndAttestationExcept(cloudprovider.QEMU)
|
||||||
cfg.Attestation.QEMUVTPM.Measurements[0] = measurements.WithAllBytes(0x00, measurements.Enforce, measurements.PCRMeasurementLength)
|
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.Name = constants.MiniConstellationUID
|
||||||
config.RemoveProviderAndAttestationExcept(cloudprovider.QEMU)
|
config.RemoveProviderAndAttestationExcept(cloudprovider.QEMU)
|
||||||
config.StateDiskSizeGB = 8
|
config.StateDiskSizeGB = 8
|
||||||
|
|
|
@ -153,7 +153,7 @@ func TestRecover(t *testing.T) {
|
||||||
fs := afero.NewMemMapFs()
|
fs := afero.NewMemMapFs()
|
||||||
fileHandler := file.NewHandler(fs)
|
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.WriteYAML(constants.ConfigFilename, config))
|
||||||
|
|
||||||
require.NoError(fileHandler.WriteJSON(
|
require.NoError(fileHandler.WriteJSON(
|
||||||
|
|
|
@ -30,6 +30,8 @@ import (
|
||||||
|
|
||||||
func TestUpgradeApply(t *testing.T) {
|
func TestUpgradeApply(t *testing.T) {
|
||||||
someErr := errors.New("some error")
|
someErr := errors.New("some error")
|
||||||
|
azureSEVSNP, err := config.DefaultForAzureSEVSNP()
|
||||||
|
require.NoError(t, err)
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
upgrader stubUpgrader
|
upgrader stubUpgrader
|
||||||
fetcher stubImageFetcher
|
fetcher stubImageFetcher
|
||||||
|
@ -38,12 +40,12 @@ func TestUpgradeApply(t *testing.T) {
|
||||||
stdin string
|
stdin string
|
||||||
}{
|
}{
|
||||||
"success": {
|
"success": {
|
||||||
upgrader: stubUpgrader{currentConfig: config.DefaultForAzureSEVSNP()},
|
upgrader: stubUpgrader{currentConfig: azureSEVSNP},
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
},
|
},
|
||||||
"nodeVersion some error": {
|
"nodeVersion some error": {
|
||||||
upgrader: stubUpgrader{
|
upgrader: stubUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: azureSEVSNP,
|
||||||
nodeVersionErr: someErr,
|
nodeVersionErr: someErr,
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
|
@ -51,14 +53,14 @@ func TestUpgradeApply(t *testing.T) {
|
||||||
},
|
},
|
||||||
"nodeVersion in progress error": {
|
"nodeVersion in progress error": {
|
||||||
upgrader: stubUpgrader{
|
upgrader: stubUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: azureSEVSNP,
|
||||||
nodeVersionErr: kubernetes.ErrInProgress,
|
nodeVersionErr: kubernetes.ErrInProgress,
|
||||||
},
|
},
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
},
|
},
|
||||||
"helm other error": {
|
"helm other error": {
|
||||||
upgrader: stubUpgrader{
|
upgrader: stubUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: azureSEVSNP,
|
||||||
helmErr: someErr,
|
helmErr: someErr,
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
|
@ -67,7 +69,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||||
},
|
},
|
||||||
"check terraform error": {
|
"check terraform error": {
|
||||||
upgrader: stubUpgrader{
|
upgrader: stubUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: azureSEVSNP,
|
||||||
checkTerraformErr: someErr,
|
checkTerraformErr: someErr,
|
||||||
},
|
},
|
||||||
fetcher: stubImageFetcher{},
|
fetcher: stubImageFetcher{},
|
||||||
|
@ -76,7 +78,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
upgrader: stubUpgrader{
|
upgrader: stubUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: azureSEVSNP,
|
||||||
terraformDiff: true,
|
terraformDiff: true,
|
||||||
},
|
},
|
||||||
fetcher: stubImageFetcher{},
|
fetcher: stubImageFetcher{},
|
||||||
|
@ -85,7 +87,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||||
},
|
},
|
||||||
"clean terraform error": {
|
"clean terraform error": {
|
||||||
upgrader: stubUpgrader{
|
upgrader: stubUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: azureSEVSNP,
|
||||||
cleanTerraformErr: someErr,
|
cleanTerraformErr: someErr,
|
||||||
terraformDiff: true,
|
terraformDiff: true,
|
||||||
},
|
},
|
||||||
|
@ -95,7 +97,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||||
},
|
},
|
||||||
"plan terraform error": {
|
"plan terraform error": {
|
||||||
upgrader: stubUpgrader{
|
upgrader: stubUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: azureSEVSNP,
|
||||||
planTerraformErr: someErr,
|
planTerraformErr: someErr,
|
||||||
},
|
},
|
||||||
fetcher: stubImageFetcher{},
|
fetcher: stubImageFetcher{},
|
||||||
|
@ -104,7 +106,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||||
},
|
},
|
||||||
"apply terraform error": {
|
"apply terraform error": {
|
||||||
upgrader: stubUpgrader{
|
upgrader: stubUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: azureSEVSNP,
|
||||||
applyTerraformErr: someErr,
|
applyTerraformErr: someErr,
|
||||||
terraformDiff: true,
|
terraformDiff: true,
|
||||||
},
|
},
|
||||||
|
@ -114,7 +116,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||||
},
|
},
|
||||||
"fetch reference error": {
|
"fetch reference error": {
|
||||||
upgrader: stubUpgrader{
|
upgrader: stubUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: azureSEVSNP,
|
||||||
},
|
},
|
||||||
fetcher: stubImageFetcher{fetchReferenceErr: someErr},
|
fetcher: stubImageFetcher{fetchReferenceErr: someErr},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
|
@ -138,7 +140,7 @@ func TestUpgradeApply(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
handler := file.NewHandler(afero.NewMemMapFs())
|
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.WriteYAML(constants.ConfigFilename, cfg))
|
||||||
require.NoError(handler.WriteJSON(constants.ClusterIDsFileName, clusterid.File{}))
|
require.NoError(handler.WriteJSON(constants.ClusterIDsFileName, clusterid.File{}))
|
||||||
|
|
||||||
|
|
|
@ -261,7 +261,7 @@ func TestUpgradeCheck(t *testing.T) {
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
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))
|
require.NoError(fileHandler.WriteYAML(tc.flags.configPath, cfg))
|
||||||
|
|
||||||
checkCmd := upgradeCheckCmd{
|
checkCmd := upgradeCheckCmd{
|
||||||
|
|
|
@ -183,7 +183,7 @@ func TestVerify(t *testing.T) {
|
||||||
}
|
}
|
||||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
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))
|
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, config))
|
||||||
if tc.idFile != nil {
|
if tc.idFile != nil {
|
||||||
require.NoError(fileHandler.WriteJSON(constants.ClusterIDsFileName, tc.idFile, file.OptNone))
|
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)
|
chart, err := loadChartsDir(helmFS, certManagerInfo.path)
|
||||||
require.NoError(err)
|
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 {
|
if tc.wantError {
|
||||||
tc.assertCorrectError(t, err)
|
tc.assertCorrectError(t, err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -46,7 +46,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
"success": {
|
"success": {
|
||||||
conf: func() *config.Config {
|
conf: func() *config.Config {
|
||||||
conf := config.Default()
|
conf := config.DefaultWithPanic()
|
||||||
conf.Image = "v1.2.3"
|
conf.Image = "v1.2.3"
|
||||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
||||||
return conf
|
return conf
|
||||||
|
@ -62,7 +62,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||||
},
|
},
|
||||||
"only k8s upgrade": {
|
"only k8s upgrade": {
|
||||||
conf: func() *config.Config {
|
conf: func() *config.Config {
|
||||||
conf := config.Default()
|
conf := config.DefaultWithPanic()
|
||||||
conf.Image = "v1.2.2"
|
conf.Image = "v1.2.2"
|
||||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
||||||
return conf
|
return conf
|
||||||
|
@ -83,7 +83,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||||
},
|
},
|
||||||
"only image upgrade": {
|
"only image upgrade": {
|
||||||
conf: func() *config.Config {
|
conf: func() *config.Config {
|
||||||
conf := config.Default()
|
conf := config.DefaultWithPanic()
|
||||||
conf.Image = "v1.2.3"
|
conf.Image = "v1.2.3"
|
||||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[0]
|
conf.KubernetesVersion = versions.SupportedK8sVersions()[0]
|
||||||
return conf
|
return conf
|
||||||
|
@ -104,7 +104,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||||
},
|
},
|
||||||
"not an upgrade": {
|
"not an upgrade": {
|
||||||
conf: func() *config.Config {
|
conf: func() *config.Config {
|
||||||
conf := config.Default()
|
conf := config.DefaultWithPanic()
|
||||||
conf.Image = "v1.2.2"
|
conf.Image = "v1.2.2"
|
||||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[0]
|
conf.KubernetesVersion = versions.SupportedK8sVersions()[0]
|
||||||
return conf
|
return conf
|
||||||
|
@ -120,7 +120,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||||
},
|
},
|
||||||
"upgrade in progress": {
|
"upgrade in progress": {
|
||||||
conf: func() *config.Config {
|
conf: func() *config.Config {
|
||||||
conf := config.Default()
|
conf := config.DefaultWithPanic()
|
||||||
conf.Image = "v1.2.3"
|
conf.Image = "v1.2.3"
|
||||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
||||||
return conf
|
return conf
|
||||||
|
@ -139,7 +139,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||||
},
|
},
|
||||||
"get error": {
|
"get error": {
|
||||||
conf: func() *config.Config {
|
conf: func() *config.Config {
|
||||||
conf := config.Default()
|
conf := config.DefaultWithPanic()
|
||||||
conf.Image = "v1.2.3"
|
conf.Image = "v1.2.3"
|
||||||
return conf
|
return conf
|
||||||
}(),
|
}(),
|
||||||
|
@ -151,7 +151,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||||
},
|
},
|
||||||
"image too new valid k8s": {
|
"image too new valid k8s": {
|
||||||
conf: func() *config.Config {
|
conf: func() *config.Config {
|
||||||
conf := config.Default()
|
conf := config.DefaultWithPanic()
|
||||||
conf.Image = "v1.4.2"
|
conf.Image = "v1.4.2"
|
||||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
||||||
return conf
|
return conf
|
||||||
|
@ -173,7 +173,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
|
||||||
},
|
},
|
||||||
"apply returns bad object": {
|
"apply returns bad object": {
|
||||||
conf: func() *config.Config {
|
conf: func() *config.Config {
|
||||||
conf := config.Default()
|
conf := config.DefaultWithPanic()
|
||||||
conf.Image = "v1.2.3"
|
conf.Image = "v1.2.3"
|
||||||
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
conf.KubernetesVersion = versions.SupportedK8sVersions()[1]
|
||||||
return conf
|
return conf
|
||||||
|
|
|
@ -213,7 +213,7 @@ func TestTrustedKeyFromSNP(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := config.DefaultForAzureSEVSNP()
|
cfg, err := config.DefaultForAzureSEVSNP()
|
||||||
cfg.FirmwareSignerConfig = config.SNPFirmwareSignerConfig{
|
cfg.FirmwareSignerConfig = config.SNPFirmwareSignerConfig{
|
||||||
AcceptedKeyDigests: tc.idkeydigests,
|
AcceptedKeyDigests: tc.idkeydigests,
|
||||||
EnforcementPolicy: tc.enforceIDKeyDigest,
|
EnforcementPolicy: tc.enforceIDKeyDigest,
|
||||||
|
@ -348,7 +348,10 @@ func TestNewSNPReportFromBytes(t *testing.T) {
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
cfg, err := config.DefaultForAzureSEVSNP()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
for name, tc := range testCases {
|
for name, tc := range testCases {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
@ -363,7 +366,6 @@ func TestNewSNPReportFromBytes(t *testing.T) {
|
||||||
assert.NotNil(report)
|
assert.NotNil(report)
|
||||||
assert.Equal(hex.EncodeToString(report.IDKeyDigest[:]), "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1")
|
assert.Equal(hex.EncodeToString(report.IDKeyDigest[:]), "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1")
|
||||||
// This is a canary for us: If this fails in the future we possibly downgraded a SVN.
|
// 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))
|
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
|
// TODO(v2.8 | AB#3130): Update tool to use variant.Variant instead of cloudprovider.Provider
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
defaultConf := config.Default()
|
defaultConf, err := config.Default()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
log.Printf("Generating measurements for %s\n", defaultConf.Image)
|
log.Printf("Generating measurements for %s\n", defaultConf.Image)
|
||||||
|
|
||||||
const filePath = "./measurements_enterprise.go"
|
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 = [
|
deps = [
|
||||||
"//internal/attestation/idkeydigest",
|
"//internal/attestation/idkeydigest",
|
||||||
"//internal/attestation/measurements",
|
"//internal/attestation/measurements",
|
||||||
|
"//internal/attestationapi",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/compatibility",
|
"//internal/compatibility",
|
||||||
"//internal/config/imageversion",
|
"//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`
|
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) {
|
func TestUnmarshalAttestationConfig(t *testing.T) {
|
||||||
|
azureSEVSNP, err := DefaultForAzureSEVSNP()
|
||||||
|
require.NoError(t, err)
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
cfg AttestationCfg
|
cfg AttestationCfg
|
||||||
}{
|
}{
|
||||||
|
@ -30,7 +32,7 @@ func TestUnmarshalAttestationConfig(t *testing.T) {
|
||||||
cfg: &AWSNitroTPM{Measurements: measurements.DefaultsFor(cloudprovider.AWS, variant.AWSNitroTPM{})},
|
cfg: &AWSNitroTPM{Measurements: measurements.DefaultsFor(cloudprovider.AWS, variant.AWSNitroTPM{})},
|
||||||
},
|
},
|
||||||
"AzureSEVSNP": {
|
"AzureSEVSNP": {
|
||||||
cfg: DefaultForAzureSEVSNP(),
|
cfg: azureSEVSNP,
|
||||||
},
|
},
|
||||||
"AzureTrustedLaunch": {
|
"AzureTrustedLaunch": {
|
||||||
cfg: &AzureTrustedLaunch{Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureTrustedLaunch{})},
|
cfg: &AzureTrustedLaunch{Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureTrustedLaunch{})},
|
||||||
|
|
|
@ -8,16 +8,19 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"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/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/config/snpversion"
|
"github.com/edgelesssys/constellation/v2/internal/config/snpversion"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/config/version"
|
"github.com/edgelesssys/constellation/v2/internal/config/version"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AzureSEVSNP is the configuration for Azure SEV-SNP attestation.
|
// 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.
|
// DefaultForAzureSEVSNP returns the default configuration for Azure SEV-SNP attestation.
|
||||||
// Version numbers are hard coded and should be updated with each new release.
|
// 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{
|
return &AzureSEVSNP{
|
||||||
Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureSEVSNP{}),
|
Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureSEVSNP{}),
|
||||||
BootloaderVersion: snpversion.GetLatest(snpversion.Bootloader),
|
BootloaderVersion: version.Bootloader,
|
||||||
TEEVersion: snpversion.GetLatest(snpversion.TEE),
|
TEEVersion: version.TEE,
|
||||||
SNPVersion: snpversion.GetLatest(snpversion.SNP),
|
SNPVersion: version.SNP,
|
||||||
MicrocodeVersion: snpversion.GetLatest(snpversion.Microcode),
|
MicrocodeVersion: version.Microcode,
|
||||||
FirmwareSignerConfig: SNPFirmwareSignerConfig{
|
FirmwareSignerConfig: SNPFirmwareSignerConfig{
|
||||||
AcceptedKeyDigests: idkeydigest.DefaultList(),
|
AcceptedKeyDigests: idkeydigest.DefaultList(),
|
||||||
EnforcementPolicy: idkeydigest.MAAFallback,
|
EnforcementPolicy: idkeydigest.MAAFallback,
|
||||||
},
|
},
|
||||||
// AMD root key. Received from the AMD Key Distribution System API (KDS).
|
// 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`),
|
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.
|
// 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.
|
// 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{
|
aux := &fusedAzureSEVSNP{
|
||||||
auxAzureSEVSNP: (*auxAzureSEVSNP)(c),
|
auxAzureSEVSNP: (*auxAzureSEVSNP)(a),
|
||||||
}
|
}
|
||||||
if err := unmarshal(aux); err != nil {
|
if err := unmarshal(aux); err != nil {
|
||||||
return fmt.Errorf("unmarshal AzureSEVSNP: %w", err)
|
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} {
|
versions, err := attestationapi.GetAzureSEVSNPVersion(context.Background())
|
||||||
if !convertLatestToNumber(c, versionType, aux) {
|
if err != nil {
|
||||||
if err := convertStringToUint(c, versionType, aux); err != nil {
|
return fmt.Errorf("failed to get AzureSEVSNP versions: %w", err)
|
||||||
return fmt.Errorf("convert %s version to number: %w", versionType, 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
|
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.
|
// AzureTrustedLaunch is the configuration for Azure Trusted Launch attestation.
|
||||||
type AzureTrustedLaunch struct {
|
type AzureTrustedLaunch struct {
|
||||||
// description: |
|
// description: |
|
||||||
|
@ -180,13 +213,13 @@ type fusedAzureSEVSNP struct {
|
||||||
// Lowest acceptable bootloader version.
|
// Lowest acceptable bootloader version.
|
||||||
BootloaderVersion string `yaml:"bootloaderVersion"`
|
BootloaderVersion string `yaml:"bootloaderVersion"`
|
||||||
// description: |
|
// description: |
|
||||||
// Lowest acceptable bootloader version.
|
// Lowest acceptable TEE version.
|
||||||
TEEVersion string `yaml:"teeVersion"`
|
TEEVersion string `yaml:"teeVersion"`
|
||||||
// description: |
|
// description: |
|
||||||
// Lowest acceptable bootloader version.
|
// Lowest acceptable SEV-SNP version.
|
||||||
SNPVersion string `yaml:"snpVersion"`
|
SNPVersion string `yaml:"snpVersion"`
|
||||||
// description: |
|
// description: |
|
||||||
// Lowest acceptable bootloader version.
|
// Lowest acceptable microcode version.
|
||||||
MicrocodeVersion string `yaml:"microcodeVersion"`
|
MicrocodeVersion string `yaml:"microcodeVersion"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,29 +234,11 @@ func convertStringToUint(c *AzureSEVSNP, versionType snpversion.Type, aux *fused
|
||||||
return nil
|
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)
|
v, stringV := getUintAndStringPtrToVersion(c, versionType, aux)
|
||||||
if strings.ToLower(*stringV) == "latest" {
|
if strings.ToLower(*stringV) == "latest" {
|
||||||
*v = snpversion.GetLatest(versionType)
|
*v = attestationapi.GetVersionByType(versions, versionType)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
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.
|
// 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{
|
return &Config{
|
||||||
Version: Version3,
|
Version: Version3,
|
||||||
Image: defaultImage,
|
Image: defaultImage,
|
||||||
|
@ -357,12 +361,21 @@ func Default() *Config {
|
||||||
// AWS will have aws-sev-snp as attestation variant
|
// AWS will have aws-sev-snp as attestation variant
|
||||||
Attestation: AttestationConfig{
|
Attestation: AttestationConfig{
|
||||||
AWSNitroTPM: &AWSNitroTPM{Measurements: measurements.DefaultsFor(cloudprovider.AWS, variant.AWSNitroTPM{})},
|
AWSNitroTPM: &AWSNitroTPM{Measurements: measurements.DefaultsFor(cloudprovider.AWS, variant.AWSNitroTPM{})},
|
||||||
AzureSEVSNP: DefaultForAzureSEVSNP(),
|
AzureSEVSNP: azureSEVSNP,
|
||||||
AzureTrustedLaunch: &AzureTrustedLaunch{Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureTrustedLaunch{})},
|
AzureTrustedLaunch: &AzureTrustedLaunch{Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureTrustedLaunch{})},
|
||||||
GCPSEVES: &GCPSEVES{Measurements: measurements.DefaultsFor(cloudprovider.GCP, variant.GCPSEVES{})},
|
GCPSEVES: &GCPSEVES{Measurements: measurements.DefaultsFor(cloudprovider.GCP, variant.GCPSEVES{})},
|
||||||
QEMUVTPM: &QEMUVTPM{Measurements: measurements.DefaultsFor(cloudprovider.QEMU, variant.QEMUVTPM{})},
|
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
|
// 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.
|
// 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.
|
// In case the field is not set in an old config we prefill it with the default value.
|
||||||
if c.MicroserviceVersion == "" {
|
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)
|
return c, c.Validate(force)
|
||||||
|
|
|
@ -33,7 +33,7 @@ func TestMain(m *testing.M) {
|
||||||
|
|
||||||
func TestDefaultConfig(t *testing.T) {
|
func TestDefaultConfig(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
def := Default()
|
def := DefaultWithPanic()
|
||||||
assert.NotNil(def)
|
assert.NotNil(def)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,11 +46,11 @@ func TestSettingLatestAsVersion(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
"mix of latest and uint as version value": {
|
"mix of latest and uint as version value": {
|
||||||
config: func() map[string]interface{} {
|
config: func() map[string]interface{} {
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
// modify versions as string
|
// modify versions as string
|
||||||
m := getConfigAsMap(conf, t)
|
m := getConfigAsMap(conf, t)
|
||||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["microcodeVersion"] = "latest"
|
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{})["snpVersion"] = "latest"
|
||||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["bootloaderVersion"] = 1
|
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["bootloaderVersion"] = 1
|
||||||
return m
|
return m
|
||||||
|
@ -58,14 +58,15 @@ func TestSettingLatestAsVersion(t *testing.T) {
|
||||||
|
|
||||||
configName: constants.ConfigFilename,
|
configName: constants.ConfigFilename,
|
||||||
wantResult: func() *Config {
|
wantResult: func() *Config {
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.Attestation.AzureSEVSNP.BootloaderVersion = 1
|
conf.Attestation.AzureSEVSNP.BootloaderVersion = 1
|
||||||
|
conf.Attestation.AzureSEVSNP.MicrocodeVersion = 93
|
||||||
return conf
|
return conf
|
||||||
}(),
|
}(),
|
||||||
},
|
},
|
||||||
"refuse invalid version value": {
|
"refuse invalid version value": {
|
||||||
config: func() map[string]interface{} {
|
config: func() map[string]interface{} {
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
m := getConfigAsMap(conf, t)
|
m := getConfigAsMap(conf, t)
|
||||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["microcodeVersion"] = "1a"
|
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["microcodeVersion"] = "1a"
|
||||||
return m
|
return m
|
||||||
|
@ -115,14 +116,14 @@ func TestFromFile(t *testing.T) {
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
"default config from default file": {
|
"default config from default file": {
|
||||||
config: Default(),
|
config: DefaultWithPanic(),
|
||||||
configName: constants.ConfigFilename,
|
configName: constants.ConfigFilename,
|
||||||
wantResult: Default(),
|
wantResult: DefaultWithPanic(),
|
||||||
},
|
},
|
||||||
"default config from different path": {
|
"default config from different path": {
|
||||||
config: Default(),
|
config: DefaultWithPanic(),
|
||||||
configName: "other-config.yaml",
|
configName: "other-config.yaml",
|
||||||
wantResult: Default(),
|
wantResult: DefaultWithPanic(),
|
||||||
},
|
},
|
||||||
"default config when path empty": {
|
"default config when path empty": {
|
||||||
config: nil,
|
config: nil,
|
||||||
|
@ -145,14 +146,14 @@ func TestFromFile(t *testing.T) {
|
||||||
},
|
},
|
||||||
"modify default config": {
|
"modify default config": {
|
||||||
config: func() *Config {
|
config: func() *Config {
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.Provider.GCP.Region = "eu-north1"
|
conf.Provider.GCP.Region = "eu-north1"
|
||||||
conf.Provider.GCP.Zone = "eu-north1-a"
|
conf.Provider.GCP.Zone = "eu-north1-a"
|
||||||
return conf
|
return conf
|
||||||
}(),
|
}(),
|
||||||
configName: constants.ConfigFilename,
|
configName: constants.ConfigFilename,
|
||||||
wantResult: func() *Config {
|
wantResult: func() *Config {
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.Provider.GCP.Region = "eu-north1"
|
conf.Provider.GCP.Region = "eu-north1"
|
||||||
conf.Provider.GCP.Zone = "eu-north1-a"
|
conf.Provider.GCP.Zone = "eu-north1-a"
|
||||||
return conf
|
return conf
|
||||||
|
@ -191,7 +192,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
"set env works": {
|
"set env works": {
|
||||||
confToWrite: func() *Config { // valid config with all, but clientSecretValue
|
confToWrite: func() *Config { // valid config with all, but clientSecretValue
|
||||||
c := Default()
|
c := DefaultWithPanic()
|
||||||
c.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
c.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||||
c.Image = "v" + constants.VersionInfo()
|
c.Image = "v" + constants.VersionInfo()
|
||||||
c.Provider.Azure.SubscriptionID = "f4278079-288c-4766-a98c-ab9d5dba01a5"
|
c.Provider.Azure.SubscriptionID = "f4278079-288c-4766-a98c-ab9d5dba01a5"
|
||||||
|
@ -212,7 +213,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
|
||||||
},
|
},
|
||||||
"set env overwrites": {
|
"set env overwrites": {
|
||||||
confToWrite: func() *Config {
|
confToWrite: func() *Config {
|
||||||
c := Default()
|
c := DefaultWithPanic()
|
||||||
c.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
c.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||||
c.Image = "v" + constants.VersionInfo()
|
c.Image = "v" + constants.VersionInfo()
|
||||||
c.Provider.Azure.SubscriptionID = "f4278079-288c-4766-a98c-ab9d5dba01a5"
|
c.Provider.Azure.SubscriptionID = "f4278079-288c-4766-a98c-ab9d5dba01a5"
|
||||||
|
@ -276,13 +277,13 @@ func TestValidate(t *testing.T) {
|
||||||
wantErrCount int
|
wantErrCount int
|
||||||
}{
|
}{
|
||||||
"default config is not valid": {
|
"default config is not valid": {
|
||||||
cnf: Default(),
|
cnf: DefaultWithPanic(),
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantErrCount: defaultErrCount,
|
wantErrCount: defaultErrCount,
|
||||||
},
|
},
|
||||||
"v0 is one error": {
|
"v0 is one error": {
|
||||||
cnf: func() *Config {
|
cnf: func() *Config {
|
||||||
cnf := Default()
|
cnf := DefaultWithPanic()
|
||||||
cnf.Version = "v0"
|
cnf.Version = "v0"
|
||||||
return cnf
|
return cnf
|
||||||
}(),
|
}(),
|
||||||
|
@ -291,7 +292,7 @@ func TestValidate(t *testing.T) {
|
||||||
},
|
},
|
||||||
"v0 and negative state disk are two errors": {
|
"v0 and negative state disk are two errors": {
|
||||||
cnf: func() *Config {
|
cnf: func() *Config {
|
||||||
cnf := Default()
|
cnf := DefaultWithPanic()
|
||||||
cnf.Version = "v0"
|
cnf.Version = "v0"
|
||||||
cnf.StateDiskSizeGB = -1
|
cnf.StateDiskSizeGB = -1
|
||||||
return cnf
|
return cnf
|
||||||
|
@ -301,7 +302,7 @@ func TestValidate(t *testing.T) {
|
||||||
},
|
},
|
||||||
"default Azure config is not valid": {
|
"default Azure config is not valid": {
|
||||||
cnf: func() *Config {
|
cnf: func() *Config {
|
||||||
cnf := Default()
|
cnf := DefaultWithPanic()
|
||||||
cnf.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
cnf.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||||
return cnf
|
return cnf
|
||||||
}(),
|
}(),
|
||||||
|
@ -310,7 +311,7 @@ func TestValidate(t *testing.T) {
|
||||||
},
|
},
|
||||||
"Azure config with all required fields is valid": {
|
"Azure config with all required fields is valid": {
|
||||||
cnf: func() *Config {
|
cnf: func() *Config {
|
||||||
cnf := Default()
|
cnf := DefaultWithPanic()
|
||||||
cnf.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
cnf.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||||
cnf.Image = "v" + constants.VersionInfo()
|
cnf.Image = "v" + constants.VersionInfo()
|
||||||
az := cnf.Provider.Azure
|
az := cnf.Provider.Azure
|
||||||
|
@ -331,7 +332,7 @@ func TestValidate(t *testing.T) {
|
||||||
},
|
},
|
||||||
"default GCP config is not valid": {
|
"default GCP config is not valid": {
|
||||||
cnf: func() *Config {
|
cnf: func() *Config {
|
||||||
cnf := Default()
|
cnf := DefaultWithPanic()
|
||||||
cnf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
cnf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
||||||
return cnf
|
return cnf
|
||||||
}(),
|
}(),
|
||||||
|
@ -340,7 +341,7 @@ func TestValidate(t *testing.T) {
|
||||||
},
|
},
|
||||||
"GCP config with all required fields is valid": {
|
"GCP config with all required fields is valid": {
|
||||||
cnf: func() *Config {
|
cnf: func() *Config {
|
||||||
cnf := Default()
|
cnf := DefaultWithPanic()
|
||||||
cnf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
cnf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
||||||
cnf.Image = "v" + constants.VersionInfo()
|
cnf.Image = "v" + constants.VersionInfo()
|
||||||
gcp := cnf.Provider.GCP
|
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.
|
// TODO: v2.7: remove this test as it should start breaking after v2.6 is released.
|
||||||
"k8s vMAJOR.MINOR is valid in v2.7": {
|
"k8s vMAJOR.MINOR is valid in v2.7": {
|
||||||
cnf: func() *Config {
|
cnf: func() *Config {
|
||||||
cnf := Default()
|
cnf := DefaultWithPanic()
|
||||||
cnf.KubernetesVersion = "v1.25"
|
cnf.KubernetesVersion = "v1.25"
|
||||||
return cnf
|
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.
|
// TODO: v2.7: remove this test as it should start breaking after v2.6 is released.
|
||||||
"k8s MAJOR.MINOR is valid in v2.7": {
|
"k8s MAJOR.MINOR is valid in v2.7": {
|
||||||
cnf: func() *Config {
|
cnf: func() *Config {
|
||||||
cnf := Default()
|
cnf := DefaultWithPanic()
|
||||||
cnf.KubernetesVersion = "1.25"
|
cnf.KubernetesVersion = "1.25"
|
||||||
return cnf
|
return cnf
|
||||||
}(),
|
}(),
|
||||||
|
@ -403,9 +404,9 @@ func TestHasProvider(t *testing.T) {
|
||||||
assert.False((&Config{}).HasProvider(cloudprovider.Azure))
|
assert.False((&Config{}).HasProvider(cloudprovider.Azure))
|
||||||
assert.False((&Config{}).HasProvider(cloudprovider.GCP))
|
assert.False((&Config{}).HasProvider(cloudprovider.GCP))
|
||||||
assert.False((&Config{}).HasProvider(cloudprovider.QEMU))
|
assert.False((&Config{}).HasProvider(cloudprovider.QEMU))
|
||||||
assert.False(Default().HasProvider(cloudprovider.Unknown))
|
assert.False(DefaultWithPanic().HasProvider(cloudprovider.Unknown))
|
||||||
assert.True(Default().HasProvider(cloudprovider.Azure))
|
assert.True(DefaultWithPanic().HasProvider(cloudprovider.Azure))
|
||||||
assert.True(Default().HasProvider(cloudprovider.GCP))
|
assert.True(DefaultWithPanic().HasProvider(cloudprovider.GCP))
|
||||||
cnfWithAzure := Config{Provider: ProviderConfig{Azure: &AzureConfig{}}}
|
cnfWithAzure := Config{Provider: ProviderConfig{Azure: &AzureConfig{}}}
|
||||||
assert.False(cnfWithAzure.HasProvider(cloudprovider.Unknown))
|
assert.False(cnfWithAzure.HasProvider(cloudprovider.Unknown))
|
||||||
assert.True(cnfWithAzure.HasProvider(cloudprovider.Azure))
|
assert.True(cnfWithAzure.HasProvider(cloudprovider.Azure))
|
||||||
|
@ -422,26 +423,26 @@ func TestConfigRemoveProviderExcept(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
"except aws": {
|
"except aws": {
|
||||||
removeExcept: cloudprovider.AWS,
|
removeExcept: cloudprovider.AWS,
|
||||||
wantAWS: Default().Provider.AWS,
|
wantAWS: DefaultWithPanic().Provider.AWS,
|
||||||
},
|
},
|
||||||
"except azure": {
|
"except azure": {
|
||||||
removeExcept: cloudprovider.Azure,
|
removeExcept: cloudprovider.Azure,
|
||||||
wantAzure: Default().Provider.Azure,
|
wantAzure: DefaultWithPanic().Provider.Azure,
|
||||||
},
|
},
|
||||||
"except gcp": {
|
"except gcp": {
|
||||||
removeExcept: cloudprovider.GCP,
|
removeExcept: cloudprovider.GCP,
|
||||||
wantGCP: Default().Provider.GCP,
|
wantGCP: DefaultWithPanic().Provider.GCP,
|
||||||
},
|
},
|
||||||
"except qemu": {
|
"except qemu": {
|
||||||
removeExcept: cloudprovider.QEMU,
|
removeExcept: cloudprovider.QEMU,
|
||||||
wantQEMU: Default().Provider.QEMU,
|
wantQEMU: DefaultWithPanic().Provider.QEMU,
|
||||||
},
|
},
|
||||||
"unknown provider": {
|
"unknown provider": {
|
||||||
removeExcept: cloudprovider.Unknown,
|
removeExcept: cloudprovider.Unknown,
|
||||||
wantAWS: Default().Provider.AWS,
|
wantAWS: DefaultWithPanic().Provider.AWS,
|
||||||
wantAzure: Default().Provider.Azure,
|
wantAzure: DefaultWithPanic().Provider.Azure,
|
||||||
wantGCP: Default().Provider.GCP,
|
wantGCP: DefaultWithPanic().Provider.GCP,
|
||||||
wantQEMU: Default().Provider.QEMU,
|
wantQEMU: DefaultWithPanic().Provider.QEMU,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,7 +450,7 @@ func TestConfigRemoveProviderExcept(t *testing.T) {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.RemoveProviderAndAttestationExcept(tc.removeExcept)
|
conf.RemoveProviderAndAttestationExcept(tc.removeExcept)
|
||||||
|
|
||||||
assert.Equal(tc.wantAWS, conf.Provider.AWS)
|
assert.Equal(tc.wantAWS, conf.Provider.AWS)
|
||||||
|
@ -481,7 +482,7 @@ func TestConfig_UpdateMeasurements(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // AWS
|
{ // AWS
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.RemoveProviderAndAttestationExcept(cloudprovider.AWS)
|
conf.RemoveProviderAndAttestationExcept(cloudprovider.AWS)
|
||||||
for k := range conf.Attestation.AWSNitroTPM.Measurements {
|
for k := range conf.Attestation.AWSNitroTPM.Measurements {
|
||||||
delete(conf.Attestation.AWSNitroTPM.Measurements, k)
|
delete(conf.Attestation.AWSNitroTPM.Measurements, k)
|
||||||
|
@ -490,7 +491,7 @@ func TestConfig_UpdateMeasurements(t *testing.T) {
|
||||||
assert.Equal(newMeasurements, conf.Attestation.AWSNitroTPM.Measurements)
|
assert.Equal(newMeasurements, conf.Attestation.AWSNitroTPM.Measurements)
|
||||||
}
|
}
|
||||||
{ // Azure
|
{ // Azure
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
conf.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||||
for k := range conf.Attestation.AzureSEVSNP.Measurements {
|
for k := range conf.Attestation.AzureSEVSNP.Measurements {
|
||||||
delete(conf.Attestation.AzureSEVSNP.Measurements, k)
|
delete(conf.Attestation.AzureSEVSNP.Measurements, k)
|
||||||
|
@ -499,7 +500,7 @@ func TestConfig_UpdateMeasurements(t *testing.T) {
|
||||||
assert.Equal(newMeasurements, conf.Attestation.AzureSEVSNP.Measurements)
|
assert.Equal(newMeasurements, conf.Attestation.AzureSEVSNP.Measurements)
|
||||||
}
|
}
|
||||||
{ // GCP
|
{ // GCP
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
conf.RemoveProviderAndAttestationExcept(cloudprovider.GCP)
|
||||||
for k := range conf.Attestation.GCPSEVES.Measurements {
|
for k := range conf.Attestation.GCPSEVES.Measurements {
|
||||||
delete(conf.Attestation.GCPSEVES.Measurements, k)
|
delete(conf.Attestation.GCPSEVES.Measurements, k)
|
||||||
|
@ -508,7 +509,7 @@ func TestConfig_UpdateMeasurements(t *testing.T) {
|
||||||
assert.Equal(newMeasurements, conf.Attestation.GCPSEVES.Measurements)
|
assert.Equal(newMeasurements, conf.Attestation.GCPSEVES.Measurements)
|
||||||
}
|
}
|
||||||
{ // QEMU
|
{ // QEMU
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.RemoveProviderAndAttestationExcept(cloudprovider.QEMU)
|
conf.RemoveProviderAndAttestationExcept(cloudprovider.QEMU)
|
||||||
for k := range conf.Attestation.QEMUVTPM.Measurements {
|
for k := range conf.Attestation.QEMUVTPM.Measurements {
|
||||||
delete(conf.Attestation.QEMUVTPM.Measurements, k)
|
delete(conf.Attestation.QEMUVTPM.Measurements, k)
|
||||||
|
@ -525,7 +526,7 @@ func TestConfig_IsReleaseImage(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
"release image v0.0.0": {
|
"release image v0.0.0": {
|
||||||
conf: func() *Config {
|
conf: func() *Config {
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.Image = "v0.0.0"
|
conf.Image = "v0.0.0"
|
||||||
return conf
|
return conf
|
||||||
}(),
|
}(),
|
||||||
|
@ -533,7 +534,7 @@ func TestConfig_IsReleaseImage(t *testing.T) {
|
||||||
},
|
},
|
||||||
"branch image": {
|
"branch image": {
|
||||||
conf: func() *Config {
|
conf: func() *Config {
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.Image = "feat-x-vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef"
|
conf.Image = "feat-x-vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef"
|
||||||
return conf
|
return conf
|
||||||
}(),
|
}(),
|
||||||
|
@ -541,7 +542,7 @@ func TestConfig_IsReleaseImage(t *testing.T) {
|
||||||
},
|
},
|
||||||
"debug image": {
|
"debug image": {
|
||||||
conf: func() *Config {
|
conf: func() *Config {
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.Image = "debug-vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef"
|
conf.Image = "debug-vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef"
|
||||||
return conf
|
return conf
|
||||||
}(),
|
}(),
|
||||||
|
@ -687,11 +688,11 @@ func TestIsDebugCluster(t *testing.T) {
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
},
|
},
|
||||||
"default config": {
|
"default config": {
|
||||||
config: Default(),
|
config: DefaultWithPanic(),
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
},
|
},
|
||||||
"enabled": {
|
"enabled": {
|
||||||
config: Default(),
|
config: DefaultWithPanic(),
|
||||||
prepareConfig: func(conf *Config) {
|
prepareConfig: func(conf *Config) {
|
||||||
*conf.DebugCluster = true
|
*conf.DebugCluster = true
|
||||||
},
|
},
|
||||||
|
@ -754,7 +755,7 @@ func TestValidateProvider(t *testing.T) {
|
||||||
v := validator.New()
|
v := validator.New()
|
||||||
trans := ut.New(en.New()).GetFallback()
|
trans := ut.New(en.New()).GetFallback()
|
||||||
|
|
||||||
conf := Default()
|
conf := DefaultWithPanic()
|
||||||
conf.Provider = tc.provider
|
conf.Provider = tc.provider
|
||||||
|
|
||||||
v.RegisterStructValidation(validateProvider, ProviderConfig{})
|
v.RegisterStructValidation(validateProvider, ProviderConfig{})
|
||||||
|
|
|
@ -242,7 +242,11 @@ func V2ToV3(path string, fileHandler file.Handler) error {
|
||||||
Measurements: cfgV2.Provider.Azure.Measurements,
|
Measurements: cfgV2.Provider.Azure.Measurements,
|
||||||
}
|
}
|
||||||
} else {
|
} 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.Measurements = cfgV2.Provider.Azure.Measurements
|
||||||
cfgV3.Attestation.AzureSEVSNP.FirmwareSignerConfig = config.SNPFirmwareSignerConfig{
|
cfgV3.Attestation.AzureSEVSNP.FirmwareSignerConfig = config.SNPFirmwareSignerConfig{
|
||||||
AcceptedKeyDigests: cfgV2.Provider.Azure.IDKeyDigest,
|
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 {
|
for _, k := range keys {
|
||||||
res = append(res, providerAttestationMapping[k]...)
|
res = append(res, providerAttestationMapping[k]...)
|
||||||
}
|
}
|
||||||
return removeDuplicate(res)
|
return RemoveDuplicate(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getter returns an ASN.1 Object Identifier.
|
// Getter returns an ASN.1 Object Identifier.
|
||||||
|
@ -259,9 +259,10 @@ func (QEMUTDX) Equal(other Getter) bool {
|
||||||
return other.OID().Equal(QEMUTDX{}.OID())
|
return other.OID().Equal(QEMUTDX{}.OID())
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeDuplicate(sliceList []Variant) []Variant {
|
// RemoveDuplicate removes duplicate elements from a slice.
|
||||||
allKeys := make(map[Variant]bool)
|
func RemoveDuplicate[T comparable](sliceList []T) []T {
|
||||||
list := []Variant{}
|
allKeys := make(map[T]bool)
|
||||||
|
list := []T{}
|
||||||
for _, item := range sliceList {
|
for _, item := range sliceList {
|
||||||
if _, value := allKeys[item]; !value {
|
if _, value := allKeys[item]; !value {
|
||||||
allKeys[item] = true
|
allKeys[item] = true
|
||||||
|
|
|
@ -4,6 +4,7 @@ load("//bazel/go:go_test.bzl", "go_test")
|
||||||
go_library(
|
go_library(
|
||||||
name = "versionsapi",
|
name = "versionsapi",
|
||||||
srcs = [
|
srcs = [
|
||||||
|
"attestation.go",
|
||||||
"cliinfo.go",
|
"cliinfo.go",
|
||||||
"imageinfo.go",
|
"imageinfo.go",
|
||||||
"latest.go",
|
"latest.go",
|
||||||
|
@ -16,6 +17,7 @@ go_library(
|
||||||
deps = [
|
deps = [
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/constants",
|
"//internal/constants",
|
||||||
|
"//internal/variant",
|
||||||
"@org_golang_x_mod//semver",
|
"@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)
|
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 {
|
type apiObject interface {
|
||||||
ValidateRequest() error
|
ValidateRequest() error
|
||||||
Validate() error
|
Validate() error
|
||||||
|
|
|
@ -38,6 +38,8 @@ func TestMain(m *testing.M) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewUpdateableValidator(t *testing.T) {
|
func TestNewUpdateableValidator(t *testing.T) {
|
||||||
|
azureSEVSNP, err := config.DefaultForAzureSEVSNP()
|
||||||
|
require.NoError(t, err)
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
variant variant.Variant
|
variant variant.Variant
|
||||||
config config.AttestationCfg
|
config config.AttestationCfg
|
||||||
|
@ -45,7 +47,7 @@ func TestNewUpdateableValidator(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
"azure": {
|
"azure": {
|
||||||
variant: variant.AzureSEVSNP{},
|
variant: variant.AzureSEVSNP{},
|
||||||
config: config.DefaultForAzureSEVSNP(),
|
config: azureSEVSNP,
|
||||||
},
|
},
|
||||||
"gcp": {
|
"gcp": {
|
||||||
variant: variant.GCPSEVES{},
|
variant: variant.GCPSEVES{},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue