diff --git a/bazel/toolchains/go_module_deps.bzl b/bazel/toolchains/go_module_deps.bzl index 83378c9f1..8dcf0f520 100644 --- a/bazel/toolchains/go_module_deps.bzl +++ b/bazel/toolchains/go_module_deps.bzl @@ -4481,8 +4481,8 @@ def go_dependencies(): build_file_generation = "on", build_file_proto_mode = "disable_global", importpath = "github.com/rogpeppe/go-internal", - sum = "h1:3RPlVWzZ/PDqmVuf/FKHARG5EMid/tl7cv54Sw/QRVY=", - version = "v1.10.1-0.20230524175051-ec119421bb97", + sum = "h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=", + version = "v1.11.0", ) go_repository( name = "com_github_rs_cors", diff --git a/cli/internal/cmd/BUILD.bazel b/cli/internal/cmd/BUILD.bazel index a7488ee7a..f2f3d0bc7 100644 --- a/cli/internal/cmd/BUILD.bazel +++ b/cli/internal/cmd/BUILD.bazel @@ -89,6 +89,7 @@ go_library( "@com_github_google_go_sev_guest//kds", "@com_github_google_uuid//:uuid", "@com_github_mattn_go_isatty//:go-isatty", + "@com_github_rogpeppe_go_internal//diff", "@com_github_siderolabs_talos_pkg_machinery//config/encoder", "@com_github_spf13_afero//:afero", "@com_github_spf13_cobra//:cobra", diff --git a/cli/internal/cmd/status.go b/cli/internal/cmd/status.go index 9827f428a..6bf67ad87 100644 --- a/cli/internal/cmd/status.go +++ b/cli/internal/cmd/status.go @@ -89,8 +89,6 @@ func runStatus(cmd *cobra.Command, _ []string) error { return helmClient.Versions() } - stableClient := kubernetes.NewStableClient(kubeClient) - fetcher := attestationconfigapi.NewFetcher() conf, err := config.New(fileHandler, constants.ConfigFilename, fetcher, flags.force) var configValidationErr *config.ValidationError @@ -99,6 +97,10 @@ func runStatus(cmd *cobra.Command, _ []string) error { } variant := conf.GetAttestationConfig().GetVariant() + stableClient, err := kubernetes.NewStableClient(constants.AdminConfFilename) + if err != nil { + return fmt.Errorf("setting up stable client: %w", err) + } output, err := status(cmd.Context(), kubeClient, stableClient, helmVersionGetter, kubernetes.NewNodeVersionClient(unstructuredClient), variant) if err != nil { return fmt.Errorf("getting status: %w", err) @@ -121,18 +123,9 @@ func status( return "", fmt.Errorf("expected exactly one condition, got %d", len(nodeVersion.Status.Conditions)) } - // attestation version - joinConfig, err := cmClient.GetCurrentConfigMap(ctx, constants.JoinConfigMap) + attestationConfig, err := getAttestationConfig(ctx, cmClient, attestVariant) if err != nil { - return "", fmt.Errorf("getting current config map: %w", err) - } - rawAttestationConfig, ok := joinConfig.Data[constants.AttestationConfigFilename] - if !ok { - return "", fmt.Errorf("attestationConfig not found in %s", constants.JoinConfigMap) - } - attestationConfig, err := config.UnmarshalAttestationConfig([]byte(rawAttestationConfig), attestVariant) - if err != nil { - return "", fmt.Errorf("unmarshalling attestation config: %w", err) + return "", fmt.Errorf("getting attestation config: %w", err) } prettyYAML, err := yaml.Marshal(attestationConfig) if err != nil { @@ -157,6 +150,22 @@ func status( return statusOutput(targetVersions, serviceVersions, status, nodeVersion, string(prettyYAML)), nil } +func getAttestationConfig(ctx context.Context, cmClient configMapClient, attestVariant variant.Variant) (config.AttestationCfg, error) { + joinConfig, err := cmClient.GetCurrentConfigMap(ctx, constants.JoinConfigMap) + if err != nil { + return nil, fmt.Errorf("getting current config map: %w", err) + } + rawAttestationConfig, ok := joinConfig.Data[constants.AttestationConfigFilename] + if !ok { + return nil, fmt.Errorf("attestationConfig not found in %s", constants.JoinConfigMap) + } + attestationConfig, err := config.UnmarshalAttestationConfig([]byte(rawAttestationConfig), attestVariant) + if err != nil { + return nil, fmt.Errorf("unmarshalling attestation config: %w", err) + } + return attestationConfig, nil +} + // statusOutput creates the status cmd output string by formatting the received information. func statusOutput( targetVersions kubernetes.TargetVersions, serviceVersions fmt.Stringer, diff --git a/cli/internal/cmd/upgradeapply.go b/cli/internal/cmd/upgradeapply.go index 4ae2bb2e0..0a8f12ca6 100644 --- a/cli/internal/cmd/upgradeapply.go +++ b/cli/internal/cmd/upgradeapply.go @@ -28,8 +28,10 @@ import ( "github.com/edgelesssys/constellation/v2/internal/file" "github.com/edgelesssys/constellation/v2/internal/imagefetcher" "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/rogpeppe/go-internal/diff" "github.com/spf13/afero" "github.com/spf13/cobra" + "gopkg.in/yaml.v3" corev1 "k8s.io/api/core/v1" ) @@ -73,9 +75,19 @@ func runUpgradeApply(cmd *cobra.Command, _ []string) error { imagefetcher := imagefetcher.New() configFetcher := attestationconfigapi.NewFetcher() - applyCmd := upgradeApplyCmd{upgrader: upgrader, log: log, imageFetcher: imagefetcher, configFetcher: configFetcher} - return applyCmd.upgradeApply(cmd, fileHandler) + return applyCmd.upgradeApply(cmd, fileHandler, stableClientFactoryImpl) +} + +type stableClientFactory func(kubeconfigPath string) (getConfigMapper, error) + +// needed because StableClient returns the bigger kubernetes.StableInterface. +func stableClientFactoryImpl(kubeconfigPath string) (getConfigMapper, error) { + return kubernetes.NewStableClient(kubeconfigPath) +} + +type getConfigMapper interface { + GetCurrentConfigMap(ctx context.Context, name string) (*corev1.ConfigMap, error) } type upgradeApplyCmd struct { @@ -85,7 +97,7 @@ type upgradeApplyCmd struct { log debugLog } -func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command, fileHandler file.Handler) error { +func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command, fileHandler file.Handler, stableClientFactory stableClientFactory) error { flags, err := parseUpgradeApplyFlags(cmd) if err != nil { return fmt.Errorf("parsing flags: %w", err) @@ -112,7 +124,6 @@ func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command, fileHandler file.Hand } } } - if err := handleInvalidK8sPatchVersion(cmd, conf.KubernetesVersion, flags.yes); err != nil { return err } @@ -124,7 +135,11 @@ func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command, fileHandler file.Hand conf.UpdateMAAURL(idFile.AttestationURL) // If an image upgrade was just executed there won't be a diff. The function will return nil in that case. - if err := u.upgradeAttestConfigIfDiff(cmd, conf.GetAttestationConfig(), flags); err != nil { + stableClient, err := stableClientFactory(constants.AdminConfFilename) + if err != nil { + return fmt.Errorf("creating stable client: %w", err) + } + if err := u.upgradeAttestConfigIfDiff(cmd, stableClient, conf.GetAttestationConfig(), flags); err != nil { return fmt.Errorf("upgrading measurements: %w", err) } // not moving existing Terraform migrator because of planned apply refactor @@ -172,6 +187,20 @@ func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command, fileHandler file.Hand return nil } +func diffAttestationCfg(currentAttestationCfg config.AttestationCfg, newAttestationCfg config.AttestationCfg) (string, error) { + // cannot compare structs directly with go-cmp because of unexported fields in the attestation config + currentYml, err := yaml.Marshal(currentAttestationCfg) + if err != nil { + return "", fmt.Errorf("marshalling remote attestation config: %w", err) + } + newYml, err := yaml.Marshal(newAttestationCfg) + if err != nil { + return "", fmt.Errorf("marshalling local attestation config: %w", err) + } + diff := string(diff.Diff("current", currentYml, "new", newYml)) + return diff, nil +} + func getImage(ctx context.Context, conf *config.Config, fetcher imageFetcher) (string, error) { // Fetch variables to execute Terraform script with provider := conf.GetProvider() @@ -290,8 +319,8 @@ type imageFetcher interface { // upgradeAttestConfigIfDiff checks if the locally configured measurements are different from the cluster's measurements. // If so the function will ask the user to confirm (if --yes is not set) and upgrade the measurements only. -func (u *upgradeApplyCmd) upgradeAttestConfigIfDiff(cmd *cobra.Command, newConfig config.AttestationCfg, flags upgradeApplyFlags) error { - clusterAttestationConfig, _, err := u.upgrader.GetClusterAttestationConfig(cmd.Context(), newConfig.GetVariant()) +func (u *upgradeApplyCmd) upgradeAttestConfigIfDiff(cmd *cobra.Command, stableClient getConfigMapper, newConfig config.AttestationCfg, flags upgradeApplyFlags) error { + clusterAttestationConfig, err := getAttestationConfig(cmd.Context(), stableClient, newConfig.GetVariant()) if err != nil { return fmt.Errorf("getting cluster attestation config: %w", err) } @@ -305,7 +334,14 @@ func (u *upgradeApplyCmd) upgradeAttestConfigIfDiff(cmd *cobra.Command, newConfi } if !flags.yes { - ok, err := askToConfirm(cmd, "You are about to change your cluster's attestation config. Are you sure you want to continue?") + cmd.Println("The configured attestation config is different from the attestation config in the cluster.") + diffStr, err := diffAttestationCfg(clusterAttestationConfig, newConfig) + if err != nil { + return fmt.Errorf("diffing attestation configs: %w", err) + } + cmd.Println("The following changes will be applied to the attestation config:") + cmd.Println(diffStr) + ok, err := askToConfirm(cmd, "Are you sure you want to change your cluster's attestation config?") if err != nil { return fmt.Errorf("asking for confirmation: %w", err) } diff --git a/cli/internal/cmd/upgradeapply_test.go b/cli/internal/cmd/upgradeapply_test.go index c7e9a1bff..31dcb21dc 100644 --- a/cli/internal/cmd/upgradeapply_test.go +++ b/cli/internal/cmd/upgradeapply_test.go @@ -9,6 +9,7 @@ package cmd import ( "bytes" "context" + "encoding/json" "errors" "testing" "time" @@ -32,11 +33,12 @@ import ( func TestUpgradeApply(t *testing.T) { someErr := errors.New("some error") testCases := map[string]struct { - upgrader stubUpgrader - fetcher stubImageFetcher - wantErr bool - yesFlag bool - stdin string + upgrader stubUpgrader + fetcher stubImageFetcher + wantErr bool + yesFlag bool + stdin string + remoteAttestationCfg config.AttestationCfg // attestation config returned by the stub Kubernetes client }{ "success": { upgrader: stubUpgrader{currentConfig: config.DefaultForAzureSEVSNP()}, @@ -140,12 +142,19 @@ func TestUpgradeApply(t *testing.T) { handler := file.NewHandler(afero.NewMemMapFs()) cfg := defaultConfigWithExpectedMeasurements(t, config.Default(), cloudprovider.Azure) + + if tc.remoteAttestationCfg == nil { + tc.remoteAttestationCfg = fakeAttestationConfigFromCluster(cmd.Context(), t, cloudprovider.Azure) + } require.NoError(handler.WriteYAML(constants.ConfigFilename, cfg)) require.NoError(handler.WriteJSON(constants.ClusterIDsFilename, clusterid.File{})) upgrader := upgradeApplyCmd{upgrader: tc.upgrader, log: logger.NewTest(t), imageFetcher: tc.fetcher, configFetcher: stubAttestationFetcher{}} - err := upgrader.upgradeApply(cmd, handler) + stubStableClientFactory := func(_ string) (getConfigMapper, error) { + return stubGetConfigMap{tc.remoteAttestationCfg}, nil + } + err := upgrader.upgradeApply(cmd, handler, stubStableClientFactory) if tc.wantErr { assert.Error(err) } else { @@ -155,6 +164,21 @@ func TestUpgradeApply(t *testing.T) { } } +type stubGetConfigMap struct { + attestationCfg config.AttestationCfg +} + +func (s stubGetConfigMap) GetCurrentConfigMap(_ context.Context, _ string) (*corev1.ConfigMap, error) { + data, err := json.Marshal(s.attestationCfg) + if err != nil { + return nil, err + } + dataMap := map[string]string{ + constants.AttestationConfigFilename: string(data), + } + return &corev1.ConfigMap{Data: dataMap}, nil +} + type stubUpgrader struct { currentConfig config.AttestationCfg nodeVersionErr error @@ -222,3 +246,11 @@ func (f stubImageFetcher) FetchReference(_ context.Context, ) (string, error) { return "", f.fetchReferenceErr } + +func fakeAttestationConfigFromCluster(ctx context.Context, t *testing.T, provider cloudprovider.Provider) config.AttestationCfg { + cpCfg := defaultConfigWithExpectedMeasurements(t, config.Default(), provider) + // the cluster attestation config needs to have real version numbers that are translated from "latest" as defined in config.Default() + err := cpCfg.Attestation.AzureSEVSNP.FetchAndSetLatestVersionNumbers(ctx, stubAttestationFetcher{}, time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC)) + require.NoError(t, err) + return cpCfg.GetAttestationConfig() +} diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/key-service/templates/mastersecret.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/key-service/templates/mastersecret.yaml index aac8457c4..6741c4e60 100644 --- a/cli/internal/helm/charts/edgeless/constellation-services/charts/key-service/templates/mastersecret.yaml +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/key-service/templates/mastersecret.yaml @@ -1,6 +1,7 @@ apiVersion: v1 kind: Secret type: Opaque +immutable: true metadata: name: {{ .Values.masterSecretName | quote }} namespace: {{ .Release.Namespace }} diff --git a/cli/internal/helm/testdata/AWS/constellation-services/charts/key-service/templates/mastersecret.yaml b/cli/internal/helm/testdata/AWS/constellation-services/charts/key-service/templates/mastersecret.yaml index 231c4329f..6af9d8949 100644 --- a/cli/internal/helm/testdata/AWS/constellation-services/charts/key-service/templates/mastersecret.yaml +++ b/cli/internal/helm/testdata/AWS/constellation-services/charts/key-service/templates/mastersecret.yaml @@ -1,6 +1,7 @@ apiVersion: v1 kind: Secret type: Opaque +immutable: true metadata: name: constellation-mastersecret namespace: testNamespace diff --git a/cli/internal/helm/testdata/Azure/constellation-services/charts/key-service/templates/mastersecret.yaml b/cli/internal/helm/testdata/Azure/constellation-services/charts/key-service/templates/mastersecret.yaml index 231c4329f..6af9d8949 100644 --- a/cli/internal/helm/testdata/Azure/constellation-services/charts/key-service/templates/mastersecret.yaml +++ b/cli/internal/helm/testdata/Azure/constellation-services/charts/key-service/templates/mastersecret.yaml @@ -1,6 +1,7 @@ apiVersion: v1 kind: Secret type: Opaque +immutable: true metadata: name: constellation-mastersecret namespace: testNamespace diff --git a/cli/internal/helm/testdata/GCP/constellation-services/charts/key-service/templates/mastersecret.yaml b/cli/internal/helm/testdata/GCP/constellation-services/charts/key-service/templates/mastersecret.yaml index 231c4329f..6af9d8949 100644 --- a/cli/internal/helm/testdata/GCP/constellation-services/charts/key-service/templates/mastersecret.yaml +++ b/cli/internal/helm/testdata/GCP/constellation-services/charts/key-service/templates/mastersecret.yaml @@ -1,6 +1,7 @@ apiVersion: v1 kind: Secret type: Opaque +immutable: true metadata: name: constellation-mastersecret namespace: testNamespace diff --git a/cli/internal/helm/testdata/OpenStack/constellation-services/charts/key-service/templates/mastersecret.yaml b/cli/internal/helm/testdata/OpenStack/constellation-services/charts/key-service/templates/mastersecret.yaml index 231c4329f..6af9d8949 100644 --- a/cli/internal/helm/testdata/OpenStack/constellation-services/charts/key-service/templates/mastersecret.yaml +++ b/cli/internal/helm/testdata/OpenStack/constellation-services/charts/key-service/templates/mastersecret.yaml @@ -1,6 +1,7 @@ apiVersion: v1 kind: Secret type: Opaque +immutable: true metadata: name: constellation-mastersecret namespace: testNamespace diff --git a/cli/internal/helm/testdata/QEMU/constellation-services/charts/key-service/templates/mastersecret.yaml b/cli/internal/helm/testdata/QEMU/constellation-services/charts/key-service/templates/mastersecret.yaml index 231c4329f..6af9d8949 100644 --- a/cli/internal/helm/testdata/QEMU/constellation-services/charts/key-service/templates/mastersecret.yaml +++ b/cli/internal/helm/testdata/QEMU/constellation-services/charts/key-service/templates/mastersecret.yaml @@ -1,6 +1,7 @@ apiVersion: v1 kind: Secret type: Opaque +immutable: true metadata: name: constellation-mastersecret namespace: testNamespace diff --git a/cli/internal/kubernetes/kubernetes.go b/cli/internal/kubernetes/kubernetes.go index d39baea66..3e5082d0f 100644 --- a/cli/internal/kubernetes/kubernetes.go +++ b/cli/internal/kubernetes/kubernetes.go @@ -10,3 +10,72 @@ Package kubernetes provides functions to interact with a live cluster to the CLI Currently it is used to implement the status and upgrade commands. */ package kubernetes + +import ( + "context" + "fmt" + + "github.com/edgelesssys/constellation/v2/internal/constants" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" +) + +func newClient(kubeconfigPath string) (kubernetes.Interface, error) { + kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath) + if err != nil { + return nil, fmt.Errorf("building kubernetes config: %w", err) + } + + kubeClient, err := kubernetes.NewForConfig(kubeConfig) + if err != nil { + return nil, fmt.Errorf("setting up kubernetes client: %w", err) + } + return kubeClient, nil +} + +// StableInterface is an interface to interact with stable resources. +type StableInterface interface { + GetCurrentConfigMap(ctx context.Context, name string) (*corev1.ConfigMap, error) + UpdateConfigMap(ctx context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) + CreateConfigMap(ctx context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) + KubernetesVersion() (string, error) +} + +// NewStableClient returns a new StableClient. +func NewStableClient(kubeconfigPath string) (StableInterface, error) { + client, err := newClient(kubeconfigPath) + if err != nil { + return nil, err + } + return &stableClient{client}, nil +} + +type stableClient struct { + client kubernetes.Interface +} + +// GetCurrentConfigMap returns a ConfigMap given it's name. +func (u *stableClient) GetCurrentConfigMap(ctx context.Context, name string) (*corev1.ConfigMap, error) { + return u.client.CoreV1().ConfigMaps(constants.ConstellationNamespace).Get(ctx, name, metav1.GetOptions{}) +} + +// UpdateConfigMap updates the given ConfigMap. +func (u *stableClient) UpdateConfigMap(ctx context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) { + return u.client.CoreV1().ConfigMaps(constants.ConstellationNamespace).Update(ctx, configMap, metav1.UpdateOptions{}) +} + +// CreateConfigMap creates the given ConfigMap. +func (u *stableClient) CreateConfigMap(ctx context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) { + return u.client.CoreV1().ConfigMaps(constants.ConstellationNamespace).Create(ctx, configMap, metav1.CreateOptions{}) +} + +// KubernetesVersion returns the Kubernetes version of the cluster. +func (u *stableClient) KubernetesVersion() (string, error) { + serverVersion, err := u.client.Discovery().ServerVersion() + if err != nil { + return "", err + } + return serverVersion.GitVersion, nil +} diff --git a/cli/internal/kubernetes/upgrade.go b/cli/internal/kubernetes/upgrade.go index 932aaedf0..1ecb1ada8 100644 --- a/cli/internal/kubernetes/upgrade.go +++ b/cli/internal/kubernetes/upgrade.go @@ -42,7 +42,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" - "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/retry" kubeadmv1beta3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3" @@ -121,18 +120,17 @@ func NewUpgrader( upgradeID: upgradeID, } - kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath) + kubeClient, err := newClient(kubeConfigPath) if err != nil { - return nil, fmt.Errorf("building kubernetes config: %w", err) - } - - kubeClient, err := kubernetes.NewForConfig(kubeConfig) - if err != nil { - return nil, fmt.Errorf("setting up kubernetes client: %w", err) + return nil, err } u.stableInterface = &stableClient{client: kubeClient} // use unstructured client to avoid importing the operator packages + kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath) + if err != nil { + return nil, fmt.Errorf("building kubernetes config: %w", err) + } unstructuredClient, err := dynamic.NewForConfig(kubeConfig) if err != nil { return nil, fmt.Errorf("setting up custom resource client: %w", err) @@ -554,47 +552,6 @@ func upgradeInProgress(nodeVersion updatev1alpha1.NodeVersion) bool { return false } -// StableInterface is an interface to interact with stable resources. -type StableInterface interface { - GetCurrentConfigMap(ctx context.Context, name string) (*corev1.ConfigMap, error) - UpdateConfigMap(ctx context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) - CreateConfigMap(ctx context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) - KubernetesVersion() (string, error) -} - -// NewStableClient returns a new StableInterface. -func NewStableClient(client kubernetes.Interface) StableInterface { - return &stableClient{client: client} -} - -type stableClient struct { - client kubernetes.Interface -} - -// GetCurrentConfigMap returns a ConfigMap given it's name. -func (u *stableClient) GetCurrentConfigMap(ctx context.Context, name string) (*corev1.ConfigMap, error) { - return u.client.CoreV1().ConfigMaps(constants.ConstellationNamespace).Get(ctx, name, metav1.GetOptions{}) -} - -// UpdateConfigMap updates the given ConfigMap. -func (u *stableClient) UpdateConfigMap(ctx context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) { - return u.client.CoreV1().ConfigMaps(constants.ConstellationNamespace).Update(ctx, configMap, metav1.UpdateOptions{}) -} - -// CreateConfigMap creates the given ConfigMap. -func (u *stableClient) CreateConfigMap(ctx context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) { - return u.client.CoreV1().ConfigMaps(constants.ConstellationNamespace).Create(ctx, configMap, metav1.CreateOptions{}) -} - -// KubernetesVersion returns the Kubernetes version of the cluster. -func (u *stableClient) KubernetesVersion() (string, error) { - serverVersion, err := u.client.Discovery().ServerVersion() - if err != nil { - return "", err - } - return serverVersion.GitVersion, nil -} - type helmInterface interface { Upgrade(ctx context.Context, config *config.Config, idFile clusterid.File, timeout time.Duration, allowDestructive, force bool, upgradeID string) error } diff --git a/cli/internal/kubernetes/upgrade_test.go b/cli/internal/kubernetes/upgrade_test.go index d00eded0b..3cbd6fdc1 100644 --- a/cli/internal/kubernetes/upgrade_test.go +++ b/cli/internal/kubernetes/upgrade_test.go @@ -38,7 +38,7 @@ import ( func TestUpgradeNodeVersion(t *testing.T) { someErr := errors.New("some error") testCases := map[string]struct { - stable *stubStableClient + stable *fakeStableClient conditions []metav1.Condition currentImageVersion string newImageReference string @@ -61,7 +61,7 @@ func TestUpgradeNodeVersion(t *testing.T) { }(), currentImageVersion: "v1.2.2", currentClusterVersion: versions.SupportedK8sVersions()[0], - stable: &stubStableClient{ + stable: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}`), }, @@ -77,7 +77,7 @@ func TestUpgradeNodeVersion(t *testing.T) { }(), currentImageVersion: "v1.2.2", currentClusterVersion: versions.SupportedK8sVersions()[0], - stable: &stubStableClient{ + stable: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}`), }, @@ -98,7 +98,7 @@ func TestUpgradeNodeVersion(t *testing.T) { }(), currentImageVersion: "v1.2.2", currentClusterVersion: versions.SupportedK8sVersions()[0], - stable: &stubStableClient{ + stable: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}`), }, @@ -119,7 +119,7 @@ func TestUpgradeNodeVersion(t *testing.T) { }(), currentImageVersion: "v1.2.2", currentClusterVersion: versions.SupportedK8sVersions()[0], - stable: &stubStableClient{}, + stable: &fakeStableClient{}, wantErr: true, assertCorrectError: func(t *testing.T, err error) bool { var upgradeErr *compatibility.InvalidUpgradeError @@ -139,7 +139,7 @@ func TestUpgradeNodeVersion(t *testing.T) { }}, currentImageVersion: "v1.2.2", currentClusterVersion: versions.SupportedK8sVersions()[0], - stable: &stubStableClient{}, + stable: &fakeStableClient{}, wantErr: true, assertCorrectError: func(t *testing.T, err error) bool { return assert.ErrorIs(t, err, ErrInProgress) @@ -158,7 +158,7 @@ func TestUpgradeNodeVersion(t *testing.T) { }}, currentImageVersion: "v1.2.2", currentClusterVersion: versions.SupportedK8sVersions()[0], - stable: &stubStableClient{}, + stable: &fakeStableClient{}, force: true, wantUpdate: true, }, @@ -184,7 +184,7 @@ func TestUpgradeNodeVersion(t *testing.T) { newImageReference: "path/to/image:v1.4.2", currentImageVersion: "v1.2.2", currentClusterVersion: versions.SupportedK8sVersions()[0], - stable: &stubStableClient{ + stable: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}`), }, @@ -206,7 +206,7 @@ func TestUpgradeNodeVersion(t *testing.T) { newImageReference: "path/to/image:v1.4.2", currentImageVersion: "v1.2.2", currentClusterVersion: versions.SupportedK8sVersions()[0], - stable: &stubStableClient{ + stable: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}`), }, @@ -224,7 +224,7 @@ func TestUpgradeNodeVersion(t *testing.T) { currentImageVersion: "v1.2.2", currentClusterVersion: versions.SupportedK8sVersions()[0], badImageVersion: "v3.2.1", - stable: &stubStableClient{ + stable: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}`), }, @@ -245,7 +245,7 @@ func TestUpgradeNodeVersion(t *testing.T) { }(), currentImageVersion: "v1.2.2", currentClusterVersion: versions.SupportedK8sVersions()[0], - stable: &stubStableClient{ + stable: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}`), }, @@ -266,7 +266,7 @@ func TestUpgradeNodeVersion(t *testing.T) { }(), currentImageVersion: "v1.2.2", currentClusterVersion: versions.SupportedK8sVersions()[0], - stable: &stubStableClient{ + stable: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}`), }, @@ -340,13 +340,13 @@ func TestUpgradeNodeVersion(t *testing.T) { func TestUpdateMeasurements(t *testing.T) { someErr := errors.New("error") testCases := map[string]struct { - updater *stubStableClient + updater *fakeStableClient newConfig config.AttestationCfg wantUpdate bool wantErr bool }{ "success": { - updater: &stubStableClient{ + updater: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"measurements":{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}}`), }, @@ -359,7 +359,7 @@ func TestUpdateMeasurements(t *testing.T) { wantUpdate: true, }, "measurements are the same": { - updater: &stubStableClient{ + updater: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"measurements":{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}}`), }, @@ -371,7 +371,7 @@ func TestUpdateMeasurements(t *testing.T) { }, }, "setting warnOnly to true is allowed": { - updater: &stubStableClient{ + updater: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"measurements":{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}}`), }, @@ -384,7 +384,7 @@ func TestUpdateMeasurements(t *testing.T) { wantUpdate: true, }, "setting warnOnly to false is allowed": { - updater: &stubStableClient{ + updater: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"measurements":{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":true}}}`), }, @@ -397,7 +397,7 @@ func TestUpdateMeasurements(t *testing.T) { wantUpdate: true, }, "getCurrent error": { - updater: &stubStableClient{getErr: someErr}, + updater: &fakeStableClient{getErr: someErr}, newConfig: &config.GCPSEVES{ Measurements: measurements.M{ 0: measurements.WithAllBytes(0xBB, measurements.Enforce, measurements.PCRMeasurementLength), @@ -406,7 +406,7 @@ func TestUpdateMeasurements(t *testing.T) { wantErr: true, }, "update error": { - updater: &stubStableClient{ + updater: &fakeStableClient{ configMaps: map[string]*corev1.ConfigMap{ constants.JoinConfigMap: newJoinConfigMap(`{"measurements":{"0":{"expected":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","warnOnly":false}}}`), }, @@ -616,7 +616,7 @@ func (u *stubDynamicClient) Update(_ context.Context, updatedObject *unstructure return u.updatedObject, u.updateErr } -type stubStableClient struct { +type fakeStableClient struct { configMaps map[string]*corev1.ConfigMap updatedConfigMaps map[string]*corev1.ConfigMap k8sVersion string @@ -626,11 +626,11 @@ type stubStableClient struct { k8sErr error } -func (s *stubStableClient) GetCurrentConfigMap(_ context.Context, name string) (*corev1.ConfigMap, error) { +func (s *fakeStableClient) GetCurrentConfigMap(_ context.Context, name string) (*corev1.ConfigMap, error) { return s.configMaps[name], s.getErr } -func (s *stubStableClient) UpdateConfigMap(_ context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) { +func (s *fakeStableClient) UpdateConfigMap(_ context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) { if s.updatedConfigMaps == nil { s.updatedConfigMaps = map[string]*corev1.ConfigMap{} } @@ -638,7 +638,7 @@ func (s *stubStableClient) UpdateConfigMap(_ context.Context, configMap *corev1. return s.updatedConfigMaps[configMap.ObjectMeta.Name], s.updateErr } -func (s *stubStableClient) CreateConfigMap(_ context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) { +func (s *fakeStableClient) CreateConfigMap(_ context.Context, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) { if s.configMaps == nil { s.configMaps = map[string]*corev1.ConfigMap{} } @@ -646,7 +646,7 @@ func (s *stubStableClient) CreateConfigMap(_ context.Context, configMap *corev1. return s.configMaps[configMap.ObjectMeta.Name], s.createErr } -func (s *stubStableClient) KubernetesVersion() (string, error) { +func (s *fakeStableClient) KubernetesVersion() (string, error) { return s.k8sVersion, s.k8sErr } diff --git a/go.mod b/go.mod index 9b474d638..3b96adbc1 100644 --- a/go.mod +++ b/go.mod @@ -92,6 +92,7 @@ require ( github.com/mattn/go-isatty v0.0.19 github.com/microsoft/ApplicationInsights-Go v0.4.4 github.com/pkg/errors v0.9.1 + github.com/rogpeppe/go-internal v1.11.0 github.com/schollz/progressbar/v3 v3.13.1 github.com/siderolabs/talos/pkg/machinery v1.4.6 github.com/sigstore/rekor v1.2.2 diff --git a/go.sum b/go.sum index d9d52351f..61573d4df 100644 --- a/go.sum +++ b/go.sum @@ -916,7 +916,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rubenv/sql-migrate v1.3.1 h1:Vx+n4Du8X8VTYuXbhNxdEUoh6wiJERA0GlWocR5FrbA= github.com/rubenv/sql-migrate v1.3.1/go.mod h1:YzG/Vh82CwyhTFXy+Mf5ahAiiEOpAlHurg+23VEzcsk= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/hack/go.mod b/hack/go.mod index 0b2c9baa5..8614bb390 100644 --- a/hack/go.mod +++ b/hack/go.mod @@ -248,6 +248,7 @@ require ( github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect github.com/rivo/uniseg v0.4.4 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/rubenv/sql-migrate v1.3.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sassoftware/relic v7.2.1+incompatible // indirect diff --git a/hack/go.sum b/hack/go.sum index b1fbb4864..ecdc7c33a 100644 --- a/hack/go.sum +++ b/hack/go.sum @@ -869,7 +869,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rubenv/sql-migrate v1.3.1 h1:Vx+n4Du8X8VTYuXbhNxdEUoh6wiJERA0GlWocR5FrbA= github.com/rubenv/sql-migrate v1.3.1/go.mod h1:YzG/Vh82CwyhTFXy+Mf5ahAiiEOpAlHurg+23VEzcsk= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/operators/constellation-node-operator/go.sum b/operators/constellation-node-operator/go.sum index 5589671a7..911290e9b 100644 --- a/operators/constellation-node-operator/go.sum +++ b/operators/constellation-node-operator/go.sum @@ -297,7 +297,7 @@ github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+Pymzi github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=