mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-09-28 23:09:36 -04:00
config: add separate option for handling attestation parameters (#1623)
* Add attestation options to config * Add join-config migration path for clusters with old measurement format * Always create MAA provider for Azure SNP clusters * Remove confidential VM option from provider in favor of attestation options * cli: add config migrate command to handle config migration (#1678) --------- Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
6027b066e5
commit
d7a2ddd939
74 changed files with 1339 additions and 1282 deletions
|
@ -318,9 +318,7 @@ go_library(
|
|||
importpath = "github.com/edgelesssys/constellation/v2/cli/internal/helm",
|
||||
visibility = ["//cli:__subpackages__"],
|
||||
deps = [
|
||||
"//cli/internal/clusterid",
|
||||
"//cli/internal/helm/imageversion",
|
||||
"//internal/attestation/idkeydigest",
|
||||
"//internal/cloud/cloudprovider",
|
||||
"//internal/compatibility",
|
||||
"//internal/config",
|
||||
|
@ -363,7 +361,6 @@ go_test(
|
|||
"//internal/deploy/helm",
|
||||
"//internal/file",
|
||||
"//internal/logger",
|
||||
"//internal/variant",
|
||||
"@com_github_pkg_errors//:errors",
|
||||
"@com_github_spf13_afero//:afero",
|
||||
"@com_github_stretchr_testify//assert",
|
||||
|
|
|
@ -5,9 +5,6 @@ metadata:
|
|||
namespace: {{ .Release.Namespace }}
|
||||
data:
|
||||
{{/* mustToJson is required so the json-strings passed from go are of type string in the rendered yaml. */}}
|
||||
measurements: {{ .Values.measurements | mustToJson }}
|
||||
{{- if eq .Values.csp "Azure" }}
|
||||
idKeyConfig: {{ .Values.idKeyConfig | mustToJson }}
|
||||
{{- end }}
|
||||
attestationConfig: {{ .Values.attestationConfig | mustToJson }}
|
||||
binaryData:
|
||||
measurementSalt: {{ .Values.measurementSalt }}
|
||||
|
|
|
@ -5,15 +5,10 @@
|
|||
"description": "CSP to which the chart is deployed.",
|
||||
"enum": ["AWS", "Azure", "GCP", "OpenStack", "QEMU"]
|
||||
},
|
||||
"measurements": {
|
||||
"description": "JSON-string to describe the expected measurements.",
|
||||
"attestationConfig": {
|
||||
"description": "JSON-string to describe the config to use for attestation validation.",
|
||||
"type": "string",
|
||||
"examples": ["{'1':{'expected':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA','warnOnly':true},'15':{'expected':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=','warnOnly':true}}"]
|
||||
},
|
||||
"idKeyConfig": {
|
||||
"description": "Configuration for validating the ID Key Digest of the SEV-SNP attestation.",
|
||||
"type": "string",
|
||||
"examples": ["{'enforcementPolicy': 'MAAFallback', 'maaURL': 'https://192.0.2.1:8080/maa', 'acceptedKeyDigests': ['57486a447ec0f1958002a22a06b7673b9fd27d11e1c6527498056054c5fa92d23c50f9de44072760fe2b6fb89740b696', '0356215882a825279a85b300b0b742931d113bf7e32dde2e50ffde7ec743ca491ecdd7f336dc28a6e0b2bb57af7a44a3'}"]
|
||||
"examples": ["{'measurements':{'1':{'expected':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA','warnOnly':true},'15':{'expected':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=','warnOnly':true}}}"]
|
||||
},
|
||||
"image": {
|
||||
"description": "Container image to use for the spawned pods.",
|
||||
|
@ -33,16 +28,11 @@
|
|||
},
|
||||
"required": [
|
||||
"csp",
|
||||
"measurements",
|
||||
"attestationConfig",
|
||||
"measurementSalt",
|
||||
"image",
|
||||
"attestationVariant"
|
||||
],
|
||||
"if": {
|
||||
"properties": { "csp": { "const": "azure" } },
|
||||
"required": ["csp"]
|
||||
},
|
||||
"then": { "required": ["idKeyConfig"] },
|
||||
"title": "Values",
|
||||
"type": "object"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
csp: "gcp"
|
||||
attestationVariant: ""
|
||||
measurements: ""
|
||||
idKeyConfig: ""
|
||||
measurementSalt: ""
|
||||
joinServicePort: 9090
|
||||
joinServiceNodePort: 30090
|
||||
|
|
|
@ -47,11 +47,6 @@ spec:
|
|||
- name: config
|
||||
projected:
|
||||
sources:
|
||||
- configMap:
|
||||
items:
|
||||
- key: {{ .Values.measurementsFilename | quote }}
|
||||
path: {{ .Values.measurementsFilename | quote }}
|
||||
name: {{ .Values.global.joinConfigCMName | quote }}
|
||||
- secret:
|
||||
items:
|
||||
- key: {{ .Values.masterSecretKeyName | quote }}
|
||||
|
|
|
@ -4,5 +4,3 @@ saltKeyName: salt
|
|||
masterSecretName: constellation-mastersecret
|
||||
# Name of the key within the respective secret that holds the master secret.
|
||||
masterSecretKeyName: mastersecret
|
||||
# Name of the ConfigMap that holds the measurements.
|
||||
measurementsFilename: measurements
|
||||
|
|
|
@ -14,8 +14,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
|
||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||
|
@ -147,9 +146,8 @@ func (c *Client) Upgrade(ctx context.Context, config *config.Config, timeout tim
|
|||
return fmt.Errorf("creating CR backup: %w", err)
|
||||
}
|
||||
|
||||
fileHandler := file.NewHandler(afero.NewOsFs())
|
||||
for _, chart := range upgradeReleases {
|
||||
err = c.upgradeRelease(ctx, timeout, config, chart, allowDestructive, fileHandler)
|
||||
err = c.upgradeRelease(ctx, timeout, config, chart, allowDestructive)
|
||||
if err != nil {
|
||||
return fmt.Errorf("upgrading %s: %w", chart.Metadata.Name, err)
|
||||
}
|
||||
|
@ -245,7 +243,7 @@ func (s ServiceVersions) ConstellationServices() string {
|
|||
}
|
||||
|
||||
func (c *Client) upgradeRelease(
|
||||
ctx context.Context, timeout time.Duration, conf *config.Config, chart *chart.Chart, allowDestructive bool, fileHandler file.Handler,
|
||||
ctx context.Context, timeout time.Duration, conf *config.Config, chart *chart.Chart, allowDestructive bool,
|
||||
) error {
|
||||
// We need to load all values that can be statically loaded before merging them with the cluster
|
||||
// values. Otherwise the templates are not rendered correctly.
|
||||
|
@ -289,7 +287,7 @@ func (c *Client) upgradeRelease(
|
|||
return fmt.Errorf("loading values: %w", err)
|
||||
}
|
||||
|
||||
if err := c.applyMigrations(releaseName, values, conf, fileHandler); err != nil {
|
||||
if err := c.applyMigrations(ctx, releaseName, values, conf); err != nil {
|
||||
return fmt.Errorf("applying migrations: %w", err)
|
||||
}
|
||||
default:
|
||||
|
@ -312,7 +310,7 @@ func (c *Client) upgradeRelease(
|
|||
// applyMigrations checks the from version and applies the necessary migrations.
|
||||
// The function assumes the caller has verified that our version drift restriction is not violated,
|
||||
// Currently, this is done during config validation.
|
||||
func (c *Client) applyMigrations(releaseName string, values map[string]any, conf *config.Config, fileHandler file.Handler) error {
|
||||
func (c *Client) applyMigrations(ctx context.Context, releaseName string, values map[string]any, conf *config.Config) error {
|
||||
current, err := c.currentVersion(releaseName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting %s version: %w", releaseName, err)
|
||||
|
@ -322,37 +320,50 @@ func (c *Client) applyMigrations(releaseName string, values map[string]any, conf
|
|||
return fmt.Errorf("parsing current version: %w", err)
|
||||
}
|
||||
|
||||
if currentV.Major == 2 && currentV.Minor == 6 {
|
||||
return migrateFrom2_6(values, conf, fileHandler)
|
||||
if currentV.Major == 2 && currentV.Minor == 7 {
|
||||
return migrateFrom2_7(ctx, values, conf, c.kubectl)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// migrateFrom2_6 applies the necessary migrations for upgrading from v2.6.x to v2.7.x.
|
||||
// migrateFrom2_6 should be applied for v2.6.x --> v2.7.x.
|
||||
// migrateFrom2_6 should NOT be applied for v2.7.0 --> v2.7.x.
|
||||
// This function can be removed once we are sure that we will no longer provide backports for v2.6.
|
||||
func migrateFrom2_6(values map[string]any, conf *config.Config, fileHandler file.Handler) error {
|
||||
// Manually setting attestationVariant is required here since upgrade normally isn't allowed to change this value.
|
||||
// However, to introduce the value into a 2.6 cluster for the first time we have to set it nevertheless.
|
||||
if err := setAttestationVariant(values, conf.AttestationVariant); err != nil {
|
||||
return fmt.Errorf("setting attestationVariant: %w", err)
|
||||
// migrateFrom2_7 applies the necessary migrations for upgrading from v2.7.x to v2.8.x.
|
||||
// migrateFrom2_7 should be applied for v2.7.x --> v2.8.x.
|
||||
// migrateFrom2_7 should NOT be applied for v2.8.0 --> v2.8.x.
|
||||
// Remove after release of v2.8.0.
|
||||
func migrateFrom2_7(ctx context.Context, values map[string]any, conf *config.Config, kubeclient crdClient) error {
|
||||
if conf.GetProvider() == cloudprovider.GCP {
|
||||
if err := updateGCPStorageClass(ctx, kubeclient); err != nil {
|
||||
return fmt.Errorf("applying migration for GCP storage class: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Manually setting idKeyConfig is required here since upgrade normally isn't allowed to change this value.
|
||||
// However, to introduce the value into a 2.6 cluster for the first time we have to set it nevertheless.
|
||||
var idFile clusterid.File
|
||||
if err := fileHandler.ReadJSON(constants.ClusterIDsFileName, &idFile); err != nil {
|
||||
return fmt.Errorf("reading cluster ID file: %w", err)
|
||||
return updateJoinConfig(values, conf)
|
||||
}
|
||||
|
||||
func updateGCPStorageClass(ctx context.Context, kubeclient crdClient) error {
|
||||
// v2.8 updates the disk type of GCP default storage class
|
||||
// This value is not updatable in Kubernetes, but we can use a workaround to update it:
|
||||
// First, we delete the storage class, then we upgrade the chart,
|
||||
// which will recreate the storage class with the new disk type.
|
||||
if err := kubeclient.DeleteStorageClass(ctx, "encrypted-rwo"); err != nil {
|
||||
return fmt.Errorf("deleting storage class for update: %w", err)
|
||||
}
|
||||
// Disallow users to set MAAFallback as ID key digest policy for upgrades, since it requires extra cloud resources.
|
||||
if conf.IDKeyDigestPolicy() == idkeydigest.MAAFallback {
|
||||
return fmt.Errorf("ID key digest policy %s is not supported for upgrades", conf.IDKeyDigestPolicy())
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateJoinConfig(values map[string]any, conf *config.Config) error {
|
||||
joinServiceVals, ok := values["join-service"].(map[string]interface{})
|
||||
if !ok {
|
||||
return errors.New("invalid join-service config")
|
||||
}
|
||||
if err := setIdkeyConfig(values, conf, idFile.AttestationURL); err != nil {
|
||||
return fmt.Errorf("setting id key config: %w", err)
|
||||
|
||||
attestationConfigJSON, err := json.Marshal(conf.GetAttestationConfig())
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshalling attestation config: %w", err)
|
||||
}
|
||||
joinServiceVals["attestationConfig"] = string(attestationConfigJSON)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -404,44 +415,6 @@ func (c *Client) updateCRDs(ctx context.Context, chart *chart.Chart) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// setAttestationVariant sets the attesationVariant value on verification-service and join-service value maps.
|
||||
func setAttestationVariant(values map[string]any, variant string) error {
|
||||
joinServiceVals, ok := values["join-service"].(map[string]any)
|
||||
if !ok {
|
||||
return errors.New("invalid join-service values")
|
||||
}
|
||||
joinServiceVals["attestationVariant"] = variant
|
||||
|
||||
verifyServiceVals, ok := values["verification-service"].(map[string]any)
|
||||
if !ok {
|
||||
return errors.New("invalid verification-service values")
|
||||
}
|
||||
verifyServiceVals["attestationVariant"] = variant
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// setIdkeyConfig sets the idkeyconfig value on the join-service value maps.
|
||||
func setIdkeyConfig(values map[string]any, cfg *config.Config, maaURL string) error {
|
||||
joinServiceVals, ok := values["join-service"].(map[string]any)
|
||||
if !ok {
|
||||
return errors.New("invalid join-service values")
|
||||
}
|
||||
|
||||
idKeyCfg := config.SNPFirmwareSignerConfig{
|
||||
AcceptedKeyDigests: cfg.IDKeyDigests(),
|
||||
EnforcementPolicy: cfg.IDKeyDigestPolicy(),
|
||||
MAAURL: maaURL,
|
||||
}
|
||||
marshalledCfg, err := json.Marshal(idKeyCfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshalling id key digest config: %w", err)
|
||||
}
|
||||
joinServiceVals["idKeyConfig"] = string(marshalledCfg)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type debugLog interface {
|
||||
Debugf(format string, args ...any)
|
||||
Sync()
|
||||
|
@ -452,6 +425,7 @@ type crdClient interface {
|
|||
ApplyCRD(ctx context.Context, rawCRD []byte) error
|
||||
GetCRDs(ctx context.Context) ([]apiextensionsv1.CustomResourceDefinition, error)
|
||||
GetCRs(ctx context.Context, gvr schema.GroupVersionResource) ([]unstructured.Unstructured, error)
|
||||
DeleteStorageClass(ctx context.Context, name string) error // TODO: remove with v2.9
|
||||
}
|
||||
|
||||
type actionWrapper interface {
|
||||
|
|
|
@ -13,9 +13,7 @@ import (
|
|||
|
||||
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"helm.sh/helm/v3/pkg/chart"
|
||||
|
@ -90,8 +88,7 @@ func TestUpgradeRelease(t *testing.T) {
|
|||
|
||||
chart, err := loadChartsDir(helmFS, certManagerInfo.path)
|
||||
require.NoError(err)
|
||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
||||
err = client.upgradeRelease(context.Background(), 0, config.Default(), chart, tc.allowDestructive, fileHandler)
|
||||
err = client.upgradeRelease(context.Background(), 0, config.Default(), chart, tc.allowDestructive)
|
||||
if tc.wantError {
|
||||
tc.assertCorrectError(t, err)
|
||||
return
|
||||
|
|
|
@ -110,7 +110,7 @@ func AvailableServiceVersions() (string, error) {
|
|||
}
|
||||
|
||||
// Load the embedded helm charts.
|
||||
func (i *ChartLoader) Load(config *config.Config, conformanceMode bool, masterSecret, salt []byte, maaURL string) ([]byte, error) {
|
||||
func (i *ChartLoader) Load(config *config.Config, conformanceMode bool, masterSecret, salt []byte) ([]byte, error) {
|
||||
ciliumRelease, err := i.loadRelease(ciliumInfo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loading cilium: %w", err)
|
||||
|
@ -131,7 +131,7 @@ func (i *ChartLoader) Load(config *config.Config, conformanceMode bool, masterSe
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("loading constellation-services: %w", err)
|
||||
}
|
||||
if err := extendConstellationServicesValues(conServicesRelease.Values, config, masterSecret, salt, maaURL); err != nil {
|
||||
if err := extendConstellationServicesValues(conServicesRelease.Values, config, masterSecret, salt); err != nil {
|
||||
return nil, fmt.Errorf("extending constellation-services values: %w", err)
|
||||
}
|
||||
|
||||
|
@ -374,11 +374,10 @@ func (i *ChartLoader) loadConstellationServicesValues() (map[string]any, error)
|
|||
"internalCMName": constants.InternalConfigMap,
|
||||
},
|
||||
"key-service": map[string]any{
|
||||
"image": i.keyServiceImage,
|
||||
"saltKeyName": constants.ConstellationSaltKey,
|
||||
"masterSecretKeyName": constants.ConstellationMasterSecretKey,
|
||||
"masterSecretName": constants.ConstellationMasterSecretStoreName,
|
||||
"measurementsFilename": constants.MeasurementsFilename,
|
||||
"image": i.keyServiceImage,
|
||||
"saltKeyName": constants.ConstellationSaltKey,
|
||||
"masterSecretKeyName": constants.ConstellationMasterSecretKey,
|
||||
"masterSecretName": constants.ConstellationMasterSecretStoreName,
|
||||
},
|
||||
"join-service": map[string]any{
|
||||
"csp": i.csp.String(),
|
||||
|
@ -468,7 +467,7 @@ func (i *ChartLoader) loadConstellationServicesValues() (map[string]any, error)
|
|||
// extendConstellationServicesValues extends the given values map by some values depending on user input.
|
||||
// Values set inside this function are only applied during init, not during upgrade.
|
||||
func extendConstellationServicesValues(
|
||||
in map[string]any, cfg *config.Config, masterSecret, salt []byte, maaURL string,
|
||||
in map[string]any, cfg *config.Config, masterSecret, salt []byte,
|
||||
) error {
|
||||
keyServiceValues, ok := in["key-service"].(map[string]any)
|
||||
if !ok {
|
||||
|
@ -481,41 +480,25 @@ func extendConstellationServicesValues(
|
|||
if !ok {
|
||||
return errors.New("invalid join-service values")
|
||||
}
|
||||
joinServiceVals["attestationVariant"] = cfg.AttestationVariant
|
||||
joinServiceVals["attestationVariant"] = cfg.GetAttestationConfig().GetVariant().String()
|
||||
|
||||
// measurements are updated separately during upgrade,
|
||||
// attestation config is updated separately during upgrade,
|
||||
// so we only set them in Helm during init.
|
||||
measurementsJSON, err := json.Marshal(cfg.GetMeasurements())
|
||||
attestationConfigJSON, err := json.Marshal(cfg.GetAttestationConfig())
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshalling measurements: %w", err)
|
||||
}
|
||||
joinServiceVals["measurements"] = string(measurementsJSON)
|
||||
joinServiceVals["attestationConfig"] = string(attestationConfigJSON)
|
||||
|
||||
verifyServiceVals, ok := in["verification-service"].(map[string]any)
|
||||
if !ok {
|
||||
return errors.New("invalid verification-service values")
|
||||
}
|
||||
verifyServiceVals["attestationVariant"] = cfg.AttestationVariant
|
||||
verifyServiceVals["attestationVariant"] = cfg.GetAttestationConfig().GetVariant().String()
|
||||
|
||||
csp := cfg.GetProvider()
|
||||
switch csp {
|
||||
case cloudprovider.Azure:
|
||||
joinServiceVals, ok := in["join-service"].(map[string]any)
|
||||
if !ok {
|
||||
return errors.New("invalid join-service values")
|
||||
}
|
||||
|
||||
idKeyCfg := config.SNPFirmwareSignerConfig{
|
||||
AcceptedKeyDigests: cfg.IDKeyDigests(),
|
||||
EnforcementPolicy: cfg.IDKeyDigestPolicy(),
|
||||
MAAURL: maaURL,
|
||||
}
|
||||
marshalledCfg, err := json.Marshal(idKeyCfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshalling id key digest config: %w", err)
|
||||
}
|
||||
joinServiceVals["idKeyConfig"] = string(marshalledCfg)
|
||||
|
||||
in["azure"] = map[string]any{
|
||||
"deployCSIDriver": cfg.DeployCSIDriver(),
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ import (
|
|||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||
"github.com/edgelesssys/constellation/v2/internal/deploy/helm"
|
||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||
)
|
||||
|
||||
// TestLoad checks if the serialized format that Load returns correctly preserves the dependencies of the loaded chart.
|
||||
|
@ -40,7 +39,7 @@ func TestLoad(t *testing.T) {
|
|||
|
||||
config := &config.Config{Provider: config.ProviderConfig{GCP: &config.GCPConfig{}}}
|
||||
chartLoader := ChartLoader{csp: config.GetProvider()}
|
||||
release, err := chartLoader.Load(config, true, []byte("secret"), []byte("salt"), "https://192.0.2.1:8080/maa")
|
||||
release, err := chartLoader.Load(config, true, []byte("secret"), []byte("salt"))
|
||||
require.NoError(err)
|
||||
|
||||
var helmReleases helm.Releases
|
||||
|
@ -63,21 +62,25 @@ func TestConstellationServices(t *testing.T) {
|
|||
}{
|
||||
"AWS": {
|
||||
config: &config.Config{
|
||||
AttestationVariant: variant.AWSNitroTPM{}.String(),
|
||||
Provider: config.ProviderConfig{AWS: &config.AWSConfig{}},
|
||||
Provider: config.ProviderConfig{AWS: &config.AWSConfig{}},
|
||||
Attestation: config.AttestationConfig{AWSNitroTPM: &config.AWSNitroTPM{
|
||||
Measurements: measurements.M{1: measurements.WithAllBytes(0xAA, measurements.Enforce)},
|
||||
}},
|
||||
},
|
||||
valuesModifier: prepareAWSValues,
|
||||
ccmImage: "ccmImageForAWS",
|
||||
},
|
||||
"Azure": {
|
||||
config: &config.Config{
|
||||
AttestationVariant: variant.AzureSEVSNP{}.String(),
|
||||
Provider: config.ProviderConfig{Azure: &config.AzureConfig{
|
||||
DeployCSIDriver: toPtr(true),
|
||||
EnforceIDKeyDigest: idkeydigest.Equal,
|
||||
IDKeyDigest: [][]byte{
|
||||
{0xba, 0xaa, 0xaa, 0xad, 0xba, 0xaa, 0xaa, 0xad, 0xba, 0xaa, 0xaa, 0xad, 0xba, 0xaa, 0xaa, 0xad, 0xba, 0xaa, 0xaa, 0xad, 0xba, 0xaa, 0xaa, 0xad, 0xba, 0xaa, 0xaa, 0xad, 0xba, 0xaa, 0xaa, 0xad},
|
||||
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa},
|
||||
DeployCSIDriver: toPtr(true),
|
||||
}},
|
||||
Attestation: config.AttestationConfig{AzureSEVSNP: &config.AzureSEVSNP{
|
||||
Measurements: measurements.M{1: measurements.WithAllBytes(0xAA, measurements.Enforce)},
|
||||
FirmwareSignerConfig: config.SNPFirmwareSignerConfig{
|
||||
AcceptedKeyDigests: idkeydigest.List{bytes.Repeat([]byte{0xAA}, 32)},
|
||||
EnforcementPolicy: idkeydigest.MAAFallback,
|
||||
MAAURL: "https://192.0.2.1:8080/maa",
|
||||
},
|
||||
}},
|
||||
},
|
||||
|
@ -88,26 +91,32 @@ func TestConstellationServices(t *testing.T) {
|
|||
},
|
||||
"GCP": {
|
||||
config: &config.Config{
|
||||
AttestationVariant: variant.GCPSEVES{}.String(),
|
||||
Provider: config.ProviderConfig{GCP: &config.GCPConfig{
|
||||
DeployCSIDriver: toPtr(true),
|
||||
}},
|
||||
Attestation: config.AttestationConfig{GCPSEVES: &config.GCPSEVES{
|
||||
Measurements: measurements.M{1: measurements.WithAllBytes(0xAA, measurements.Enforce)},
|
||||
}},
|
||||
},
|
||||
valuesModifier: prepareGCPValues,
|
||||
ccmImage: "ccmImageForGCP",
|
||||
},
|
||||
"OpenStack": {
|
||||
config: &config.Config{
|
||||
AttestationVariant: variant.QEMUVTPM{}.String(),
|
||||
Provider: config.ProviderConfig{OpenStack: &config.OpenStackConfig{}},
|
||||
Provider: config.ProviderConfig{OpenStack: &config.OpenStackConfig{}},
|
||||
Attestation: config.AttestationConfig{QEMUVTPM: &config.QEMUVTPM{
|
||||
Measurements: measurements.M{1: measurements.WithAllBytes(0xAA, measurements.Enforce)},
|
||||
}},
|
||||
},
|
||||
valuesModifier: prepareOpenStackValues,
|
||||
ccmImage: "ccmImageForOpenStack",
|
||||
},
|
||||
"QEMU": {
|
||||
config: &config.Config{
|
||||
AttestationVariant: variant.QEMUVTPM{}.String(),
|
||||
Provider: config.ProviderConfig{QEMU: &config.QEMUConfig{}},
|
||||
Provider: config.ProviderConfig{QEMU: &config.QEMUConfig{}},
|
||||
Attestation: config.AttestationConfig{QEMUVTPM: &config.QEMUVTPM{
|
||||
Measurements: measurements.M{1: measurements.WithAllBytes(0xAA, measurements.Enforce)},
|
||||
}},
|
||||
},
|
||||
valuesModifier: prepareQEMUValues,
|
||||
},
|
||||
|
@ -133,7 +142,7 @@ func TestConstellationServices(t *testing.T) {
|
|||
require.NoError(err)
|
||||
values, err := chartLoader.loadConstellationServicesValues()
|
||||
require.NoError(err)
|
||||
err = extendConstellationServicesValues(values, tc.config, []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), "https://192.0.2.1:8080/maa")
|
||||
err = extendConstellationServicesValues(values, tc.config, []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
|
||||
require.NoError(err)
|
||||
|
||||
options := chartutil.ReleaseOptions{
|
||||
|
@ -313,12 +322,7 @@ func prepareAWSValues(values map[string]any) error {
|
|||
if !ok {
|
||||
return errors.New("missing 'join-service' key")
|
||||
}
|
||||
m := measurements.M{1: measurements.WithAllBytes(0xAA, false)}
|
||||
mJSON, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
joinVals["measurements"] = string(mJSON)
|
||||
|
||||
joinVals["measurementSalt"] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
|
||||
ccmVals, ok := values["ccm"].(map[string]any)
|
||||
|
@ -347,13 +351,7 @@ func prepareAzureValues(values map[string]any) error {
|
|||
if !ok {
|
||||
return errors.New("missing 'join-service' key")
|
||||
}
|
||||
joinVals["idkeydigests"] = "[\"baaaaaadbaaaaaadbaaaaaadbaaaaaadbaaaaaadbaaaaaadbaaaaaadbaaaaaad\", \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"]"
|
||||
m := measurements.M{1: measurements.WithAllBytes(0xAA, false)}
|
||||
mJSON, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
joinVals["measurements"] = string(mJSON)
|
||||
|
||||
joinVals["measurementSalt"] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
|
||||
ccmVals, ok := values["ccm"].(map[string]any)
|
||||
|
@ -459,14 +457,6 @@ func prepareGCPValues(values map[string]any) error {
|
|||
return errors.New("missing 'join-service' key")
|
||||
}
|
||||
|
||||
m := measurements.M{
|
||||
1: measurements.WithAllBytes(0xAA, measurements.Enforce),
|
||||
}
|
||||
mJSON, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
joinVals["measurements"] = string(mJSON)
|
||||
joinVals["measurementSalt"] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
|
||||
ccmVals, ok := values["ccm"].(map[string]any)
|
||||
|
@ -535,12 +525,7 @@ func prepareOpenStackValues(values map[string]any) error {
|
|||
if !ok {
|
||||
return errors.New("missing 'join-service' key")
|
||||
}
|
||||
m := measurements.M{1: measurements.WithAllBytes(0xAA, measurements.Enforce)}
|
||||
mJSON, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
joinVals["measurements"] = string(mJSON)
|
||||
|
||||
joinVals["measurementSalt"] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
|
||||
ccmVals, ok := values["ccm"].(map[string]any)
|
||||
|
@ -570,12 +555,7 @@ func prepareQEMUValues(values map[string]any) error {
|
|||
if !ok {
|
||||
return errors.New("missing 'join-service' key")
|
||||
}
|
||||
m := measurements.M{1: measurements.WithAllBytes(0xAA, measurements.Enforce)}
|
||||
mJSON, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
joinVals["measurements"] = string(mJSON)
|
||||
|
||||
joinVals["measurementSalt"] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
|
||||
verificationVals, ok := values["verification-service"].(map[string]any)
|
||||
|
|
|
@ -4,6 +4,6 @@ metadata:
|
|||
name: join-config
|
||||
namespace: testNamespace
|
||||
data:
|
||||
measurements: "{\"1\":{\"expected\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"warnOnly\":false}}"
|
||||
attestationConfig: "{\"measurements\":{\"1\":{\"expected\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"warnOnly\":false}}}"
|
||||
binaryData:
|
||||
measurementSalt: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
|
|
|
@ -47,11 +47,6 @@ spec:
|
|||
- name: config
|
||||
projected:
|
||||
sources:
|
||||
- configMap:
|
||||
items:
|
||||
- key: measurements
|
||||
path: measurements
|
||||
name: join-config
|
||||
- secret:
|
||||
items:
|
||||
- key: mastersecret
|
||||
|
|
|
@ -4,7 +4,6 @@ metadata:
|
|||
name: join-config
|
||||
namespace: testNamespace
|
||||
data:
|
||||
measurements: "{\"1\":{\"expected\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"warnOnly\":false}}"
|
||||
idKeyConfig: "{\"acceptedKeyDigests\":[\"baaaaaadbaaaaaadbaaaaaadbaaaaaadbaaaaaadbaaaaaadbaaaaaadbaaaaaad\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"],\"enforcementPolicy\":\"Equal\",\"maaURL\":\"https://192.0.2.1:8080/maa\"}"
|
||||
attestationConfig: "{\"measurements\":{\"1\":{\"expected\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"warnOnly\":false}},\"bootloaderVersion\":0,\"teeVersion\":0,\"snpVersion\":0,\"microcodeVersion\":0,\"firmwareSignerConfig\":{\"acceptedKeyDigests\":[\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"],\"enforcementPolicy\":\"MAAFallback\",\"maaURL\":\"https://192.0.2.1:8080/maa\"},\"amdRootKey\":\"-----BEGIN CERTIFICATE-----\\n-----END CERTIFICATE-----\\n\"}"
|
||||
binaryData:
|
||||
measurementSalt: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
|
|
|
@ -47,11 +47,6 @@ spec:
|
|||
- name: config
|
||||
projected:
|
||||
sources:
|
||||
- configMap:
|
||||
items:
|
||||
- key: measurements
|
||||
path: measurements
|
||||
name: join-config
|
||||
- secret:
|
||||
items:
|
||||
- key: mastersecret
|
||||
|
|
|
@ -4,6 +4,6 @@ metadata:
|
|||
name: join-config
|
||||
namespace: testNamespace
|
||||
data:
|
||||
measurements: "{\"1\":{\"expected\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"warnOnly\":false}}"
|
||||
attestationConfig: "{\"measurements\":{\"1\":{\"expected\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"warnOnly\":false}}}"
|
||||
binaryData:
|
||||
measurementSalt: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
|
|
|
@ -47,11 +47,6 @@ spec:
|
|||
- name: config
|
||||
projected:
|
||||
sources:
|
||||
- configMap:
|
||||
items:
|
||||
- key: measurements
|
||||
path: measurements
|
||||
name: join-config
|
||||
- secret:
|
||||
items:
|
||||
- key: mastersecret
|
||||
|
|
|
@ -4,6 +4,6 @@ metadata:
|
|||
name: join-config
|
||||
namespace: testNamespace
|
||||
data:
|
||||
measurements: "{\"1\":{\"expected\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"warnOnly\":false}}"
|
||||
attestationConfig: "{\"measurements\":{\"1\":{\"expected\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"warnOnly\":false}}}"
|
||||
binaryData:
|
||||
measurementSalt: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
|
|
|
@ -47,11 +47,6 @@ spec:
|
|||
- name: config
|
||||
projected:
|
||||
sources:
|
||||
- configMap:
|
||||
items:
|
||||
- key: measurements
|
||||
path: measurements
|
||||
name: join-config
|
||||
- secret:
|
||||
items:
|
||||
- key: mastersecret
|
||||
|
|
|
@ -4,6 +4,6 @@ metadata:
|
|||
name: join-config
|
||||
namespace: testNamespace
|
||||
data:
|
||||
measurements: "{\"1\":{\"expected\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"warnOnly\":false}}"
|
||||
attestationConfig: "{\"measurements\":{\"1\":{\"expected\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"warnOnly\":false}}}"
|
||||
binaryData:
|
||||
measurementSalt: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
|
|
|
@ -47,11 +47,6 @@ spec:
|
|||
- name: config
|
||||
projected:
|
||||
sources:
|
||||
- configMap:
|
||||
items:
|
||||
- key: measurements
|
||||
path: measurements
|
||||
name: join-config
|
||||
- secret:
|
||||
items:
|
||||
- key: mastersecret
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue