From b966f57a2fcd59b6eefdc00c5372387d61e4b2c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Wei=C3=9Fe?= <66256922+daniel-weisse@users.noreply.github.com> Date: Fri, 18 Nov 2022 10:05:02 +0100 Subject: [PATCH] AB#2554 GCP CSI driver deployment (#532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Allow enabling/disabling of CSI driver through config * Fix inconsistent namespace parsing * Deploy GCP CSI driver on init * Update invalid pod tolerations * Add generate script for CSI charts * Update generateCilium script Signed-off-by: Daniel Weiße --- CHANGELOG.md | 2 + cli/internal/cmd/init.go | 30 +- .../constellation-services/Chart.yaml | 10 + .../autoscaler/templates/rolebinding.yaml | 2 +- .../charts/cnm/templates/azure-daemonset.yaml | 3 +- .../charts/csi-azuredisk/Chart.yaml | 5 + .../charts/csi-azuredisk/values.yaml | 0 .../Chart.yaml | 5 + .../templates/cluster_setup.yaml | 308 ++++++++++++++++++ .../templates/controller.yaml | 175 ++++++++++ .../templates/node.yaml | 117 +++++++ .../templates/storageclass_default.yaml | 14 + .../templates/storageclass_integrity.yaml | 14 + .../templates/v1_csidriver.yaml | 7 + .../values.yaml | 36 ++ .../join-service/templates/configmap.yaml | 2 +- .../join-service/templates/daemonset.yaml | 5 +- .../charts/join-service/values.yaml | 2 - .../charts/kms/templates/daemonset.yaml | 3 +- .../charts/kms/values.yaml | 2 - .../constellation-services/values.yaml | 8 + cli/internal/helm/generateCilium.sh | 13 +- cli/internal/helm/loader.go | 108 +++--- cli/internal/helm/loader_test.go | 64 +++- .../autoscaler/templates/rolebinding.yaml | 2 +- .../charts/cnm/templates/azure-daemonset.yaml | 3 +- .../join-service/templates/configmap.yaml | 2 +- .../join-service/templates/daemonset.yaml | 5 +- .../charts/kms/templates/daemonset.yaml | 3 +- .../autoscaler/templates/rolebinding.yaml | 2 +- .../templates/cluster_setup.yaml | 297 +++++++++++++++++ .../templates/controller.yaml | 167 ++++++++++ .../templates/node.yaml | 110 +++++++ .../templates/storageclass_default.yaml | 12 + .../templates/storageclass_integrity.yaml | 12 + .../templates/v1_csidriver.yaml | 7 + .../join-service/templates/configmap.yaml | 2 +- .../join-service/templates/daemonset.yaml | 5 +- .../charts/kms/templates/daemonset.yaml | 3 +- .../join-service/templates/configmap.yaml | 2 +- .../join-service/templates/daemonset.yaml | 5 +- .../charts/kms/templates/daemonset.yaml | 3 +- cli/internal/helm/update-csi-charts.sh | 54 +++ internal/config/config.go | 55 +++- internal/config/config_doc.go | 76 +++-- 45 files changed, 1597 insertions(+), 165 deletions(-) create mode 100644 cli/internal/helm/charts/edgeless/constellation-services/charts/csi-azuredisk/Chart.yaml create mode 100644 cli/internal/helm/charts/edgeless/constellation-services/charts/csi-azuredisk/values.yaml create mode 100644 cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/Chart.yaml create mode 100644 cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/cluster_setup.yaml create mode 100644 cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/controller.yaml create mode 100644 cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/node.yaml create mode 100644 cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_default.yaml create mode 100644 cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_integrity.yaml create mode 100644 cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/v1_csidriver.yaml create mode 100644 cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/values.yaml create mode 100644 cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/cluster_setup.yaml create mode 100644 cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/controller.yaml create mode 100644 cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/node.yaml create mode 100644 cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_default.yaml create mode 100644 cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_integrity.yaml create mode 100644 cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/v1_csidriver.yaml create mode 100755 cli/internal/helm/update-csi-charts.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f40ea280..0b10e8925 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Environment variable `CONSTELL_AZURE_CLIENT_SECRET_VALUE` as an alternative way to provide the configuration value `provider.azure.clientSecretValue`. +- GCP CSI driver deployment during Constellation init + ### Changed diff --git a/cli/internal/cmd/init.go b/cli/internal/cmd/init.go index 317c02171..0b73eb1f0 100644 --- a/cli/internal/cmd/init.go +++ b/cli/internal/cmd/init.go @@ -117,7 +117,7 @@ func initialize(cmd *cobra.Command, newDialer func(validator *cloudcmd.Validator return fmt.Errorf("parsing or generating master secret from file %s: %w", flags.masterSecretPath, err) } helmLoader := helm.New(provider, k8sVersion) - helmDeployments, err := helmLoader.Load(provider, flags.conformance, masterSecret.Key, masterSecret.Salt, getEnforcedPCRs(provider, conf), getEnforceIDKeyDigest(provider, conf)) + helmDeployments, err := helmLoader.Load(conf, flags.conformance, masterSecret.Key, masterSecret.Salt) if err != nil { return fmt.Errorf("loading Helm charts: %w", err) } @@ -133,8 +133,8 @@ func initialize(cmd *cobra.Command, newDialer func(validator *cloudcmd.Validator CloudServiceAccountUri: serviceAccURI, KubernetesVersion: conf.KubernetesVersion, HelmDeployments: helmDeployments, - EnforcedPcrs: getEnforcedPCRs(provider, conf), - EnforceIdkeydigest: getEnforceIDKeyDigest(provider, conf), + EnforcedPcrs: conf.GetEnforcedPCRs(), + EnforceIdkeydigest: conf.EnforcesIDKeyDigest(), ConformanceMode: flags.conformance, } resp, err := initCall(cmd.Context(), newDialer(validator), idFile.IP, req) @@ -219,30 +219,6 @@ func writeRow(wr io.Writer, col1 string, col2 string) { fmt.Fprint(wr, col1, "\t", col2, "\n") } -func getEnforcedPCRs(provider cloudprovider.Provider, config *config.Config) []uint32 { - switch provider { - case cloudprovider.AWS: - return config.Provider.AWS.EnforcedMeasurements - case cloudprovider.Azure: - return config.Provider.Azure.EnforcedMeasurements - case cloudprovider.GCP: - return config.Provider.GCP.EnforcedMeasurements - case cloudprovider.QEMU: - return config.Provider.QEMU.EnforcedMeasurements - default: - return nil - } -} - -func getEnforceIDKeyDigest(provider cloudprovider.Provider, config *config.Config) bool { - switch provider { - case cloudprovider.Azure: - return *config.Provider.Azure.EnforceIDKeyDigest - default: - return false - } -} - // evalFlagArgs gets the flag values and does preprocessing of these values like // reading the content from file path flags and deriving other values from flag combinations. func evalFlagArgs(cmd *cobra.Command) (initFlags, error) { diff --git a/cli/internal/helm/charts/edgeless/constellation-services/Chart.yaml b/cli/internal/helm/charts/edgeless/constellation-services/Chart.yaml index 749ddcd3f..244b71f62 100644 --- a/cli/internal/helm/charts/edgeless/constellation-services/Chart.yaml +++ b/cli/internal/helm/charts/edgeless/constellation-services/Chart.yaml @@ -35,3 +35,13 @@ dependencies: - Azure - GCP - AWS + - name: gcp-compute-persistent-disk-csi-driver + version: 1.0.1 + condition: gcp.deployCSIDriver + tags: + - GCP + - name: csi-azuredisk + version: 1.0.1 + condition: azure.deployCSIDriver + tags: + - Azure diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/autoscaler/templates/rolebinding.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/autoscaler/templates/rolebinding.yaml index 6d1c2a273..ffc2beb9d 100644 --- a/cli/internal/helm/charts/edgeless/constellation-services/charts/autoscaler/templates/rolebinding.yaml +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/autoscaler/templates/rolebinding.yaml @@ -14,4 +14,4 @@ roleRef: subjects: - kind: ServiceAccount name: constellation-cluster-autoscaler - namespace: kube-system + namespace: {{ .Release.Namespace }} diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/cnm/templates/azure-daemonset.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/cnm/templates/azure-daemonset.yaml index a2da0d2d0..f9515b051 100644 --- a/cli/internal/helm/charts/edgeless/constellation-services/charts/cnm/templates/azure-daemonset.yaml +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/cnm/templates/azure-daemonset.yaml @@ -45,8 +45,7 @@ spec: operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/master - operator: Equal - value: "true" + operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/csi-azuredisk/Chart.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/csi-azuredisk/Chart.yaml new file mode 100644 index 000000000..3ce6b5d4d --- /dev/null +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/csi-azuredisk/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +appVersion: "v1.0.1" +description: Azure disk Container Storage Interface (CSI) Storage Plugin with on-node encryption support +name: csi-azuredisk +version: v1.0.1 diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/csi-azuredisk/values.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/csi-azuredisk/values.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/Chart.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/Chart.yaml new file mode 100644 index 000000000..667aa4434 --- /dev/null +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +version: 1.0.1 +appVersion: "v1.0.1" +description: GCP Compute Persistent Disk Container Storage Interface (CSI) Storage Plugin with on-node encryption support +name: gcp-compute-persistent-disk-csi-driver diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/cluster_setup.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/cluster_setup.yaml new file mode 100644 index 000000000..1310fff30 --- /dev/null +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/cluster_setup.yaml @@ -0,0 +1,308 @@ +##### Node Service Account, Roles, RoleBindings +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-gce-pd-node-sa + namespace: {{ .Release.Namespace }} + +--- + +##### Controller Service Account, Roles, Rolebindings +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-gce-pd-controller-sa + namespace: {{ .Release.Namespace }} + +--- + +# xref: https://github.com/kubernetes-csi/external-provisioner/blob/master/deploy/kubernetes/rbac.yaml +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-provisioner-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + # Access to volumeattachments is only needed when the CSI driver + # has the PUBLISH_UNPUBLISH_VOLUME controller capability. + # In that case, external-provisioner will watch volumeattachments + # to determine when it is safe to delete a volume. + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-controller-provisioner-binding +subjects: + - kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-gce-pd-provisioner-role + apiGroup: rbac.authorization.k8s.io + +--- + +# xref: https://github.com/kubernetes-csi/external-attacher/blob/master/deploy/kubernetes/rbac.yaml +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-attacher-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-controller-attacher-binding +subjects: + - kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-gce-pd-attacher-role + apiGroup: rbac.authorization.k8s.io + +--- + +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: csi-gce-pd-controller +value: 900000000 +globalDefault: false +description: "This priority class should be used for the GCE PD CSI driver controller deployment only." + +--- + +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: csi-gce-pd-node +value: 900001000 +globalDefault: false +description: "This priority class should be used for the GCE PD CSI driver node deployment only." + +--- + +# Resizer must be able to work with PVCs, PVs, SCs. +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-resizer-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + # If handle-volume-inuse-error=true, the pod specific rbac is needed + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-resizer-binding +subjects: + - kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-gce-pd-resizer-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-controller-deploy +rules: + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + verbs: ["use"] + resourceNames: + - csi-gce-pd-controller-psp + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: csi-gce-pd-controller-deploy +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: csi-gce-pd-controller-deploy +subjects: + - kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: {{ .Release.Namespace }} + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-node-deploy +rules: + - apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - csi-gce-pd-node-psp + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: csi-gce-pd-node +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: csi-gce-pd-node-deploy +subjects: +- kind: ServiceAccount + name: csi-gce-pd-node-sa + namespace: {{ .Release.Namespace }} + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: csi-gce-pd-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: csi-gce-pd-node-deploy +subjects: +- kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: {{ .Release.Namespace }} + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: csi-gce-pd-snapshotter-role +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + # Secrets resource omitted since GCE PD snapshots does not require them + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-controller-snapshotter-binding +subjects: + - kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-gce-pd-snapshotter-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-leaderelection-role + namespace: {{ .Release.Namespace }} + labels: + k8s-app: gcp-compute-persistent-disk-csi-driver +rules: +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + +--- + +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-controller-leaderelection-binding + namespace: {{ .Release.Namespace }} + labels: + k8s-app: gcp-compute-persistent-disk-csi-driver +subjects: +- kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: {{ .Release.Namespace }} +roleRef: + kind: Role + name: csi-gce-pd-leaderelection-role + apiGroup: rbac.authorization.k8s.io diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/controller.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/controller.yaml new file mode 100644 index 000000000..3b126510b --- /dev/null +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/controller.yaml @@ -0,0 +1,175 @@ +kind: Deployment +apiVersion: apps/v1 +metadata: + name: csi-gce-pd-controller + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.csiController.replicas }} + selector: + matchLabels: + app: gcp-compute-persistent-disk-csi-driver + template: + metadata: + labels: + app: gcp-compute-persistent-disk-csi-driver + spec: +{{- if .Values.csiController.runOnControlPlane }} + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + - effect: NoSchedule + key: node.cloudprovider.kubernetes.io/uninitialized + operator: Exists + - effect: NoSchedule + key: node.kubernetes.io/not-ready + operator: Exists +{{- end }} + nodeSelector: + kubernetes.io/os: linux +{{- if .Values.csiController.runOnControlPlane }} + node-role.kubernetes.io/control-plane: "" +{{- end }} + serviceAccountName: csi-gce-pd-controller-sa + priorityClassName: csi-gce-pd-controller + containers: + - name: csi-provisioner + image: {{ .Values.image.csiProvisioner.repo }}:{{ .Values.image.csiProvisioner.tag }} + imagePullPolicy: {{ .Values.image.csiProvisioner.pullPolicy }} + args: + - "--v=5" + - "--csi-address=/csi/csi.sock" + - "--feature-gates=Topology=true" + - "--http-endpoint=:22011" + - "--leader-election-namespace=$(PDCSI_NAMESPACE)" + - "--timeout=450s" + - "--extra-create-metadata" + # - "--run-controller-service=false" # disable the controller service of the CSI driver + # - "--run-node-service=false" # disable the node service of the CSI driver + - "--leader-election" + - "--default-fstype=ext4" + - "--controller-publish-readonly=true" + env: + - name: PDCSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - containerPort: 22011 + name: http-endpoint + protocol: TCP + livenessProbe: + failureThreshold: 1 + httpGet: + path: /healthz/leader-election + port: http-endpoint + initialDelaySeconds: 10 + timeoutSeconds: 10 + periodSeconds: 20 + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: csi-attacher + image: {{ .Values.image.csiAttacher.repo }}:{{ .Values.image.csiAttacher.tag }} + imagePullPolicy: {{ .Values.image.csiAttacher.pullPolicy }} + args: + - "--v=5" + - "--csi-address=/csi/csi.sock" + - "--http-endpoint=:22012" + - "--leader-election" + - "--leader-election-namespace=$(PDCSI_NAMESPACE)" + - "--timeout=450s" + env: + - name: PDCSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - containerPort: 22012 + name: http-endpoint + protocol: TCP + livenessProbe: + failureThreshold: 1 + httpGet: + path: /healthz/leader-election + port: http-endpoint + initialDelaySeconds: 10 + timeoutSeconds: 10 + periodSeconds: 20 + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: csi-resizer + image: {{ .Values.image.csiResizer.repo }}:{{ .Values.image.csiResizer.tag }} + imagePullPolicy: {{ .Values.image.csiResizer.pullPolicy }} + args: + - "--v=5" + - "--csi-address=/csi/csi.sock" + - "--http-endpoint=:22013" + - "--leader-election" + - "--leader-election-namespace=$(PDCSI_NAMESPACE)" + - "--handle-volume-inuse-error=false" + env: + - name: PDCSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - containerPort: 22013 + name: http-endpoint + protocol: TCP + livenessProbe: + failureThreshold: 1 + httpGet: + path: /healthz/leader-election + port: http-endpoint + initialDelaySeconds: 10 + timeoutSeconds: 10 + periodSeconds: 20 + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: csi-snapshotter + image: {{ .Values.image.csiSnapshotter.repo }}:{{ .Values.image.csiSnapshotter.tag }} + imagePullPolicy: {{ .Values.image.csiSnapshotter.pullPolicy }} + args: + - "--v=5" + - "--csi-address=/csi/csi.sock" + - "--metrics-address=:22014" + - "--leader-election" + - "--leader-election-namespace=$(PDCSI_NAMESPACE)" + - "--timeout=450s" + env: + - name: PDCSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: gce-pd-driver + # Don't change base image without changing pdImagePlaceholder in + # test/k8s-integration/main.go + image: {{ .Values.image.gcepdDriver.repo }}:{{ .Values.image.gcepdDriver.tag }} + imagePullPolicy: {{ .Values.image.gcepdDriver.pullPolicy }} + args: + - "--v=5" + - "--endpoint=unix:/csi/csi.sock" + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/cloud-sa/key.json" + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: cloud-sa-volume + readOnly: true + mountPath: "/etc/cloud-sa" + volumes: + - name: socket-dir + emptyDir: {} + - name: cloud-sa-volume + secret: + secretName: gcekey diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/node.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/node.yaml new file mode 100644 index 000000000..43b122dc9 --- /dev/null +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/node.yaml @@ -0,0 +1,117 @@ +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: csi-gce-pd-node + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: gcp-compute-persistent-disk-csi-driver + template: + metadata: + labels: + app: gcp-compute-persistent-disk-csi-driver + spec: + priorityClassName: csi-gce-pd-node + serviceAccountName: csi-gce-pd-node-sa + nodeSelector: + kubernetes.io/os: linux + containers: + - name: csi-driver-registrar + image: {{ .Values.image.csiNodeRegistrar.repo }}:{{ .Values.image.csiNodeRegistrar.tag }} + imagePullPolicy: {{ .Values.image.csiNodeRegistrar.pullPolicy }} + args: + - "--v=5" + - "--csi-address=/csi/csi.sock" + - "--kubelet-registration-path=/var/lib/kubelet/plugins/gcp.csi.confidential.cloud/csi.sock" + env: + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: plugin-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + livenessProbe: + initialDelaySeconds: 3 + exec: + command: + - /csi-node-driver-registrar + - --kubelet-registration-path=/var/lib/kubelet/plugins/gcp.csi.confidential.cloud/csi.sock + - --mode=kubelet-registration-probe + - name: gce-pd-driver + image: {{ .Values.image.gcepdDriver.repo }}:{{ .Values.image.gcepdDriver.tag }} + imagePullPolicy: {{ .Values.image.gcepdDriver.pullPolicy }} + args: + - "--v=5" + - "--endpoint=unix:/csi/csi.sock" + - "--run-controller-service=false" + - "--kms-addr=kms.{{ .Values.csiNode.kmsNamespace | default .Release.Namespace }}:{{ .Values.csiNode.kmsPort }}" + securityContext: + privileged: true + volumeMounts: + - name: kubelet-dir + mountPath: /var/lib/kubelet + mountPropagation: "Bidirectional" + - name: plugin-dir + mountPath: /csi + - name: device-dir + mountPath: /dev + # The following mounts are required to trigger host udevadm from + # container + - name: udev-rules-etc + mountPath: /etc/udev + - name: udev-rules-lib + mountPath: /lib/udev + - name: udev-socket + mountPath: /run/udev + - name: sys + mountPath: /sys + - name: cryptsetup + mountPath: /run/cryptsetup + volumes: + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: Directory + - name: kubelet-dir + hostPath: + path: /var/lib/kubelet + type: Directory + - name: plugin-dir + hostPath: + path: /var/lib/kubelet/plugins/gcp.csi.confidential.cloud/ + type: DirectoryOrCreate + - name: device-dir + hostPath: + path: /dev + type: Directory + # The following mounts are required to trigger host udevadm from + # container + - name: udev-rules-etc + hostPath: + path: /etc/udev + type: Directory + - name: udev-rules-lib + hostPath: + path: /lib/udev + type: Directory + - name: udev-socket + hostPath: + path: /run/udev + type: Directory + - name: sys + hostPath: + path: /sys + type: Directory + - name: cryptsetup + hostPath: + path: /run/cryptsetup + type: Directory + # https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + # See "special case". This will tolerate everything. Node component should + # be scheduled on all nodes. + tolerations: + - operator: Exists diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_default.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_default.yaml new file mode 100644 index 000000000..1ff0af10e --- /dev/null +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_default.yaml @@ -0,0 +1,14 @@ +{{- if .Values.createStorageClass }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + storageclass.kubernetes.io/is-default-class: "true" + name: encrypted-rwo +parameters: + type: pd-standard +provisioner: gcp.csi.confidential.cloud +allowVolumeExpansion: true +reclaimPolicy: Delete +volumeBindingMode: Immediate +{{- end }} diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_integrity.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_integrity.yaml new file mode 100644 index 000000000..6172302b8 --- /dev/null +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_integrity.yaml @@ -0,0 +1,14 @@ +{{- if .Values.createStorageClass }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + name: integrity-encrypted-rwo +parameters: + type: pd-ssd + csi.storage.k8s.io/fstype: ext4-integrity +provisioner: gcp.csi.confidential.cloud +allowVolumeExpansion: false +reclaimPolicy: Delete +volumeBindingMode: Immediate +{{- end }} diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/v1_csidriver.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/v1_csidriver.yaml new file mode 100644 index 000000000..7fed19483 --- /dev/null +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/v1_csidriver.yaml @@ -0,0 +1,7 @@ +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: gcp.csi.confidential.cloud +spec: + attachRequired: true + podInfoOnMount: false diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/values.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/values.yaml new file mode 100644 index 000000000..ee2e8c5bd --- /dev/null +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/values.yaml @@ -0,0 +1,36 @@ +image: + csiProvisioner: + repo: k8s.gcr.io/sig-storage/csi-provisioner + tag: "v3.1.0" + pullPolicy: IfNotPresent + csiAttacher: + repo: k8s.gcr.io/sig-storage/csi-attacher + tag: "v3.4.0" + pullPolicy: IfNotPresent + csiResizer: + repo: k8s.gcr.io/sig-storage/csi-resizer + tag: "v1.4.0" + pullPolicy: IfNotPresent + csiSnapshotter: + repo: k8s.gcr.io/sig-storage/csi-snapshotter + tag: "v4.0.1" + pullPolicy: IfNotPresent + csiNodeRegistrar: + repo: k8s.gcr.io/sig-storage/csi-node-driver-registrar + tag: "v2.5.0" + pullPolicy: IfNotPresent + gcepdDriver: + repo: ghcr.io/edgelesssys/constellation/gcp-csi-driver + # CSI driver version is independent of Constellation releases + tag: "v1.0.0" + pullPolicy: IfNotPresent + +csiController: + replicas: 1 + runOnControlPlane: true + +csiNode: + kmsPort: "9000" + kmsNamespace: "kube-system" + +createStorageClass: true diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/templates/configmap.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/templates/configmap.yaml index 5ff6db384..7f0493084 100644 --- a/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/templates/configmap.yaml +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/templates/configmap.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: join-config - namespace: kube-system + namespace: {{ .Release.Namespace }} data: # mustToJson is required so the json-strings passed from go are of type string in the rendered yaml. enforcedPCRs: {{ .Values.enforcedPCRs | mustToJson }} diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/templates/daemonset.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/templates/daemonset.yaml index e37fcf144..7aacd308d 100644 --- a/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/templates/daemonset.yaml +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/templates/daemonset.yaml @@ -23,8 +23,7 @@ spec: operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/master - operator: Equal - value: "true" + operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists @@ -39,7 +38,7 @@ spec: image: {{ .Values.image }} args: - --cloud-provider={{ .Values.csp }} - - --kms-endpoint=kms.kube-system:{{ .Values.global.kmsPort }} + - --kms-endpoint=kms.{{ .Release.Namespace }}:{{ .Values.global.kmsPort }} volumeMounts: - mountPath: {{ .Values.global.serviceBasePath }} name: config diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/values.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/values.yaml index 1e13d8233..814fd565b 100644 --- a/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/values.yaml +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/join-service/values.yaml @@ -1,5 +1,3 @@ -# Namespace to which to deploy -namespace: "kube-system" csp: "gcp" joinServicePort: 9090 joinServiceNodePort: 30090 diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/kms/templates/daemonset.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/kms/templates/daemonset.yaml index a86d50f27..ab1c64437 100644 --- a/cli/internal/helm/charts/edgeless/constellation-services/charts/kms/templates/daemonset.yaml +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/kms/templates/daemonset.yaml @@ -35,8 +35,7 @@ spec: operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/master - operator: Equal - value: "true" + operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists diff --git a/cli/internal/helm/charts/edgeless/constellation-services/charts/kms/values.yaml b/cli/internal/helm/charts/edgeless/constellation-services/charts/kms/values.yaml index f4c2f1a0b..aba7a9a5c 100644 --- a/cli/internal/helm/charts/edgeless/constellation-services/charts/kms/values.yaml +++ b/cli/internal/helm/charts/edgeless/constellation-services/charts/kms/values.yaml @@ -1,5 +1,3 @@ -# Namespace to which KMS will be deployed. -namespace: "kube-system" # Name of the key within the respective secret that holds the salt. saltKeyName: salt # Name of the secret that contains the master secret. diff --git a/cli/internal/helm/charts/edgeless/constellation-services/values.yaml b/cli/internal/helm/charts/edgeless/constellation-services/values.yaml index 70f52dad7..b55d610a6 100644 --- a/cli/internal/helm/charts/edgeless/constellation-services/values.yaml +++ b/cli/internal/helm/charts/edgeless/constellation-services/values.yaml @@ -10,6 +10,14 @@ global: # Name of the ConfigMap that holds configs that should not be modified by the user. internalCMName: internal-config +# GCP specific configuration +gcp: + deployCSIDriver: false + +# Azure specific configuration +azure: + deployCSIDriver: false + # Set one of the tags to true to indicate which CSP you are deploying to. tags: Azure: false diff --git a/cli/internal/helm/generateCilium.sh b/cli/internal/helm/generateCilium.sh index 6bf85a722..1408696ba 100755 --- a/cli/internal/helm/generateCilium.sh +++ b/cli/internal/helm/generateCilium.sh @@ -5,9 +5,16 @@ shopt -s inherit_errexit calldir=$(pwd) ciliumTmpDir=$(mktemp -d) -cd "${ciliumTmpDir}" || exit 1 -git clone --depth 1 -b 1.12.1 https://github.com/cilium/cilium.git -cd cilium || exit 1 +pushd "${ciliumTmpDir}" +git clone --filter=blob:none --no-checkout --sparse --depth 1 -b 1.12.1 https://github.com/cilium/cilium.git +pushd cilium + +git sparse-checkout add install/kubernetes/cilium +git checkout + git apply "${calldir}"/cilium.patch cp -r install/kubernetes/cilium "${calldir}"/charts + +popd +popd rm -r "${ciliumTmpDir}" diff --git a/cli/internal/helm/loader.go b/cli/internal/helm/loader.go index 84723976c..e2d47c8a1 100644 --- a/cli/internal/helm/loader.go +++ b/cli/internal/helm/loader.go @@ -18,6 +18,7 @@ import ( "strings" "github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider" + "github.com/edgelesssys/constellation/v2/internal/config" "github.com/edgelesssys/constellation/v2/internal/constants" "github.com/edgelesssys/constellation/v2/internal/deploy/helm" "github.com/edgelesssys/constellation/v2/internal/versions" @@ -30,6 +31,8 @@ import ( // Run `go generate` to deterministically create the patched Helm deployment for cilium //go:generate ./generateCilium.sh +// Run `go generate` to load CSI driver charts from the CSI repositories +//go:generate ./update-csi-charts.sh //go:embed all:charts/* var helmFS embed.FS @@ -66,13 +69,15 @@ func New(csp cloudprovider.Provider, k8sVersion versions.ValidK8sVersion) *Chart } // Load the embedded helm charts. -func (i *ChartLoader) Load(csp cloudprovider.Provider, conformanceMode bool, masterSecret []byte, salt []byte, enforcedPCRs []uint32, enforceIDKeyDigest bool) ([]byte, error) { +func (i *ChartLoader) Load(config *config.Config, conformanceMode bool, masterSecret, salt []byte) ([]byte, error) { + csp := config.GetProvider() + ciliumRelease, err := i.loadCilium(csp, conformanceMode) if err != nil { return nil, fmt.Errorf("loading cilium: %w", err) } - conServicesRelease, err := i.loadConstellationServices(csp, masterSecret, salt, enforcedPCRs, enforceIDKeyDigest) + conServicesRelease, err := i.loadConstellationServices(config, masterSecret, salt) if err != nil { return nil, fmt.Errorf("loading constellation-services: %w", err) } @@ -122,11 +127,9 @@ func (i *ChartLoader) loadCilium(csp cloudprovider.Provider, conformanceMode boo return helm.Release{Chart: chartRaw, Values: ciliumVals, ReleaseName: "cilium", Wait: true}, nil } -// loadConstellationServices loads the constellation-services chart from the embed.FS, marshals it into a helm-package .tgz and sets the values that can be set in the CLI. -func (i *ChartLoader) loadConstellationServices(csp cloudprovider.Provider, - masterSecret []byte, salt []byte, enforcedPCRs []uint32, - enforceIDKeyDigest bool, -) (helm.Release, error) { +// loadConstellationServices loads the constellation-services chart from the embed.FS, +// marshals it into a helm-package .tgz and sets the values that can be set in the CLI. +func (i *ChartLoader) loadConstellationServices(config *config.Config, masterSecret, salt []byte) (helm.Release, error) { chart, err := loadChartsDir(helmFS, "charts/edgeless/constellation-services") if err != nil { return helm.Release{}, fmt.Errorf("loading constellation-services chart: %w", err) @@ -137,11 +140,12 @@ func (i *ChartLoader) loadConstellationServices(csp cloudprovider.Provider, return helm.Release{}, fmt.Errorf("packaging chart: %w", err) } - enforcedPCRsJSON, err := json.Marshal(enforcedPCRs) + enforcedPCRsJSON, err := json.Marshal(config.GetEnforcedPCRs()) if err != nil { return helm.Release{}, fmt.Errorf("marshaling enforcedPCRs: %w", err) } + csp := config.GetProvider() vals := map[string]any{ "global": map[string]any{ "kmsPort": constants.KMSPort, @@ -154,7 +158,6 @@ func (i *ChartLoader) loadConstellationServices(csp cloudprovider.Provider, "image": i.kmsImage, "masterSecret": base64.StdEncoding.EncodeToString(masterSecret), "salt": base64.StdEncoding.EncodeToString(salt), - "namespace": constants.ConstellationNamespace, "saltKeyName": constants.ConstellationSaltKey, "masterSecretKeyName": constants.ConstellationMasterSecretKey, "masterSecretName": constants.ConstellationMasterSecretStoreName, @@ -164,7 +167,6 @@ func (i *ChartLoader) loadConstellationServices(csp cloudprovider.Provider, "csp": csp, "enforcedPCRs": string(enforcedPCRsJSON), "image": i.joinServiceImage, - "namespace": constants.ConstellationNamespace, }, "ccm": map[string]any{ "csp": csp, @@ -177,49 +179,61 @@ func (i *ChartLoader) loadConstellationServices(csp cloudprovider.Provider, switch csp { case cloudprovider.Azure: - { - joinServiceVals, ok := vals["join-service"].(map[string]any) - if !ok { - return helm.Release{}, errors.New("invalid join-service values") - } - joinServiceVals["enforceIdKeyDigest"] = enforceIDKeyDigest - - ccmVals, ok := vals["ccm"].(map[string]any) - if !ok { - return helm.Release{}, errors.New("invalid ccm values") - } - ccmVals["Azure"] = map[string]any{ - "image": i.ccmImage, - } - - vals["cnm"] = map[string]any{ - "image": i.cnmImage, - } - - vals["tags"] = map[string]any{ - "Azure": true, - } + joinServiceVals, ok := vals["join-service"].(map[string]any) + if !ok { + return helm.Release{}, errors.New("invalid join-service values") } + joinServiceVals["enforceIdKeyDigest"] = config.EnforcesIDKeyDigest() + + ccmVals, ok := vals["ccm"].(map[string]any) + if !ok { + return helm.Release{}, errors.New("invalid ccm values") + } + ccmVals["Azure"] = map[string]any{ + "image": i.ccmImage, + } + + vals["cnm"] = map[string]any{ + "image": i.cnmImage, + } + + vals["azure"] = map[string]any{ + "deployCSIDriver": config.DeployCSIDriver(), + } + + vals["tags"] = map[string]any{ + "Azure": true, + } + case cloudprovider.GCP: - { - ccmVals, ok := vals["ccm"].(map[string]any) - if !ok { - return helm.Release{}, errors.New("invalid ccm values") - } - ccmVals["GCP"] = map[string]any{ - "image": i.ccmImage, - } + ccmVals, ok := vals["ccm"].(map[string]any) + if !ok { + return helm.Release{}, errors.New("invalid ccm values") + } + ccmVals["GCP"] = map[string]any{ + "image": i.ccmImage, + } - vals["tags"] = map[string]any{ - "GCP": true, - } + vals["gcp"] = map[string]any{ + "deployCSIDriver": config.DeployCSIDriver(), } + + vals["gcp-compute-persistent-disk-csi-driver"] = map[string]any{ + "csiNode": map[string]any{ + "kmsPort": constants.KMSPort, + "kmsNamespace": "", // empty namespace means we use the release namespace + }, + } + + vals["tags"] = map[string]any{ + "GCP": true, + } + case cloudprovider.QEMU: - { - vals["tags"] = map[string]interface{}{ - "QEMU": true, - } + vals["tags"] = map[string]interface{}{ + "QEMU": true, } + case cloudprovider.AWS: ccmVals, ok := vals["ccm"].(map[string]any) if !ok { diff --git a/cli/internal/helm/loader_test.go b/cli/internal/helm/loader_test.go index c5bd704f1..3904d8c78 100644 --- a/cli/internal/helm/loader_test.go +++ b/cli/internal/helm/loader_test.go @@ -15,7 +15,7 @@ import ( "path" "testing" - "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/pkg/errors" "github.com/stretchr/testify/assert" @@ -31,7 +31,8 @@ func TestLoad(t *testing.T) { require := require.New(t) chartLoader := ChartLoader{} - release, err := chartLoader.Load(cloudprovider.GCP, true, []byte("secret"), []byte("salt"), nil, false) + config := &config.Config{Provider: config.ProviderConfig{GCP: &config.GCPConfig{}}} + release, err := chartLoader.Load(config, true, []byte("secret"), []byte("salt")) require.NoError(err) var helmReleases helm.Releases @@ -46,27 +47,35 @@ func TestLoad(t *testing.T) { // TestTemplate checks if the rendered constellation-services chart produces the expected yaml files. func TestTemplate(t *testing.T) { testCases := map[string]struct { - csp cloudprovider.Provider + config *config.Config enforceIDKeyDigest bool valuesModifier func(map[string]any) error ccmImage string cnmImage string }{ "GCP": { - csp: cloudprovider.GCP, + config: &config.Config{Provider: config.ProviderConfig{GCP: &config.GCPConfig{ + DeployCSIDriver: func() *bool { b := true; return &b }(), + EnforcedMeasurements: []uint32{1, 11}, + }}}, enforceIDKeyDigest: false, valuesModifier: prepareGCPValues, ccmImage: "ccmImageForGCP", }, "Azure": { - csp: cloudprovider.Azure, + config: &config.Config{Provider: config.ProviderConfig{Azure: &config.AzureConfig{ + EnforcedMeasurements: []uint32{1, 11}, + EnforceIDKeyDigest: func() *bool { b := true; return &b }(), + }}}, enforceIDKeyDigest: true, valuesModifier: prepareAzureValues, ccmImage: "ccmImageForAzure", cnmImage: "cnmImageForAzure", }, "QEMU": { - csp: cloudprovider.QEMU, + config: &config.Config{Provider: config.ProviderConfig{QEMU: &config.QEMUConfig{ + EnforcedMeasurements: []uint32{1, 11}, + }}}, enforceIDKeyDigest: false, valuesModifier: prepareQEMUValues, }, @@ -78,7 +87,7 @@ func TestTemplate(t *testing.T) { require := require.New(t) chartLoader := ChartLoader{joinServiceImage: "joinServiceImage", kmsImage: "kmsImage", ccmImage: tc.ccmImage, cnmImage: tc.cnmImage, autoscalerImage: "autoscalerImage"} - release, err := chartLoader.Load(tc.csp, true, []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), []uint32{1, 11}, tc.enforceIDKeyDigest) + release, err := chartLoader.Load(tc.config, true, []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) require.NoError(err) var helmReleases helm.Releases @@ -110,7 +119,7 @@ func TestTemplate(t *testing.T) { result, err := engine.Render(chart, valuesToRender) require.NoError(err) for k, v := range result { - currentFile := path.Join("testdata", tc.csp.String(), k) + currentFile := path.Join("testdata", tc.config.GetProvider().String(), k) content, err := os.ReadFile(currentFile) // If a file does not exist, we expect the render for that path to be empty. @@ -142,6 +151,45 @@ func prepareGCPValues(values map[string]any) error { ccmVals["GCP"].(map[string]any)["uid"] = "242424242424" ccmVals["GCP"].(map[string]any)["secretData"] = "baaaaaad" + testTag := "v0.0.0" + pullPolicy := "IfNotPresent" + csiVals, ok := values["gcp-compute-persistent-disk-csi-driver"].(map[string]any) + if !ok { + return errors.New("missing 'gcp-compute-persistent-disk-csi-driver' key") + } + csiVals["image"] = map[string]any{ + "csiProvisioner": map[string]any{ + "repo": "csi-provisioner", + "tag": testTag, + "pullPolicy": pullPolicy, + }, + "csiAttacher": map[string]any{ + "repo": "csi-attacher", + "tag": testTag, + "pullPolicy": pullPolicy, + }, + "csiResizer": map[string]any{ + "repo": "csi-resizer", + "tag": testTag, + "pullPolicy": pullPolicy, + }, + "csiSnapshotter": map[string]any{ + "repo": "csi-snapshotter", + "tag": testTag, + "pullPolicy": pullPolicy, + }, + "csiNodeRegistrar": map[string]any{ + "repo": "csi-registrar", + "tag": testTag, + "pullPolicy": pullPolicy, + }, + "gcepdDriver": map[string]any{ + "repo": "csi-driver", + "tag": testTag, + "pullPolicy": pullPolicy, + }, + } + return nil } diff --git a/cli/internal/helm/testdata/Azure/constellation-services/charts/autoscaler/templates/rolebinding.yaml b/cli/internal/helm/testdata/Azure/constellation-services/charts/autoscaler/templates/rolebinding.yaml index 5f567e23f..ef6f15262 100644 --- a/cli/internal/helm/testdata/Azure/constellation-services/charts/autoscaler/templates/rolebinding.yaml +++ b/cli/internal/helm/testdata/Azure/constellation-services/charts/autoscaler/templates/rolebinding.yaml @@ -14,4 +14,4 @@ roleRef: subjects: - kind: ServiceAccount name: constellation-cluster-autoscaler - namespace: kube-system + namespace: testNamespace diff --git a/cli/internal/helm/testdata/Azure/constellation-services/charts/cnm/templates/azure-daemonset.yaml b/cli/internal/helm/testdata/Azure/constellation-services/charts/cnm/templates/azure-daemonset.yaml index c3b9bb9ab..6e3c2175e 100644 --- a/cli/internal/helm/testdata/Azure/constellation-services/charts/cnm/templates/azure-daemonset.yaml +++ b/cli/internal/helm/testdata/Azure/constellation-services/charts/cnm/templates/azure-daemonset.yaml @@ -45,8 +45,7 @@ spec: operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/master - operator: Equal - value: "true" + operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists diff --git a/cli/internal/helm/testdata/Azure/constellation-services/charts/join-service/templates/configmap.yaml b/cli/internal/helm/testdata/Azure/constellation-services/charts/join-service/templates/configmap.yaml index 1998e0b4a..a6770a452 100644 --- a/cli/internal/helm/testdata/Azure/constellation-services/charts/join-service/templates/configmap.yaml +++ b/cli/internal/helm/testdata/Azure/constellation-services/charts/join-service/templates/configmap.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: join-config - namespace: kube-system + namespace: testNamespace data: enforcedPCRs: "[1,11]" measurements: "{'1':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA','15':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='}" diff --git a/cli/internal/helm/testdata/Azure/constellation-services/charts/join-service/templates/daemonset.yaml b/cli/internal/helm/testdata/Azure/constellation-services/charts/join-service/templates/daemonset.yaml index c5f588d2c..69097c713 100644 --- a/cli/internal/helm/testdata/Azure/constellation-services/charts/join-service/templates/daemonset.yaml +++ b/cli/internal/helm/testdata/Azure/constellation-services/charts/join-service/templates/daemonset.yaml @@ -23,8 +23,7 @@ spec: operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/master - operator: Equal - value: "true" + operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists @@ -39,7 +38,7 @@ spec: image: joinServiceImage args: - --cloud-provider=Azure - - --kms-endpoint=kms.kube-system:9000 + - --kms-endpoint=kms.testNamespace:9000 volumeMounts: - mountPath: /var/config name: config diff --git a/cli/internal/helm/testdata/Azure/constellation-services/charts/kms/templates/daemonset.yaml b/cli/internal/helm/testdata/Azure/constellation-services/charts/kms/templates/daemonset.yaml index a3c593791..2f744e199 100644 --- a/cli/internal/helm/testdata/Azure/constellation-services/charts/kms/templates/daemonset.yaml +++ b/cli/internal/helm/testdata/Azure/constellation-services/charts/kms/templates/daemonset.yaml @@ -35,8 +35,7 @@ spec: operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/master - operator: Equal - value: "true" + operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists diff --git a/cli/internal/helm/testdata/GCP/constellation-services/charts/autoscaler/templates/rolebinding.yaml b/cli/internal/helm/testdata/GCP/constellation-services/charts/autoscaler/templates/rolebinding.yaml index 5f567e23f..ef6f15262 100644 --- a/cli/internal/helm/testdata/GCP/constellation-services/charts/autoscaler/templates/rolebinding.yaml +++ b/cli/internal/helm/testdata/GCP/constellation-services/charts/autoscaler/templates/rolebinding.yaml @@ -14,4 +14,4 @@ roleRef: subjects: - kind: ServiceAccount name: constellation-cluster-autoscaler - namespace: kube-system + namespace: testNamespace diff --git a/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/cluster_setup.yaml b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/cluster_setup.yaml new file mode 100644 index 000000000..5202fd80a --- /dev/null +++ b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/cluster_setup.yaml @@ -0,0 +1,297 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-gce-pd-node-sa + namespace: testNamespace + +--- + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-gce-pd-controller-sa + namespace: testNamespace + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-provisioner-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-controller-provisioner-binding +subjects: + - kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: testNamespace +roleRef: + kind: ClusterRole + name: csi-gce-pd-provisioner-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-attacher-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-controller-attacher-binding +subjects: + - kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: testNamespace +roleRef: + kind: ClusterRole + name: csi-gce-pd-attacher-role + apiGroup: rbac.authorization.k8s.io + +--- + +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: csi-gce-pd-controller +value: 900000000 +globalDefault: false +description: "This priority class should be used for the GCE PD CSI driver controller deployment only." + +--- + +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: csi-gce-pd-node +value: 900001000 +globalDefault: false +description: "This priority class should be used for the GCE PD CSI driver node deployment only." + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-resizer-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-resizer-binding +subjects: + - kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: testNamespace +roleRef: + kind: ClusterRole + name: csi-gce-pd-resizer-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-controller-deploy +rules: + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + verbs: ["use"] + resourceNames: + - csi-gce-pd-controller-psp + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: csi-gce-pd-controller-deploy +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: csi-gce-pd-controller-deploy +subjects: + - kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: testNamespace + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-node-deploy +rules: + - apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - csi-gce-pd-node-psp + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: csi-gce-pd-node +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: csi-gce-pd-node-deploy +subjects: +- kind: ServiceAccount + name: csi-gce-pd-node-sa + namespace: testNamespace + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: csi-gce-pd-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: csi-gce-pd-node-deploy +subjects: +- kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: testNamespace + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: csi-gce-pd-snapshotter-role +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-controller-snapshotter-binding +subjects: + - kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: testNamespace +roleRef: + kind: ClusterRole + name: csi-gce-pd-snapshotter-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-leaderelection-role + namespace: testNamespace + labels: + k8s-app: gcp-compute-persistent-disk-csi-driver +rules: +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + +--- + +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-gce-pd-controller-leaderelection-binding + namespace: testNamespace + labels: + k8s-app: gcp-compute-persistent-disk-csi-driver +subjects: +- kind: ServiceAccount + name: csi-gce-pd-controller-sa + namespace: testNamespace +roleRef: + kind: Role + name: csi-gce-pd-leaderelection-role + apiGroup: rbac.authorization.k8s.io diff --git a/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/controller.yaml b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/controller.yaml new file mode 100644 index 000000000..d0d855bd6 --- /dev/null +++ b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/controller.yaml @@ -0,0 +1,167 @@ +kind: Deployment +apiVersion: apps/v1 +metadata: + name: csi-gce-pd-controller + namespace: testNamespace +spec: + replicas: 1 + selector: + matchLabels: + app: gcp-compute-persistent-disk-csi-driver + template: + metadata: + labels: + app: gcp-compute-persistent-disk-csi-driver + spec: + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + - effect: NoSchedule + key: node.cloudprovider.kubernetes.io/uninitialized + operator: Exists + - effect: NoSchedule + key: node.kubernetes.io/not-ready + operator: Exists + nodeSelector: + node-role.kubernetes.io/control-plane: "" + kubernetes.io/os: linux + serviceAccountName: csi-gce-pd-controller-sa + priorityClassName: csi-gce-pd-controller + containers: + - name: csi-provisioner + image: csi-provisioner:v0.0.0 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--csi-address=/csi/csi.sock" + - "--feature-gates=Topology=true" + - "--http-endpoint=:22011" + - "--leader-election-namespace=$(PDCSI_NAMESPACE)" + - "--timeout=450s" + - "--extra-create-metadata" + - "--leader-election" + - "--default-fstype=ext4" + - "--controller-publish-readonly=true" + env: + - name: PDCSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - containerPort: 22011 + name: http-endpoint + protocol: TCP + livenessProbe: + failureThreshold: 1 + httpGet: + path: /healthz/leader-election + port: http-endpoint + initialDelaySeconds: 10 + timeoutSeconds: 10 + periodSeconds: 20 + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: csi-attacher + image: csi-attacher:v0.0.0 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--csi-address=/csi/csi.sock" + - "--http-endpoint=:22012" + - "--leader-election" + - "--leader-election-namespace=$(PDCSI_NAMESPACE)" + - "--timeout=450s" + env: + - name: PDCSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - containerPort: 22012 + name: http-endpoint + protocol: TCP + livenessProbe: + failureThreshold: 1 + httpGet: + path: /healthz/leader-election + port: http-endpoint + initialDelaySeconds: 10 + timeoutSeconds: 10 + periodSeconds: 20 + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: csi-resizer + image: csi-resizer:v0.0.0 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--csi-address=/csi/csi.sock" + - "--http-endpoint=:22013" + - "--leader-election" + - "--leader-election-namespace=$(PDCSI_NAMESPACE)" + - "--handle-volume-inuse-error=false" + env: + - name: PDCSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - containerPort: 22013 + name: http-endpoint + protocol: TCP + livenessProbe: + failureThreshold: 1 + httpGet: + path: /healthz/leader-election + port: http-endpoint + initialDelaySeconds: 10 + timeoutSeconds: 10 + periodSeconds: 20 + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: csi-snapshotter + image: csi-snapshotter:v0.0.0 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--csi-address=/csi/csi.sock" + - "--metrics-address=:22014" + - "--leader-election" + - "--leader-election-namespace=$(PDCSI_NAMESPACE)" + - "--timeout=450s" + env: + - name: PDCSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: gce-pd-driver + image: csi-driver:v0.0.0 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--endpoint=unix:/csi/csi.sock" + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/cloud-sa/key.json" + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: cloud-sa-volume + readOnly: true + mountPath: "/etc/cloud-sa" + volumes: + - name: socket-dir + emptyDir: {} + - name: cloud-sa-volume + secret: + secretName: gcekey diff --git a/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/node.yaml b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/node.yaml new file mode 100644 index 000000000..201bc885c --- /dev/null +++ b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/node.yaml @@ -0,0 +1,110 @@ +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: csi-gce-pd-node + namespace: testNamespace +spec: + selector: + matchLabels: + app: gcp-compute-persistent-disk-csi-driver + template: + metadata: + labels: + app: gcp-compute-persistent-disk-csi-driver + spec: + priorityClassName: csi-gce-pd-node + serviceAccountName: csi-gce-pd-node-sa + nodeSelector: + kubernetes.io/os: linux + containers: + - name: csi-driver-registrar + image: csi-registrar:v0.0.0 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--csi-address=/csi/csi.sock" + - "--kubelet-registration-path=/var/lib/kubelet/plugins/gcp.csi.confidential.cloud/csi.sock" + env: + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: plugin-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + livenessProbe: + initialDelaySeconds: 3 + exec: + command: + - /csi-node-driver-registrar + - --kubelet-registration-path=/var/lib/kubelet/plugins/gcp.csi.confidential.cloud/csi.sock + - --mode=kubelet-registration-probe + - name: gce-pd-driver + image: csi-driver:v0.0.0 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--endpoint=unix:/csi/csi.sock" + - "--run-controller-service=false" + - "--kms-addr=kms.testNamespace:9000" + securityContext: + privileged: true + volumeMounts: + - name: kubelet-dir + mountPath: /var/lib/kubelet + mountPropagation: "Bidirectional" + - name: plugin-dir + mountPath: /csi + - name: device-dir + mountPath: /dev + - name: udev-rules-etc + mountPath: /etc/udev + - name: udev-rules-lib + mountPath: /lib/udev + - name: udev-socket + mountPath: /run/udev + - name: sys + mountPath: /sys + - name: cryptsetup + mountPath: /run/cryptsetup + volumes: + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: Directory + - name: kubelet-dir + hostPath: + path: /var/lib/kubelet + type: Directory + - name: plugin-dir + hostPath: + path: /var/lib/kubelet/plugins/gcp.csi.confidential.cloud/ + type: DirectoryOrCreate + - name: device-dir + hostPath: + path: /dev + type: Directory + - name: udev-rules-etc + hostPath: + path: /etc/udev + type: Directory + - name: udev-rules-lib + hostPath: + path: /lib/udev + type: Directory + - name: udev-socket + hostPath: + path: /run/udev + type: Directory + - name: sys + hostPath: + path: /sys + type: Directory + - name: cryptsetup + hostPath: + path: /run/cryptsetup + type: Directory + tolerations: + - operator: Exists diff --git a/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_default.yaml b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_default.yaml new file mode 100644 index 000000000..3ada4e418 --- /dev/null +++ b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_default.yaml @@ -0,0 +1,12 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + storageclass.kubernetes.io/is-default-class: "true" + name: encrypted-rwo +parameters: + type: pd-standard +provisioner: gcp.csi.confidential.cloud +allowVolumeExpansion: true +reclaimPolicy: Delete +volumeBindingMode: Immediate diff --git a/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_integrity.yaml b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_integrity.yaml new file mode 100644 index 000000000..b1009d527 --- /dev/null +++ b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/storageclass_integrity.yaml @@ -0,0 +1,12 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + name: integrity-encrypted-rwo +parameters: + type: pd-ssd + csi.storage.k8s.io/fstype: ext4-integrity +provisioner: gcp.csi.confidential.cloud +allowVolumeExpansion: false +reclaimPolicy: Delete +volumeBindingMode: Immediate diff --git a/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/v1_csidriver.yaml b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/v1_csidriver.yaml new file mode 100644 index 000000000..7fed19483 --- /dev/null +++ b/cli/internal/helm/testdata/GCP/constellation-services/charts/gcp-compute-persistent-disk-csi-driver/templates/v1_csidriver.yaml @@ -0,0 +1,7 @@ +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: gcp.csi.confidential.cloud +spec: + attachRequired: true + podInfoOnMount: false diff --git a/cli/internal/helm/testdata/GCP/constellation-services/charts/join-service/templates/configmap.yaml b/cli/internal/helm/testdata/GCP/constellation-services/charts/join-service/templates/configmap.yaml index 756a84497..889dfe8f6 100644 --- a/cli/internal/helm/testdata/GCP/constellation-services/charts/join-service/templates/configmap.yaml +++ b/cli/internal/helm/testdata/GCP/constellation-services/charts/join-service/templates/configmap.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: join-config - namespace: kube-system + namespace: testNamespace data: enforcedPCRs: "[1,11]" measurements: "{'1':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA','15':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='}" diff --git a/cli/internal/helm/testdata/GCP/constellation-services/charts/join-service/templates/daemonset.yaml b/cli/internal/helm/testdata/GCP/constellation-services/charts/join-service/templates/daemonset.yaml index 2b8088d84..950fc27d5 100644 --- a/cli/internal/helm/testdata/GCP/constellation-services/charts/join-service/templates/daemonset.yaml +++ b/cli/internal/helm/testdata/GCP/constellation-services/charts/join-service/templates/daemonset.yaml @@ -23,8 +23,7 @@ spec: operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/master - operator: Equal - value: "true" + operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists @@ -39,7 +38,7 @@ spec: image: joinServiceImage args: - --cloud-provider=GCP - - --kms-endpoint=kms.kube-system:9000 + - --kms-endpoint=kms.testNamespace:9000 volumeMounts: - mountPath: /var/config name: config diff --git a/cli/internal/helm/testdata/GCP/constellation-services/charts/kms/templates/daemonset.yaml b/cli/internal/helm/testdata/GCP/constellation-services/charts/kms/templates/daemonset.yaml index a3c593791..2f744e199 100644 --- a/cli/internal/helm/testdata/GCP/constellation-services/charts/kms/templates/daemonset.yaml +++ b/cli/internal/helm/testdata/GCP/constellation-services/charts/kms/templates/daemonset.yaml @@ -35,8 +35,7 @@ spec: operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/master - operator: Equal - value: "true" + operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists diff --git a/cli/internal/helm/testdata/QEMU/constellation-services/charts/join-service/templates/configmap.yaml b/cli/internal/helm/testdata/QEMU/constellation-services/charts/join-service/templates/configmap.yaml index 756a84497..889dfe8f6 100644 --- a/cli/internal/helm/testdata/QEMU/constellation-services/charts/join-service/templates/configmap.yaml +++ b/cli/internal/helm/testdata/QEMU/constellation-services/charts/join-service/templates/configmap.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: join-config - namespace: kube-system + namespace: testNamespace data: enforcedPCRs: "[1,11]" measurements: "{'1':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA','15':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='}" diff --git a/cli/internal/helm/testdata/QEMU/constellation-services/charts/join-service/templates/daemonset.yaml b/cli/internal/helm/testdata/QEMU/constellation-services/charts/join-service/templates/daemonset.yaml index b75a14e3c..7cc4f2991 100644 --- a/cli/internal/helm/testdata/QEMU/constellation-services/charts/join-service/templates/daemonset.yaml +++ b/cli/internal/helm/testdata/QEMU/constellation-services/charts/join-service/templates/daemonset.yaml @@ -23,8 +23,7 @@ spec: operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/master - operator: Equal - value: "true" + operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists @@ -39,7 +38,7 @@ spec: image: joinServiceImage args: - --cloud-provider=QEMU - - --kms-endpoint=kms.kube-system:9000 + - --kms-endpoint=kms.testNamespace:9000 volumeMounts: - mountPath: /var/config name: config diff --git a/cli/internal/helm/testdata/QEMU/constellation-services/charts/kms/templates/daemonset.yaml b/cli/internal/helm/testdata/QEMU/constellation-services/charts/kms/templates/daemonset.yaml index a3c593791..2f744e199 100644 --- a/cli/internal/helm/testdata/QEMU/constellation-services/charts/kms/templates/daemonset.yaml +++ b/cli/internal/helm/testdata/QEMU/constellation-services/charts/kms/templates/daemonset.yaml @@ -35,8 +35,7 @@ spec: operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/master - operator: Equal - value: "true" + operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists diff --git a/cli/internal/helm/update-csi-charts.sh b/cli/internal/helm/update-csi-charts.sh new file mode 100755 index 000000000..7f2f05e9f --- /dev/null +++ b/cli/internal/helm/update-csi-charts.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# update-csi-charts updates the Helm charts for the CSI drivers in the CLI. + +set -euo pipefail +shopt -s inherit_errexit + +# Required tools +if ! command -v git &> /dev/null; then + echo "git could not be found" + exit 1 +fi + +# download_chart downloads the Helm chart for the given CSI driver and version. +# +# Arguments: +# $1: URL of the git repo containing the Helm chart +# $2: branch or tag of the git repo +# $3: path to the Helm chart in the git repo +# $4: name of the Helm chart +download_chart() { + chart_url=$1 + branch=$2 + chart_dir=$3 + chart_name=$4 + + repo_tmp_dir=$(mktemp -d) + + chart_base_path="charts/edgeless/constellation-services/charts/" + + pushd "${repo_tmp_dir}" + git clone --filter=blob:none --no-checkout --sparse --depth 1 --branch="${branch}" "${chart_url}" "${repo_tmp_dir}" + + git sparse-checkout add "${chart_dir}" + git checkout + popd + + # remove old chart + rm -r "${chart_base_path}${chart_name}" + + # move new chart + mkdir -p "${chart_base_path}/${chart_name}" + cp -r "${repo_tmp_dir}/${chart_dir}"/* "${chart_base_path}${chart_name}" + rm -r "${repo_tmp_dir}" + + return +} + +## GCP CSI Driver +# TODO: clone from main branch once we rebase on upstream +download_chart "https://github.com/edgelesssys/constellation-gcp-compute-persistent-disk-csi-driver" "develop" "charts" "gcp-compute-persistent-disk-csi-driver" + +## Azure CSI Driver +# TODO: https://github.com/edgelesssys/constellation/pull/548 diff --git a/internal/config/config.go b/internal/config/config.go index 8cca965b0..a9fffec71 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -182,11 +182,14 @@ type AzureConfig struct { // Type of a node's state disk. The type influences boot time and I/O performance. See: https://docs.microsoft.com/en-us/azure/virtual-machines/disks-types#disk-type-comparison StateDiskType string `yaml:"stateDiskType" validate:"oneof=Premium_LRS Premium_ZRS Standard_LRS StandardSSD_LRS StandardSSD_ZRS"` // description: | - // Expected confidential VM measurements. - Measurements Measurements `yaml:"measurements"` + // Deploy Azure Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage + DeployCSIDriver *bool `yaml:"deployCSIDriver" validate:"required"` // description: | - // List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning. - EnforcedMeasurements []uint32 `yaml:"enforcedMeasurements"` + // Use Confidential VMs. If set to false, Trusted Launch VMs are used instead. See: https://docs.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview + ConfidentialVM *bool `yaml:"confidentialVM" validate:"required"` + // description: | + // Enable secure boot for VMs. If enabled, the OS image has to include a virtual machine guest state (VMGS) blob. + SecureBoot *bool `yaml:"secureBoot" validate:"required"` // description: | // Expected value for the field 'idkeydigest' in the AMD SEV-SNP attestation report. Only usable with ConfidentialVMs. See 4.6 and 7.3 in: https://www.amd.com/system/files/TechDocs/56860.pdf IDKeyDigest string `yaml:"idKeyDigest" validate:"required_if=EnforceIdKeyDigest true,omitempty,hexadecimal,len=96"` @@ -194,11 +197,11 @@ type AzureConfig struct { // Enforce the specified idKeyDigest value during remote attestation. EnforceIDKeyDigest *bool `yaml:"enforceIdKeyDigest" validate:"required"` // description: | - // Use Confidential VMs. If set to false, Trusted Launch VMs are used instead. See: https://docs.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview - ConfidentialVM *bool `yaml:"confidentialVM" validate:"required"` + // Expected confidential VM measurements. + Measurements Measurements `yaml:"measurements"` // description: | - // Enable secure boot for VMs. If enabled, the OS image has to include a virtual machine guest state (VMGS) blob. - SecureBoot *bool `yaml:"secureBoot" validate:"required"` + // List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning. + EnforcedMeasurements []uint32 `yaml:"enforcedMeasurements"` } // GCPConfig are GCP specific configuration values used by the CLI. @@ -225,6 +228,9 @@ type GCPConfig struct { // Type of a node's state disk. The type influences boot time and I/O performance. See: https://cloud.google.com/compute/docs/disks#disk-types StateDiskType string `yaml:"stateDiskType" validate:"oneof=pd-standard pd-balanced pd-ssd"` // description: | + // Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage + DeployCSIDriver *bool `yaml:"deployCSIDriver" validate:"required"` + // description: | // Expected confidential VM measurements. Measurements Measurements `yaml:"measurements"` // description: | @@ -295,21 +301,23 @@ func Default() *Config { Image: DefaultImageAzure, InstanceType: "Standard_DC4as_v5", StateDiskType: "Premium_LRS", - Measurements: measurements.DefaultsFor(cloudprovider.Azure), - EnforcedMeasurements: []uint32{4, 8, 9, 11, 12, 13, 15}, + DeployCSIDriver: func() *bool { b := true; return &b }(), IDKeyDigest: "57486a447ec0f1958002a22a06b7673b9fd27d11e1c6527498056054c5fa92d23c50f9de44072760fe2b6fb89740b696", EnforceIDKeyDigest: func() *bool { b := true; return &b }(), ConfidentialVM: func() *bool { b := true; return &b }(), SecureBoot: func() *bool { b := false; return &b }(), + Measurements: measurements.DefaultsFor(cloudprovider.Azure), + EnforcedMeasurements: []uint32{4, 8, 9, 11, 12, 13, 15}, }, GCP: &GCPConfig{ Project: "", Region: "", Zone: "", + ServiceAccountKeyPath: "", Image: DefaultImageGCP, InstanceType: "n2d-standard-4", StateDiskType: "pd-ssd", - ServiceAccountKeyPath: "", + DeployCSIDriver: func() *bool { b := true; return &b }(), Measurements: measurements.DefaultsFor(cloudprovider.GCP), EnforcedMeasurements: []uint32{0, 4, 8, 9, 11, 12, 13, 15}, }, @@ -320,9 +328,9 @@ func Default() *Config { MetadataAPIImage: versions.QEMUMetadataImage, LibvirtURI: "", LibvirtContainerImage: versions.LibvirtImage, + NVRAM: "production", Measurements: measurements.DefaultsFor(cloudprovider.QEMU), EnforcedMeasurements: []uint32{4, 8, 9, 11, 12, 13, 15}, - NVRAM: "production", }, }, KubernetesVersion: string(versions.Default), @@ -482,6 +490,29 @@ func (c *Config) EnforcesIDKeyDigest() bool { return c.Provider.Azure != nil && c.Provider.Azure.EnforceIDKeyDigest != nil && *c.Provider.Azure.EnforceIDKeyDigest } +// GetEnforcedPCRs returns the list of enforced PCRs for the configured cloud provider. +func (c *Config) GetEnforcedPCRs() []uint32 { + provider := c.GetProvider() + switch provider { + case cloudprovider.AWS: + return c.Provider.AWS.EnforcedMeasurements + case cloudprovider.Azure: + return c.Provider.Azure.EnforcedMeasurements + case cloudprovider.GCP: + return c.Provider.GCP.EnforcedMeasurements + case cloudprovider.QEMU: + return c.Provider.QEMU.EnforcedMeasurements + default: + return nil + } +} + +// DeployCSIDriver returns whether the CSI driver should be deployed for a given cloud provider. +func (c *Config) DeployCSIDriver() bool { + return c.Provider.Azure != nil && c.Provider.Azure.DeployCSIDriver != nil && *c.Provider.Azure.DeployCSIDriver || + c.Provider.GCP != nil && c.Provider.GCP.DeployCSIDriver != nil && *c.Provider.GCP.DeployCSIDriver +} + // Validate checks the config values and returns validation errors. func (c *Config) Validate() error { trans := ut.New(en.New()).GetFallback() diff --git a/internal/config/config_doc.go b/internal/config/config_doc.go index 43c648759..7b3fba986 100644 --- a/internal/config/config_doc.go +++ b/internal/config/config_doc.go @@ -208,7 +208,7 @@ func init() { FieldName: "azure", }, } - AzureConfigDoc.Fields = make([]encoder.Doc, 16) + AzureConfigDoc.Fields = make([]encoder.Doc, 17) AzureConfigDoc.Fields[0].Name = "subscription" AzureConfigDoc.Fields[0].Type = "string" AzureConfigDoc.Fields[0].Note = "" @@ -259,36 +259,41 @@ func init() { AzureConfigDoc.Fields[9].Note = "" AzureConfigDoc.Fields[9].Description = "Type of a node's state disk. The type influences boot time and I/O performance. See: https://docs.microsoft.com/en-us/azure/virtual-machines/disks-types#disk-type-comparison" AzureConfigDoc.Fields[9].Comments[encoder.LineComment] = "Type of a node's state disk. The type influences boot time and I/O performance. See: https://docs.microsoft.com/en-us/azure/virtual-machines/disks-types#disk-type-comparison" - AzureConfigDoc.Fields[10].Name = "measurements" - AzureConfigDoc.Fields[10].Type = "Measurements" + AzureConfigDoc.Fields[10].Name = "deployCSIDriver" + AzureConfigDoc.Fields[10].Type = "bool" AzureConfigDoc.Fields[10].Note = "" - AzureConfigDoc.Fields[10].Description = "Expected confidential VM measurements." - AzureConfigDoc.Fields[10].Comments[encoder.LineComment] = "Expected confidential VM measurements." - AzureConfigDoc.Fields[11].Name = "enforcedMeasurements" - AzureConfigDoc.Fields[11].Type = "[]uint32" + AzureConfigDoc.Fields[10].Description = "Deploy Azure Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage" + AzureConfigDoc.Fields[10].Comments[encoder.LineComment] = "Deploy Azure Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage" + AzureConfigDoc.Fields[11].Name = "confidentialVM" + AzureConfigDoc.Fields[11].Type = "bool" AzureConfigDoc.Fields[11].Note = "" - AzureConfigDoc.Fields[11].Description = "List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning." - AzureConfigDoc.Fields[11].Comments[encoder.LineComment] = "List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning." - AzureConfigDoc.Fields[12].Name = "idKeyDigest" - AzureConfigDoc.Fields[12].Type = "string" + AzureConfigDoc.Fields[11].Description = "Use Confidential VMs. If set to false, Trusted Launch VMs are used instead. See: https://docs.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview" + AzureConfigDoc.Fields[11].Comments[encoder.LineComment] = "Use Confidential VMs. If set to false, Trusted Launch VMs are used instead. See: https://docs.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview" + AzureConfigDoc.Fields[12].Name = "secureBoot" + AzureConfigDoc.Fields[12].Type = "bool" AzureConfigDoc.Fields[12].Note = "" - AzureConfigDoc.Fields[12].Description = "Expected value for the field 'idkeydigest' in the AMD SEV-SNP attestation report. Only usable with ConfidentialVMs. See 4.6 and 7.3 in: https://www.amd.com/system/files/TechDocs/56860.pdf" - AzureConfigDoc.Fields[12].Comments[encoder.LineComment] = "Expected value for the field 'idkeydigest' in the AMD SEV-SNP attestation report. Only usable with ConfidentialVMs. See 4.6 and 7.3 in: https://www.amd.com/system/files/TechDocs/56860.pdf" - AzureConfigDoc.Fields[13].Name = "enforceIdKeyDigest" - AzureConfigDoc.Fields[13].Type = "bool" + AzureConfigDoc.Fields[12].Description = "Enable secure boot for VMs. If enabled, the OS image has to include a virtual machine guest state (VMGS) blob." + AzureConfigDoc.Fields[12].Comments[encoder.LineComment] = "Enable secure boot for VMs. If enabled, the OS image has to include a virtual machine guest state (VMGS) blob." + AzureConfigDoc.Fields[13].Name = "idKeyDigest" + AzureConfigDoc.Fields[13].Type = "string" AzureConfigDoc.Fields[13].Note = "" - AzureConfigDoc.Fields[13].Description = "Enforce the specified idKeyDigest value during remote attestation." - AzureConfigDoc.Fields[13].Comments[encoder.LineComment] = "Enforce the specified idKeyDigest value during remote attestation." - AzureConfigDoc.Fields[14].Name = "confidentialVM" + AzureConfigDoc.Fields[13].Description = "Expected value for the field 'idkeydigest' in the AMD SEV-SNP attestation report. Only usable with ConfidentialVMs. See 4.6 and 7.3 in: https://www.amd.com/system/files/TechDocs/56860.pdf" + AzureConfigDoc.Fields[13].Comments[encoder.LineComment] = "Expected value for the field 'idkeydigest' in the AMD SEV-SNP attestation report. Only usable with ConfidentialVMs. See 4.6 and 7.3 in: https://www.amd.com/system/files/TechDocs/56860.pdf" + AzureConfigDoc.Fields[14].Name = "enforceIdKeyDigest" AzureConfigDoc.Fields[14].Type = "bool" AzureConfigDoc.Fields[14].Note = "" - AzureConfigDoc.Fields[14].Description = "Use Confidential VMs. If set to false, Trusted Launch VMs are used instead. See: https://docs.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview" - AzureConfigDoc.Fields[14].Comments[encoder.LineComment] = "Use Confidential VMs. If set to false, Trusted Launch VMs are used instead. See: https://docs.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview" - AzureConfigDoc.Fields[15].Name = "secureBoot" - AzureConfigDoc.Fields[15].Type = "bool" + AzureConfigDoc.Fields[14].Description = "Enforce the specified idKeyDigest value during remote attestation." + AzureConfigDoc.Fields[14].Comments[encoder.LineComment] = "Enforce the specified idKeyDigest value during remote attestation." + AzureConfigDoc.Fields[15].Name = "measurements" + AzureConfigDoc.Fields[15].Type = "Measurements" AzureConfigDoc.Fields[15].Note = "" - AzureConfigDoc.Fields[15].Description = "Enable secure boot for VMs. If enabled, the OS image has to include a virtual machine guest state (VMGS) blob." - AzureConfigDoc.Fields[15].Comments[encoder.LineComment] = "Enable secure boot for VMs. If enabled, the OS image has to include a virtual machine guest state (VMGS) blob." + AzureConfigDoc.Fields[15].Description = "Expected confidential VM measurements." + AzureConfigDoc.Fields[15].Comments[encoder.LineComment] = "Expected confidential VM measurements." + AzureConfigDoc.Fields[16].Name = "enforcedMeasurements" + AzureConfigDoc.Fields[16].Type = "[]uint32" + AzureConfigDoc.Fields[16].Note = "" + AzureConfigDoc.Fields[16].Description = "List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning." + AzureConfigDoc.Fields[16].Comments[encoder.LineComment] = "List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning." GCPConfigDoc.Type = "GCPConfig" GCPConfigDoc.Comments[encoder.LineComment] = "GCPConfig are GCP specific configuration values used by the CLI." @@ -299,7 +304,7 @@ func init() { FieldName: "gcp", }, } - GCPConfigDoc.Fields = make([]encoder.Doc, 9) + GCPConfigDoc.Fields = make([]encoder.Doc, 10) GCPConfigDoc.Fields[0].Name = "project" GCPConfigDoc.Fields[0].Type = "string" GCPConfigDoc.Fields[0].Note = "" @@ -335,16 +340,21 @@ func init() { GCPConfigDoc.Fields[6].Note = "" GCPConfigDoc.Fields[6].Description = "Type of a node's state disk. The type influences boot time and I/O performance. See: https://cloud.google.com/compute/docs/disks#disk-types" GCPConfigDoc.Fields[6].Comments[encoder.LineComment] = "Type of a node's state disk. The type influences boot time and I/O performance. See: https://cloud.google.com/compute/docs/disks#disk-types" - GCPConfigDoc.Fields[7].Name = "measurements" - GCPConfigDoc.Fields[7].Type = "Measurements" + GCPConfigDoc.Fields[7].Name = "deployCSIDriver" + GCPConfigDoc.Fields[7].Type = "bool" GCPConfigDoc.Fields[7].Note = "" - GCPConfigDoc.Fields[7].Description = "Expected confidential VM measurements." - GCPConfigDoc.Fields[7].Comments[encoder.LineComment] = "Expected confidential VM measurements." - GCPConfigDoc.Fields[8].Name = "enforcedMeasurements" - GCPConfigDoc.Fields[8].Type = "[]uint32" + GCPConfigDoc.Fields[7].Description = "Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage" + GCPConfigDoc.Fields[7].Comments[encoder.LineComment] = "Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage" + GCPConfigDoc.Fields[8].Name = "measurements" + GCPConfigDoc.Fields[8].Type = "Measurements" GCPConfigDoc.Fields[8].Note = "" - GCPConfigDoc.Fields[8].Description = "List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning." - GCPConfigDoc.Fields[8].Comments[encoder.LineComment] = "List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning." + GCPConfigDoc.Fields[8].Description = "Expected confidential VM measurements." + GCPConfigDoc.Fields[8].Comments[encoder.LineComment] = "Expected confidential VM measurements." + GCPConfigDoc.Fields[9].Name = "enforcedMeasurements" + GCPConfigDoc.Fields[9].Type = "[]uint32" + GCPConfigDoc.Fields[9].Note = "" + GCPConfigDoc.Fields[9].Description = "List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning." + GCPConfigDoc.Fields[9].Comments[encoder.LineComment] = "List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning." QEMUConfigDoc.Type = "QEMUConfig" QEMUConfigDoc.Comments[encoder.LineComment] = "QEMUConfig holds config information for QEMU based Constellation deployments."