From 620436626b10f5536bb8d873c65726f759ddb006 Mon Sep 17 00:00:00 2001 From: Leonard Cohnen Date: Wed, 4 Jan 2023 23:28:24 +0100 Subject: [PATCH] operator: add cluster version to nodeversion --- .../crds/nodeversion-crd.yaml | 10 ++++--- .../api/v1alpha1/nodeversion_types.go | 2 ++ .../update.edgeless.systems_nodeversions.yaml | 4 +++ .../internal/deploy/deploy.go | 26 +++++++++---------- .../internal/deploy/deploy_test.go | 8 ++++++ 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/cli/internal/helm/charts/edgeless/operators/charts/constellation-operator/crds/nodeversion-crd.yaml b/cli/internal/helm/charts/edgeless/operators/charts/constellation-operator/crds/nodeversion-crd.yaml index e45b88e46..90a07f684 100644 --- a/cli/internal/helm/charts/edgeless/operators/charts/constellation-operator/crds/nodeversion-crd.yaml +++ b/cli/internal/helm/charts/edgeless/operators/charts/constellation-operator/crds/nodeversion-crd.yaml @@ -16,7 +16,7 @@ spec: - name: v1alpha1 schema: openAPIV3Schema: - description: NodeVersion is the Schema for the nodeimages API. + description: NodeVersion is the Schema for the nodeversions API. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation @@ -31,7 +31,7 @@ spec: metadata: type: object spec: - description: NodeVersionSpec defines the desired state of NodeImage. + description: NodeVersionSpec defines the desired state of NodeVersion. properties: image: description: ImageReference is the image to use for all nodes. @@ -40,13 +40,17 @@ spec: description: ImageVersion is the CSP independent version of the image to use for all nodes. type: string + kubernetesClusterVersion: + description: KubernetesClusterVersion is the advertised Kubernetes + version of the cluster. + type: string kubernetesComponentsReference: description: KubernetesComponentsReference is a reference to the ConfigMap containing the Kubernetes components to use for all nodes. type: string type: object status: - description: NodeVersionStatus defines the observed state of NodeImage. + description: NodeVersionStatus defines the observed state of NodeVersion. properties: budget: description: Budget is the amount of extra nodes that can be created diff --git a/operators/constellation-node-operator/api/v1alpha1/nodeversion_types.go b/operators/constellation-node-operator/api/v1alpha1/nodeversion_types.go index 3bfa8cf06..21150ec0f 100644 --- a/operators/constellation-node-operator/api/v1alpha1/nodeversion_types.go +++ b/operators/constellation-node-operator/api/v1alpha1/nodeversion_types.go @@ -19,6 +19,8 @@ type NodeVersionSpec struct { ImageVersion string `json:"imageVersion,omitempty"` // KubernetesComponentsReference is a reference to the ConfigMap containing the Kubernetes components to use for all nodes. KubernetesComponentsReference string `json:"kubernetesComponentsReference,omitempty"` + // KubernetesClusterVersion is the advertised Kubernetes version of the cluster. + KubernetesClusterVersion string `json:"kubernetesClusterVersion,omitempty"` } // NodeVersionStatus defines the observed state of NodeVersion. diff --git a/operators/constellation-node-operator/config/crd/bases/update.edgeless.systems_nodeversions.yaml b/operators/constellation-node-operator/config/crd/bases/update.edgeless.systems_nodeversions.yaml index b98a50875..6a99cd144 100644 --- a/operators/constellation-node-operator/config/crd/bases/update.edgeless.systems_nodeversions.yaml +++ b/operators/constellation-node-operator/config/crd/bases/update.edgeless.systems_nodeversions.yaml @@ -42,6 +42,10 @@ spec: description: ImageVersion is the CSP independent version of the image to use for all nodes. type: string + kubernetesClusterVersion: + description: KubernetesClusterVersion is the advertised Kubernetes + version of the cluster. + type: string kubernetesComponentsReference: description: KubernetesComponentsReference is a reference to the ConfigMap containing the Kubernetes components to use for all nodes. diff --git a/operators/constellation-node-operator/internal/deploy/deploy.go b/operators/constellation-node-operator/internal/deploy/deploy.go index 3a8b819e0..64dd0d8a2 100644 --- a/operators/constellation-node-operator/internal/deploy/deploy.go +++ b/operators/constellation-node-operator/internal/deploy/deploy.go @@ -13,6 +13,7 @@ import ( "fmt" "strings" + mainconstants "github.com/edgelesssys/constellation/v2/internal/constants" updatev1alpha1 "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/api/v1alpha1" "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/internal/constants" corev1 "k8s.io/api/core/v1" @@ -113,7 +114,7 @@ func createAutoscalingStrategy(ctx context.Context, k8sClient client.Writer, pro // createNodeVersion creates the initial nodeversion resource if it does not exist yet. func createNodeVersion(ctx context.Context, k8sClient client.Client, imageReference, imageVersion string) error { - k8sComponentsRef, err := findLatestK8sComponentsConfigMap(ctx, k8sClient) + latestComponentCM, err := findLatestK8sComponentsConfigMap(ctx, k8sClient) if err != nil { return fmt.Errorf("finding latest k8s-components configmap: %w", err) } @@ -125,7 +126,8 @@ func createNodeVersion(ctx context.Context, k8sClient client.Client, imageRefere Spec: updatev1alpha1.NodeVersionSpec{ ImageReference: imageReference, ImageVersion: imageVersion, - KubernetesComponentsReference: k8sComponentsRef, + KubernetesComponentsReference: latestComponentCM.Name, + KubernetesClusterVersion: latestComponentCM.Data[mainconstants.K8sVersionFieldName], }, }) if k8sErrors.IsAlreadyExists(err) { @@ -138,31 +140,29 @@ func createNodeVersion(ctx context.Context, k8sClient client.Client, imageRefere // findLatestK8sComponentsConfigMap finds most recently created k8s-components configmap in the kube-system namespace. // It returns an error if there is no or multiple configmaps matching the prefix "k8s-components". -func findLatestK8sComponentsConfigMap(ctx context.Context, k8sClient client.Client) (string, error) { +func findLatestK8sComponentsConfigMap(ctx context.Context, k8sClient client.Client) (corev1.ConfigMap, error) { var configMaps corev1.ConfigMapList err := k8sClient.List(ctx, &configMaps, client.InNamespace("kube-system")) if err != nil { - return "", fmt.Errorf("listing configmaps: %w", err) + return corev1.ConfigMap{}, fmt.Errorf("listing configmaps: %w", err) } // collect all k8s-components configmaps - componentConfigMaps := make(map[string]time.Time) + componentConfigMaps := []corev1.ConfigMap{} for _, configMap := range configMaps.Items { if strings.HasPrefix(configMap.Name, "k8s-components") { - componentConfigMaps[configMap.Name] = configMap.CreationTimestamp.Time + componentConfigMaps = append(componentConfigMaps, configMap) } } if len(componentConfigMaps) == 0 { - return "", fmt.Errorf("no configmaps found") + return corev1.ConfigMap{}, fmt.Errorf("no configmaps found") } // find latest configmap - var latestConfigMap string - var latestTime time.Time - for configMap, creationTime := range componentConfigMaps { - if creationTime.After(latestTime) { - latestConfigMap = configMap - latestTime = creationTime + var latestConfigMap corev1.ConfigMap + for _, cm := range componentConfigMaps { + if cm.CreationTimestamp.After(latestConfigMap.CreationTimestamp.Time) { + latestConfigMap = cm } } return latestConfigMap, nil diff --git a/operators/constellation-node-operator/internal/deploy/deploy_test.go b/operators/constellation-node-operator/internal/deploy/deploy_test.go index 373fc89b8..470c47d75 100644 --- a/operators/constellation-node-operator/internal/deploy/deploy_test.go +++ b/operators/constellation-node-operator/internal/deploy/deploy_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + mainconstants "github.com/edgelesssys/constellation/v2/internal/constants" updatev1alpha1 "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/api/v1alpha1" "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/internal/constants" "github.com/stretchr/testify/assert" @@ -184,6 +185,7 @@ func TestCreateAutoscalingStrategy(t *testing.T) { func TestCreateNodeVersion(t *testing.T) { k8sComponentsReference := "k8s-components-sha256-reference" + k8sClusterVersion := "1.20.0" testCases := map[string]struct { createErr error existingNodeVersion *updatev1alpha1.NodeVersion @@ -200,6 +202,7 @@ func TestCreateNodeVersion(t *testing.T) { ImageReference: "image-reference", ImageVersion: "image-version", KubernetesComponentsReference: k8sComponentsReference, + KubernetesClusterVersion: k8sClusterVersion, }, }, }, @@ -218,6 +221,7 @@ func TestCreateNodeVersion(t *testing.T) { ImageReference: "image-reference2", ImageVersion: "image-version2", KubernetesComponentsReference: "components-reference2", + KubernetesClusterVersion: "cluster-version2", }, }, wantNodeVersion: &updatev1alpha1.NodeVersion{ @@ -229,6 +233,7 @@ func TestCreateNodeVersion(t *testing.T) { ImageReference: "image-reference2", ImageVersion: "image-version2", KubernetesComponentsReference: "components-reference2", + KubernetesClusterVersion: "cluster-version2", }, }, }, @@ -247,6 +252,9 @@ func TestCreateNodeVersion(t *testing.T) { Name: k8sComponentsReference, CreationTimestamp: metav1.Time{Time: time.Unix(1, 0)}, }, + Data: map[string]string{ + mainconstants.K8sVersionFieldName: k8sClusterVersion, + }, }, }, }