mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-10-01 01:36:09 -04:00
cli: declare mastersecret as immutable and print attestationCfg diff in warning (#2167)
This commit is contained in:
parent
e97b2afc14
commit
70861ee8ad
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
immutable: true
|
||||
metadata:
|
||||
name: {{ .Values.masterSecretName | quote }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
@ -1,6 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
immutable: true
|
||||
metadata:
|
||||
name: constellation-mastersecret
|
||||
namespace: testNamespace
|
||||
|
@ -1,6 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
immutable: true
|
||||
metadata:
|
||||
name: constellation-mastersecret
|
||||
namespace: testNamespace
|
||||
|
@ -1,6 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
immutable: true
|
||||
metadata:
|
||||
name: constellation-mastersecret
|
||||
namespace: testNamespace
|
||||
|
@ -1,6 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
immutable: true
|
||||
metadata:
|
||||
name: constellation-mastersecret
|
||||
namespace: testNamespace
|
||||
|
@ -1,6 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
immutable: true
|
||||
metadata:
|
||||
name: constellation-mastersecret
|
||||
namespace: testNamespace
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
1
go.mod
1
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
|
||||
|
3
go.sum
3
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=
|
||||
|
@ -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
|
||||
|
@ -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=
|
||||
|
@ -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=
|
||||
|
Loading…
Reference in New Issue
Block a user