From 71c236a65ae00be6662b42d8c0da526d792315c8 Mon Sep 17 00:00:00 2001 From: Chaitanya Kandagatla Date: Mon, 24 Aug 2026 17:18:36 -0500 Subject: [PATCH] [release-5.0] OCPBUGS-114002: GCP-1074: feat(gcp-pd): enable HyperShift support for GCP PD CSI driver operator Enables HyperShift asset generation and runtime support for the GCP PD CSI driver operator: - Add --guest-kubeconfig flag so the operator can run against a HyperShift guest cluster. - Remove StandaloneOnly gating in GetGCPPDGeneratorConfig and generate the hypershift asset overlay alongside standalone. - Add controller_add_hypershift_controller_minter.yaml patch: wires the token-minter sidecar and hosted-kubeconfig volume, fixes the GOOGLE_APPLICATION_CREDENTIALS filename mismatch with HyperShift's WIF credentials secret, disables hostNetwork (blocked by GKE Autopilot), sets explicit ephemeral-storage requests per container (GKE Autopilot pod-level cap), and disables the node service on the controller (--run-node-service=false, since hostNetwork is off). - Remove the HyperShift-unsupported error in GetGCPPDOperatorControllerConfig and gate OldControllerPrivilegedBindingRemoval to Standalone only. - Add unit tests covering Standalone vs HyperShift controller config. make update run against release-5.0 to regenerate assets. Co-authored-by: Cursor (cherry picked from commit 81451bc3b161a1c5a9e7dd5ff8884f6a6d802989) --- .../generated/hypershift/cabundle_cm.yaml | 13 + .../generated/hypershift/controller.yaml | 453 ++++++++++++++++++ .../controller_hostnetwork_binding.yaml | 18 + .../generated/hypershift/controller_pdb.yaml | 17 + .../generated/hypershift/controller_sa.yaml | 14 + .../generated/hypershift/csidriver.yaml | 19 + .../hypershift/hostnetwork_role.yaml | 25 + .../hypershift/kube_rbac_proxy_binding.yaml | 19 + .../hypershift/kube_rbac_proxy_role.yaml | 18 + .../lease_leader_election_binding.yaml | 20 + .../lease_leader_election_role.yaml | 24 + .../hypershift/main_attacher_binding.yaml | 19 + .../hypershift/main_provisioner_binding.yaml | 19 + .../hypershift/main_resizer_binding.yaml | 19 + .../hypershift/main_snapshotter_binding.yaml | 19 + .../generated/hypershift/manifests.yaml | 33 ++ .../gcp-pd/generated/hypershift/node.yaml | 206 ++++++++ .../hypershift/node_privileged_binding.yaml | 18 + .../gcp-pd/generated/hypershift/node_sa.yaml | 11 + .../generated/hypershift/privileged_role.yaml | 20 + .../hypershift/prometheus_binding.yaml | 20 + .../generated/hypershift/prometheus_role.yaml | 23 + .../gcp-pd/generated/hypershift/service.yaml | 41 ++ .../generated/hypershift/storageclass.yaml | 19 + .../storageclass_hyperdisk_balanced.yaml | 19 + .../storageclass_reader_resizer_binding.yaml | 19 + .../hypershift/storageclass_ssd.yaml | 17 + ...butesclass_reader_provisioner_binding.yaml | 19 + ...ttributesclass_reader_resizer_binding.yaml | 19 + ...mesnapshot_reader_provisioner_binding.yaml | 19 + .../hypershift/volumesnapshotclass.yaml | 14 + .../volumesnapshotclass_images.yaml | 14 + .../generated/standalone/controller.yaml | 1 + ...ller_add_hypershift_controller_minter.yaml | 143 ++++++ cmd/gcp-pd-csi-driver-operator/main.go | 6 +- pkg/driver/gcp-pd/gcp_pd.go | 49 +- pkg/driver/gcp-pd/hypershift_test.go | 68 +++ 37 files changed, 1491 insertions(+), 23 deletions(-) create mode 100644 assets/overlays/gcp-pd/generated/hypershift/cabundle_cm.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/controller.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/controller_hostnetwork_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/controller_pdb.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/controller_sa.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/csidriver.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/hostnetwork_role.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/kube_rbac_proxy_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/kube_rbac_proxy_role.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/lease_leader_election_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/lease_leader_election_role.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/main_attacher_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/main_provisioner_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/main_resizer_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/main_snapshotter_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/manifests.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/node.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/node_privileged_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/node_sa.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/privileged_role.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/prometheus_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/prometheus_role.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/service.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/storageclass.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/storageclass_hyperdisk_balanced.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/storageclass_reader_resizer_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/storageclass_ssd.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/volumeattributesclass_reader_provisioner_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/volumeattributesclass_reader_resizer_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/volumesnapshot_reader_provisioner_binding.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/volumesnapshotclass.yaml create mode 100644 assets/overlays/gcp-pd/generated/hypershift/volumesnapshotclass_images.yaml create mode 100644 assets/overlays/gcp-pd/patches/controller_add_hypershift_controller_minter.yaml create mode 100644 pkg/driver/gcp-pd/hypershift_test.go diff --git a/assets/overlays/gcp-pd/generated/hypershift/cabundle_cm.yaml b/assets/overlays/gcp-pd/generated/hypershift/cabundle_cm.yaml new file mode 100644 index 000000000..ea19ef85c --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/cabundle_cm.yaml @@ -0,0 +1,13 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/cabundle_cm.yaml +# +# + +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + config.openshift.io/inject-trusted-cabundle: "true" + name: gcp-pd-csi-driver-trusted-ca-bundle + namespace: ${NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/controller.yaml b/assets/overlays/gcp-pd/generated/hypershift/controller.yaml new file mode 100644 index 000000000..b3ea258de --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/controller.yaml @@ -0,0 +1,453 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/controller.yaml +# Applied strategic merge patch overlays/gcp-pd/patches/controller_add_driver.yaml +# provisioner.yaml: Loaded from common/sidecars/provisioner.yaml +# provisioner.yaml: Added arguments [--default-fstype=ext4 --feature-gates=Topology=true --extra-create-metadata=true --timeout=250s --controller-publish-readonly] +# provisioner.yaml: Applied JSON patch common/hypershift/sidecar_add_kubeconfig.yaml.patch +# Applied strategic merge patch provisioner.yaml +# attacher.yaml: Loaded from common/sidecars/attacher.yaml +# attacher.yaml: Added arguments [--timeout=250s] +# attacher.yaml: Applied JSON patch common/hypershift/sidecar_add_kubeconfig.yaml.patch +# Applied strategic merge patch attacher.yaml +# resizer.yaml: Loaded from common/sidecars/resizer.yaml +# resizer.yaml: Applied JSON patch common/hypershift/sidecar_add_kubeconfig.yaml.patch +# Applied strategic merge patch resizer.yaml +# snapshotter.yaml: Loaded from common/sidecars/snapshotter.yaml +# snapshotter.yaml: Added arguments [--timeout=300s] +# snapshotter.yaml: Applied JSON patch common/hypershift/sidecar_add_kubeconfig.yaml.patch +# Applied strategic merge patch snapshotter.yaml +# pod_network_livenessprobe.yaml: Loaded from common/sidecars/pod_network_livenessprobe.yaml +# pod_network_livenessprobe.yaml: Added arguments [--probe-timeout=3s] +# Applied strategic merge patch pod_network_livenessprobe.yaml +# Applied strategic merge patch common/hypershift/controller_add_affinity_tolerations.yaml +# Applied JSON patch common/hypershift/controller_add_kubeconfig_volume.yaml.patch +# Applied strategic merge patch common/hypershift/controller_add_hypershift_managed_by_label.yaml +# Applied strategic merge patch common/hypershift/controller_add_hypershift_desired_version_annotation.yaml +# Applied strategic merge patch common/readOnlyRootFilesystem.yaml +# Applied strategic merge patch overlays/gcp-pd/patches/controller_add_hypershift_controller_minter.yaml +# +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + config.openshift.io/inject-proxy: csi-driver + config.openshift.io/inject-proxy-cabundle: csi-driver + release.openshift.io/desired-version: ${RELEASE_VERSION} + labels: + hypershift.openshift.io/managed-by: cluster-storage-operator + name: gcp-pd-csi-driver-controller + namespace: ${NAMESPACE} +spec: + selector: + matchLabels: + app: gcp-pd-csi-driver-controller + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + annotations: + cluster-autoscaler.kubernetes.io/safe-to-evict-local-volumes: socket-dir + openshift.io/required-scc: hostnetwork-v2 + target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}' + labels: + app: gcp-pd-csi-driver-controller + hypershift.openshift.io/hosted-control-plane: ${NAMESPACE} + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: hypershift.openshift.io/control-plane + operator: In + values: + - "true" + weight: 50 + - preference: + matchExpressions: + - key: hypershift.openshift.io/cluster + operator: In + values: + - ${NAMESPACE} + weight: 100 + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + hypershift.openshift.io/hosted-control-plane: ${NAMESPACE} + topologyKey: kubernetes.io/hostname + weight: 100 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app: gcp-pd-csi-driver-controller + topologyKey: kubernetes.io/hostname + weight: 100 + containers: + - args: + - --endpoint=$(CSI_ENDPOINT) + - --logtostderr + - --v=${LOG_LEVEL} + - --enable-storage-pools=true + - --allow-hdha-provisioning=true + - --supports-dynamic-throughput-provisioning=hyperdisk-balanced,hyperdisk-throughput,hyperdisk-ml + - --supports-dynamic-iops-provisioning=hyperdisk-balanced,hyperdisk-extreme + - --run-node-service=false + - --cloud-config=/etc/gcp-cloud-config/cloud.conf + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /etc/cloud-sa/application_default_credentials.json + - name: CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + image: ${DRIVER_IMAGE} + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 3 + name: csi-driver + ports: + - containerPort: 10301 + name: healthz + protocol: TCP + resources: + requests: + cpu: 10m + ephemeral-storage: 20Mi + memory: 50Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/lib/csi/sockets/pluginproxy/ + name: socket-dir + - mountPath: /etc/cloud-sa + name: cloud-sa-volume + readOnly: true + - mountPath: /var/run/secrets/openshift/serviceaccount + name: bound-sa-token + readOnly: true + - mountPath: /etc/gcp-cloud-config + name: gcp-cloud-config + readOnly: true + - args: + - --csi-address=/var/lib/csi/sockets/pluginproxy/csi.sock + - --http-endpoint=localhost:8202 + - --leader-election + - --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION} + - --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE} + - --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD} + - --leader-election-namespace=${NODE_NAMESPACE} + - --v=${LOG_LEVEL} + - --default-fstype=ext4 + - --feature-gates=Topology=true + - --extra-create-metadata=true + - --timeout=250s + - --controller-publish-readonly + - --kubeconfig=$(KUBECONFIG) + env: + - name: KUBECONFIG + value: /etc/hosted-kubernetes/kubeconfig + image: ${PROVISIONER_IMAGE} + imagePullPolicy: IfNotPresent + name: csi-provisioner + resources: + requests: + cpu: 10m + ephemeral-storage: 10Mi + memory: 50Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/lib/csi/sockets/pluginproxy/ + name: socket-dir + - mountPath: /etc/hosted-kubernetes + name: hosted-kubeconfig + readOnly: true + - args: + - --secure-listen-address=0.0.0.0:9202 + - --upstream=http://127.0.0.1:8202/ + - --tls-cert-file=/etc/tls/private/tls.crt + - --tls-private-key-file=/etc/tls/private/tls.key + - --tls-cipher-suites=${TLS_CIPHER_SUITES} + - --tls-min-version=${TLS_MIN_VERSION} + - --logtostderr=true + image: ${KUBE_RBAC_PROXY_IMAGE} + imagePullPolicy: IfNotPresent + name: provisioner-kube-rbac-proxy + ports: + - containerPort: 9202 + name: provisioner-m + protocol: TCP + resources: + requests: + cpu: 10m + ephemeral-storage: 10Mi + memory: 20Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /etc/tls/private + name: metrics-serving-cert + - args: + - --csi-address=/var/lib/csi/sockets/pluginproxy/csi.sock + - --http-endpoint=localhost:8203 + - --leader-election + - --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION} + - --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE} + - --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD} + - --leader-election-namespace=${NODE_NAMESPACE} + - --v=${LOG_LEVEL} + - --timeout=250s + - --kubeconfig=$(KUBECONFIG) + env: + - name: KUBECONFIG + value: /etc/hosted-kubernetes/kubeconfig + image: ${ATTACHER_IMAGE} + imagePullPolicy: IfNotPresent + name: csi-attacher + resources: + requests: + cpu: 10m + ephemeral-storage: 10Mi + memory: 50Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/lib/csi/sockets/pluginproxy/ + name: socket-dir + - mountPath: /etc/hosted-kubernetes + name: hosted-kubeconfig + readOnly: true + - args: + - --secure-listen-address=0.0.0.0:9203 + - --upstream=http://127.0.0.1:8203/ + - --tls-cert-file=/etc/tls/private/tls.crt + - --tls-private-key-file=/etc/tls/private/tls.key + - --tls-cipher-suites=${TLS_CIPHER_SUITES} + - --tls-min-version=${TLS_MIN_VERSION} + - --logtostderr=true + image: ${KUBE_RBAC_PROXY_IMAGE} + imagePullPolicy: IfNotPresent + name: attacher-kube-rbac-proxy + ports: + - containerPort: 9203 + name: attacher-m + protocol: TCP + resources: + requests: + cpu: 10m + ephemeral-storage: 10Mi + memory: 20Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /etc/tls/private + name: metrics-serving-cert + - args: + - --csi-address=/var/lib/csi/sockets/pluginproxy/csi.sock + - --http-endpoint=localhost:8204 + - --leader-election + - --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION} + - --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE} + - --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD} + - --leader-election-namespace=${NODE_NAMESPACE} + - --v=${LOG_LEVEL} + - --kubeconfig=$(KUBECONFIG) + env: + - name: KUBECONFIG + value: /etc/hosted-kubernetes/kubeconfig + image: ${RESIZER_IMAGE} + imagePullPolicy: IfNotPresent + name: csi-resizer + resources: + requests: + cpu: 10m + ephemeral-storage: 10Mi + memory: 50Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/lib/csi/sockets/pluginproxy/ + name: socket-dir + - mountPath: /etc/hosted-kubernetes + name: hosted-kubeconfig + readOnly: true + - args: + - --secure-listen-address=0.0.0.0:9204 + - --upstream=http://127.0.0.1:8204/ + - --tls-cert-file=/etc/tls/private/tls.crt + - --tls-private-key-file=/etc/tls/private/tls.key + - --tls-cipher-suites=${TLS_CIPHER_SUITES} + - --tls-min-version=${TLS_MIN_VERSION} + - --logtostderr=true + image: ${KUBE_RBAC_PROXY_IMAGE} + imagePullPolicy: IfNotPresent + name: resizer-kube-rbac-proxy + ports: + - containerPort: 9204 + name: resizer-m + protocol: TCP + resources: + requests: + cpu: 10m + ephemeral-storage: 10Mi + memory: 20Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /etc/tls/private + name: metrics-serving-cert + - args: + - --csi-address=/var/lib/csi/sockets/pluginproxy/csi.sock + - --metrics-address=localhost:8205 + - --leader-election + - --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION} + - --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE} + - --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD} + - --leader-election-namespace=${NODE_NAMESPACE} + - --v=${LOG_LEVEL} + - --timeout=300s + - --kubeconfig=$(KUBECONFIG) + env: + - name: KUBECONFIG + value: /etc/hosted-kubernetes/kubeconfig + image: ${SNAPSHOTTER_IMAGE} + imagePullPolicy: IfNotPresent + name: csi-snapshotter + resources: + requests: + cpu: 10m + ephemeral-storage: 10Mi + memory: 50Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/lib/csi/sockets/pluginproxy/ + name: socket-dir + - mountPath: /etc/hosted-kubernetes + name: hosted-kubeconfig + readOnly: true + - args: + - --secure-listen-address=0.0.0.0:9205 + - --upstream=http://127.0.0.1:8205/ + - --tls-cert-file=/etc/tls/private/tls.crt + - --tls-private-key-file=/etc/tls/private/tls.key + - --tls-cipher-suites=${TLS_CIPHER_SUITES} + - --tls-min-version=${TLS_MIN_VERSION} + - --logtostderr=true + image: ${KUBE_RBAC_PROXY_IMAGE} + imagePullPolicy: IfNotPresent + name: snapshotter-kube-rbac-proxy + ports: + - containerPort: 9205 + name: snapshotter-m + protocol: TCP + resources: + requests: + cpu: 10m + ephemeral-storage: 10Mi + memory: 20Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /etc/tls/private + name: metrics-serving-cert + - args: + - --csi-address=/csi/csi.sock + - --health-port=10301 + - --v=${LOG_LEVEL} + - --probe-timeout=3s + env: [] + image: ${LIVENESS_PROBE_IMAGE} + imagePullPolicy: IfNotPresent + name: csi-liveness-probe + resources: + requests: + cpu: 10m + ephemeral-storage: 10Mi + memory: 50Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /csi + name: socket-dir + - args: + - --service-account-namespace=openshift-cluster-csi-drivers + - --service-account-name=gcp-pd-csi-driver-controller-sa + - --token-audience=openshift + - --token-file=/var/run/secrets/openshift/serviceaccount/token + - --kubeconfig=/etc/hosted-kubernetes/kubeconfig + command: + - /usr/bin/control-plane-operator + - token-minter + image: ${HYPERSHIFT_IMAGE} + imagePullPolicy: IfNotPresent + name: token-minter + resources: + requests: + cpu: 10m + ephemeral-storage: 10Mi + memory: 10Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/run/secrets/openshift/serviceaccount + name: bound-sa-token + - mountPath: /etc/hosted-kubernetes + name: hosted-kubeconfig + readOnly: true + hostNetwork: false + priorityClassName: hypershift-control-plane + serviceAccount: gcp-pd-csi-driver-controller-sa + tolerations: + - effect: NoSchedule + key: hypershift.openshift.io/control-plane + operator: Equal + value: "true" + - effect: NoSchedule + key: hypershift.openshift.io/cluster + operator: Equal + value: ${NAMESPACE} + volumes: + - emptyDir: {} + name: socket-dir + - name: metrics-serving-cert + secret: + secretName: gcp-pd-csi-driver-controller-metrics-serving-cert + - name: cloud-sa-volume + secret: + secretName: gcp-pd-cloud-credentials + - emptyDir: + medium: Memory + name: bound-sa-token + - name: hosted-kubeconfig + secret: + defaultMode: 420 + secretName: service-network-admin-kubeconfig + - configMap: + name: gcp-pd-cloud-config + name: gcp-cloud-config diff --git a/assets/overlays/gcp-pd/generated/hypershift/controller_hostnetwork_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/controller_hostnetwork_binding.yaml new file mode 100644 index 000000000..a9250bc96 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/controller_hostnetwork_binding.yaml @@ -0,0 +1,18 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from overlays/gcp-pd/base/controller_hostnetwork_binding.yaml +# +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gcp-pd-controller-hostnetwork-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: gcp-pd-hostnetwork-role +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-controller-sa + namespace: ${NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/controller_pdb.yaml b/assets/overlays/gcp-pd/generated/hypershift/controller_pdb.yaml new file mode 100644 index 000000000..634bd7cbe --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/controller_pdb.yaml @@ -0,0 +1,17 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/controller_pdb.yaml +# +# + +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: gcp-pd-csi-driver-controller-pdb + namespace: ${NAMESPACE} +spec: + maxUnavailable: 1 + selector: + matchLabels: + app: gcp-pd-csi-driver-controller + unhealthyPodEvictionPolicy: AlwaysAllow diff --git a/assets/overlays/gcp-pd/generated/hypershift/controller_sa.yaml b/assets/overlays/gcp-pd/generated/hypershift/controller_sa.yaml new file mode 100644 index 000000000..6400b7c56 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/controller_sa.yaml @@ -0,0 +1,14 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/controller_sa.yaml +# Applied strategic merge patch common/hypershift/controller_sa_pull_secret.yaml +# +# + +apiVersion: v1 +imagePullSecrets: +- name: pull-secret +kind: ServiceAccount +metadata: + name: gcp-pd-csi-driver-controller-sa + namespace: ${NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/csidriver.yaml b/assets/overlays/gcp-pd/generated/hypershift/csidriver.yaml new file mode 100644 index 000000000..a4c1ec2c7 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/csidriver.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from overlays/gcp-pd/base/csidriver.yaml +# +# + +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: pd.csi.storage.gke.io +spec: + attachRequired: true + fsGroupPolicy: File + podInfoOnMount: false + requiresRepublish: false + seLinuxMount: true + storageCapacity: false + volumeLifecycleModes: + - Persistent diff --git a/assets/overlays/gcp-pd/generated/hypershift/hostnetwork_role.yaml b/assets/overlays/gcp-pd/generated/hypershift/hostnetwork_role.yaml new file mode 100644 index 000000000..b7519c171 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/hostnetwork_role.yaml @@ -0,0 +1,25 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from overlays/gcp-pd/base/hostnetwork_role.yaml +# +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: gcp-pd-hostnetwork-role +rules: +- apiGroups: + - security.openshift.io + resourceNames: + - hostnetwork-v2 + resources: + - securitycontextconstraints + verbs: + - use +- apiGroups: + - "" + resources: + - nodes + verbs: + - get diff --git a/assets/overlays/gcp-pd/generated/hypershift/kube_rbac_proxy_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/kube_rbac_proxy_binding.yaml new file mode 100644 index 000000000..ff1679b5a --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/kube_rbac_proxy_binding.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/kube_rbac_proxy_binding.yaml +# +# +# Allow kube-rbac-proxies to create tokenreviews to check Prometheus identity when scraping metrics. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gcp-pd-kube-rbac-proxy-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: gcp-pd-kube-rbac-proxy-role +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-controller-sa + namespace: ${NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/kube_rbac_proxy_role.yaml b/assets/overlays/gcp-pd/generated/hypershift/kube_rbac_proxy_role.yaml new file mode 100644 index 000000000..10ee3bb24 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/kube_rbac_proxy_role.yaml @@ -0,0 +1,18 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/kube_rbac_proxy_role.yaml +# +# +# Allow kube-rbac-proxies to create tokenreviews to check Prometheus identity when scraping metrics. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: gcp-pd-kube-rbac-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create diff --git a/assets/overlays/gcp-pd/generated/hypershift/lease_leader_election_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/lease_leader_election_binding.yaml new file mode 100644 index 000000000..3c60ef682 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/lease_leader_election_binding.yaml @@ -0,0 +1,20 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/lease_leader_election_binding.yaml +# +# +# Grant controller access to leases + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: gcp-pd-csi-driver-lease-leader-election + namespace: ${NODE_NAMESPACE} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: gcp-pd-csi-driver-lease-leader-election +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-controller-sa + namespace: ${NODE_NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/lease_leader_election_role.yaml b/assets/overlays/gcp-pd/generated/hypershift/lease_leader_election_role.yaml new file mode 100644 index 000000000..d71694513 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/lease_leader_election_role.yaml @@ -0,0 +1,24 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/lease_leader_election_role.yaml +# +# +# Role for electing leader by the operator + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: gcp-pd-csi-driver-lease-leader-election + namespace: ${NODE_NAMESPACE} +rules: +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - watch + - list + - delete + - update + - create diff --git a/assets/overlays/gcp-pd/generated/hypershift/main_attacher_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/main_attacher_binding.yaml new file mode 100644 index 000000000..db1a22bc3 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/main_attacher_binding.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/main_attacher_binding.yaml +# because it's needed by controller sidecar common/sidecars/attacher.yaml +# +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gcp-pd-csi-main-attacher-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openshift-csi-main-attacher-role +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-controller-sa + namespace: ${NODE_NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/main_provisioner_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/main_provisioner_binding.yaml new file mode 100644 index 000000000..e7a8813cc --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/main_provisioner_binding.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/main_provisioner_binding.yaml +# because it's needed by controller sidecar common/sidecars/provisioner.yaml +# +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gcp-pd-csi-main-provisioner-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openshift-csi-main-provisioner-role +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-controller-sa + namespace: ${NODE_NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/main_resizer_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/main_resizer_binding.yaml new file mode 100644 index 000000000..4cb68d049 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/main_resizer_binding.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/main_resizer_binding.yaml +# because it's needed by controller sidecar common/sidecars/resizer.yaml +# +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gcp-pd-csi-main-resizer-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openshift-csi-main-resizer-role +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-controller-sa + namespace: ${NODE_NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/main_snapshotter_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/main_snapshotter_binding.yaml new file mode 100644 index 000000000..cd2960a52 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/main_snapshotter_binding.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/main_snapshotter_binding.yaml +# because it's needed by controller sidecar common/sidecars/snapshotter.yaml +# +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gcp-pd-csi-main-snapshotter-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openshift-csi-main-snapshotter-role +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-controller-sa + namespace: ${NODE_NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/manifests.yaml b/assets/overlays/gcp-pd/generated/hypershift/manifests.yaml new file mode 100644 index 000000000..72a579438 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/manifests.yaml @@ -0,0 +1,33 @@ +controllerStaticAssetNames: +- cabundle_cm.yaml +- controller.yaml +- controller_pdb.yaml +- controller_sa.yaml +- service.yaml +guestStaticAssetNames: +- controller_hostnetwork_binding.yaml +- csidriver.yaml +- hostnetwork_role.yaml +- kube_rbac_proxy_binding.yaml +- kube_rbac_proxy_role.yaml +- lease_leader_election_binding.yaml +- lease_leader_election_role.yaml +- main_attacher_binding.yaml +- main_provisioner_binding.yaml +- main_resizer_binding.yaml +- main_snapshotter_binding.yaml +- node.yaml +- node_privileged_binding.yaml +- node_sa.yaml +- privileged_role.yaml +- prometheus_binding.yaml +- prometheus_role.yaml +- storageclass.yaml +- storageclass_hyperdisk_balanced.yaml +- storageclass_reader_resizer_binding.yaml +- storageclass_ssd.yaml +- volumeattributesclass_reader_provisioner_binding.yaml +- volumeattributesclass_reader_resizer_binding.yaml +- volumesnapshot_reader_provisioner_binding.yaml +- volumesnapshotclass.yaml +- volumesnapshotclass_images.yaml diff --git a/assets/overlays/gcp-pd/generated/hypershift/node.yaml b/assets/overlays/gcp-pd/generated/hypershift/node.yaml new file mode 100644 index 000000000..f2a6cc909 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/node.yaml @@ -0,0 +1,206 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/node.yaml +# Applied strategic merge patch overlays/gcp-pd/patches/node_add_driver.yaml +# node_driver_registrar.yaml: Loaded from common/sidecars/node_driver_registrar.yaml +# Applied strategic merge patch node_driver_registrar.yaml +# host_network_livenessprobe.yaml: Loaded from common/sidecars/host_network_livenessprobe.yaml +# host_network_livenessprobe.yaml: Added arguments [--probe-timeout=3s] +# Applied strategic merge patch host_network_livenessprobe.yaml +# Applied strategic merge patch common/readOnlyRootFilesystem.yaml +# +# + +apiVersion: apps/v1 +kind: DaemonSet +metadata: + annotations: + config.openshift.io/inject-proxy: csi-driver + config.openshift.io/inject-proxy-cabundle: csi-driver + name: gcp-pd-csi-driver-node + namespace: ${NODE_NAMESPACE} +spec: + selector: + matchLabels: + app: gcp-pd-csi-driver-node + template: + metadata: + annotations: + cluster-autoscaler.kubernetes.io/enable-ds-eviction: "false" + openshift.io/required-scc: privileged + target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}' + labels: + app: gcp-pd-csi-driver-node + spec: + containers: + - args: + - --endpoint=$(CSI_ENDPOINT) + - --logtostderr + - --v=${LOG_LEVEL} + - --enable-storage-pools=true + - --node-name=$(KUBE_NODE_NAME) + env: + - name: CSI_ENDPOINT + value: unix:/csi/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + image: ${DRIVER_IMAGE} + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 5 + httpGet: + host: 127.0.0.1 + path: /healthz + port: healthz + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 3 + name: csi-driver + ports: + - containerPort: 10300 + name: healthz + protocol: TCP + resources: + requests: + cpu: 10m + memory: 50Mi + securityContext: + privileged: true + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/lib/kubelet + mountPropagation: Bidirectional + name: kubelet-dir + - mountPath: /csi + name: socket-dir + - mountPath: /dev + name: device-dir + - mountPath: /etc/udev + name: udev-rules-etc + - mountPath: /lib/udev + name: udev-rules-lib + - mountPath: /run/udev + name: udev-socket + - mountPath: /sys + name: sys + - mountPath: /etc/selinux + name: etc-selinux + - args: + - --csi-address=/csi/csi.sock + - --kubelet-registration-path=/var/lib/kubelet/plugins/pd.csi.storage.gke.io/csi.sock + - --http-endpoint=127.0.0.1:10303 + - --v=${LOG_LEVEL} + env: [] + image: ${NODE_DRIVER_REGISTRAR_IMAGE} + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - /bin/sh + - -c + - rm -rf /registration/pd.csi.storage.gke.io-reg.sock /csi/csi.sock + livenessProbe: + failureThreshold: 5 + httpGet: + host: 127.0.0.1 + path: /healthz + port: rhealthz + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 3 + name: csi-node-driver-registrar + ports: + - containerPort: 10303 + name: rhealthz + protocol: TCP + resources: + requests: + cpu: 10m + memory: 50Mi + securityContext: + privileged: true + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /registration + name: registration-dir + - args: + - --csi-address=/csi/csi.sock + - --http-endpoint=127.0.0.1:10300 + - --v=${LOG_LEVEL} + - --probe-timeout=3s + env: [] + image: ${LIVENESS_PROBE_IMAGE} + imagePullPolicy: IfNotPresent + name: csi-liveness-probe + resources: + requests: + cpu: 10m + memory: 50Mi + securityContext: + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /csi + name: socket-dir + hostNetwork: true + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-node-critical + serviceAccount: gcp-pd-csi-driver-node-sa + tolerations: + - operator: Exists + volumes: + - hostPath: + path: /var/lib/kubelet + type: Directory + name: kubelet-dir + - hostPath: + path: /var/lib/kubelet/plugins/pd.csi.storage.gke.io/ + type: DirectoryOrCreate + name: socket-dir + - hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: Directory + name: registration-dir + - hostPath: + path: /dev + type: Directory + name: device-dir + - hostPath: + path: /etc/selinux + type: DirectoryOrCreate + name: etc-selinux + - hostPath: + path: /sys/fs + type: Directory + name: sys-fs + - name: metrics-serving-cert + secret: + secretName: gcp-pd-csi-driver-node-metrics-serving-cert + - hostPath: + path: /etc/udev + type: Directory + name: udev-rules-etc + - hostPath: + path: /lib/udev + type: Directory + name: udev-rules-lib + - hostPath: + path: /run/udev + type: Directory + name: udev-socket + - hostPath: + path: /sys + type: Directory + name: sys + updateStrategy: + rollingUpdate: + maxUnavailable: 10% + type: RollingUpdate diff --git a/assets/overlays/gcp-pd/generated/hypershift/node_privileged_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/node_privileged_binding.yaml new file mode 100644 index 000000000..1f74ae355 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/node_privileged_binding.yaml @@ -0,0 +1,18 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/node_privileged_binding.yaml +# +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gcp-pd-node-privileged-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: gcp-pd-privileged-role +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-node-sa + namespace: ${NODE_NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/node_sa.yaml b/assets/overlays/gcp-pd/generated/hypershift/node_sa.yaml new file mode 100644 index 000000000..5992ae351 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/node_sa.yaml @@ -0,0 +1,11 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/node_sa.yaml +# +# + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: gcp-pd-csi-driver-node-sa + namespace: ${NODE_NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/privileged_role.yaml b/assets/overlays/gcp-pd/generated/hypershift/privileged_role.yaml new file mode 100644 index 000000000..e01547de6 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/privileged_role.yaml @@ -0,0 +1,20 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/privileged_role.yaml +# +# +# TODO: create custom SCC with things that the AWS CSI driver needs + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: gcp-pd-privileged-role +rules: +- apiGroups: + - security.openshift.io + resourceNames: + - privileged + resources: + - securitycontextconstraints + verbs: + - use diff --git a/assets/overlays/gcp-pd/generated/hypershift/prometheus_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/prometheus_binding.yaml new file mode 100644 index 000000000..ba67080c8 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/prometheus_binding.yaml @@ -0,0 +1,20 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/prometheus_binding.yaml +# +# +# Grant cluster-monitoring access to the operator metrics service + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: gcp-pd-csi-driver-prometheus + namespace: ${NODE_NAMESPACE} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: gcp-pd-csi-driver-prometheus +subjects: +- kind: ServiceAccount + name: prometheus-k8s + namespace: openshift-monitoring diff --git a/assets/overlays/gcp-pd/generated/hypershift/prometheus_role.yaml b/assets/overlays/gcp-pd/generated/hypershift/prometheus_role.yaml new file mode 100644 index 000000000..dbb55778b --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/prometheus_role.yaml @@ -0,0 +1,23 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/prometheus_role.yaml +# +# +# Role for accessing metrics exposed by the operator + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: gcp-pd-csi-driver-prometheus + namespace: ${NODE_NAMESPACE} +rules: +- apiGroups: + - "" + resources: + - services + - endpoints + - pods + verbs: + - get + - list + - watch diff --git a/assets/overlays/gcp-pd/generated/hypershift/service.yaml b/assets/overlays/gcp-pd/generated/hypershift/service.yaml new file mode 100644 index 000000000..245d99bc2 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/service.yaml @@ -0,0 +1,41 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/controller_metrics_service.yaml +# Applied strategic merge patch common/metrics/service_add_port.yaml +# Applied strategic merge patch common/metrics/service_add_port.yaml +# Applied strategic merge patch common/metrics/service_add_port.yaml +# Applied strategic merge patch common/metrics/service_add_port.yaml +# +# + +apiVersion: v1 +kind: Service +metadata: + annotations: + service.beta.openshift.io/serving-cert-secret-name: gcp-pd-csi-driver-controller-metrics-serving-cert + labels: + app: gcp-pd-csi-driver-controller-metrics + name: gcp-pd-csi-driver-controller-metrics + namespace: ${NAMESPACE} +spec: + ports: + - name: provisioner-m + port: 9202 + protocol: TCP + targetPort: provisioner-m + - name: attacher-m + port: 9203 + protocol: TCP + targetPort: attacher-m + - name: resizer-m + port: 9204 + protocol: TCP + targetPort: resizer-m + - name: snapshotter-m + port: 9205 + protocol: TCP + targetPort: snapshotter-m + selector: + app: gcp-pd-csi-driver-controller + sessionAffinity: None + type: ClusterIP diff --git a/assets/overlays/gcp-pd/generated/hypershift/storageclass.yaml b/assets/overlays/gcp-pd/generated/hypershift/storageclass.yaml new file mode 100644 index 000000000..c9f68a04e --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/storageclass.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from overlays/gcp-pd/base/storageclass.yaml +# +# + +allowVolumeExpansion: true +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + storageclass.kubernetes.io/is-default-class: "true" + name: standard-csi +parameters: + replication-type: none + type: pd-standard +provisioner: pd.csi.storage.gke.io +reclaimPolicy: Delete +volumeBindingMode: WaitForFirstConsumer diff --git a/assets/overlays/gcp-pd/generated/hypershift/storageclass_hyperdisk_balanced.yaml b/assets/overlays/gcp-pd/generated/hypershift/storageclass_hyperdisk_balanced.yaml new file mode 100644 index 000000000..55d39b5bc --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/storageclass_hyperdisk_balanced.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from overlays/gcp-pd/base/storageclass_hyperdisk_balanced.yaml +# +# + +allowVolumeExpansion: true +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + storageclass.kubernetes.io/is-default-class: "true" + name: hyperdisk-balanced +parameters: + replication-type: none + type: hyperdisk-balanced +provisioner: pd.csi.storage.gke.io +reclaimPolicy: Delete +volumeBindingMode: WaitForFirstConsumer diff --git a/assets/overlays/gcp-pd/generated/hypershift/storageclass_reader_resizer_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/storageclass_reader_resizer_binding.yaml new file mode 100644 index 000000000..24a0a46e1 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/storageclass_reader_resizer_binding.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/storageclass_reader_resizer_binding.yaml +# because it's needed by controller sidecar common/sidecars/resizer.yaml +# +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gcp-pd-csi-storageclass-reader-resizer-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openshift-csi-resizer-storageclass-reader-role +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-controller-sa + namespace: ${NODE_NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/storageclass_ssd.yaml b/assets/overlays/gcp-pd/generated/hypershift/storageclass_ssd.yaml new file mode 100644 index 000000000..72d9b3880 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/storageclass_ssd.yaml @@ -0,0 +1,17 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from overlays/gcp-pd/base/storageclass_ssd.yaml +# +# + +allowVolumeExpansion: true +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: ssd-csi +parameters: + replication-type: none + type: pd-ssd +provisioner: pd.csi.storage.gke.io +reclaimPolicy: Delete +volumeBindingMode: WaitForFirstConsumer diff --git a/assets/overlays/gcp-pd/generated/hypershift/volumeattributesclass_reader_provisioner_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/volumeattributesclass_reader_provisioner_binding.yaml new file mode 100644 index 000000000..fad362178 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/volumeattributesclass_reader_provisioner_binding.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/volumeattributesclass_reader_provisioner_binding.yaml +# because it's needed by controller sidecar common/sidecars/provisioner.yaml +# +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gcp-pd-csi-volumeattributesclass-reader-provisioner-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openshift-csi-provisioner-volumeattributesclass-reader-role +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-controller-sa + namespace: ${NODE_NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/volumeattributesclass_reader_resizer_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/volumeattributesclass_reader_resizer_binding.yaml new file mode 100644 index 000000000..666a81782 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/volumeattributesclass_reader_resizer_binding.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/volumeattributesclass_reader_resizer_binding.yaml +# because it's needed by controller sidecar common/sidecars/resizer.yaml +# +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gcp-pd-csi-volumeattributesclass-reader-resizer-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openshift-csi-resizer-volumeattributesclass-reader-role +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-controller-sa + namespace: ${NODE_NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/volumesnapshot_reader_provisioner_binding.yaml b/assets/overlays/gcp-pd/generated/hypershift/volumesnapshot_reader_provisioner_binding.yaml new file mode 100644 index 000000000..04980849d --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/volumesnapshot_reader_provisioner_binding.yaml @@ -0,0 +1,19 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from base/rbac/volumesnapshot_reader_provisioner_binding.yaml +# because it's needed by controller sidecar common/sidecars/provisioner.yaml +# +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gcp-pd-csi-volumesnapshot-reader-provisioner-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openshift-csi-provisioner-volumesnapshot-reader-role +subjects: +- kind: ServiceAccount + name: gcp-pd-csi-driver-controller-sa + namespace: ${NODE_NAMESPACE} diff --git a/assets/overlays/gcp-pd/generated/hypershift/volumesnapshotclass.yaml b/assets/overlays/gcp-pd/generated/hypershift/volumesnapshotclass.yaml new file mode 100644 index 000000000..ac6f40c48 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/volumesnapshotclass.yaml @@ -0,0 +1,14 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from overlays/gcp-pd/base/volumesnapshotclass.yaml +# +# + +apiVersion: snapshot.storage.k8s.io/v1 +deletionPolicy: Delete +driver: pd.csi.storage.gke.io +kind: VolumeSnapshotClass +metadata: + annotations: + snapshot.storage.kubernetes.io/is-default-class: "true" + name: csi-gce-pd-vsc diff --git a/assets/overlays/gcp-pd/generated/hypershift/volumesnapshotclass_images.yaml b/assets/overlays/gcp-pd/generated/hypershift/volumesnapshotclass_images.yaml new file mode 100644 index 000000000..ed9018819 --- /dev/null +++ b/assets/overlays/gcp-pd/generated/hypershift/volumesnapshotclass_images.yaml @@ -0,0 +1,14 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from overlays/gcp-pd/base/volumesnapshotclass_images.yaml +# +# + +apiVersion: snapshot.storage.k8s.io/v1 +deletionPolicy: Delete +driver: pd.csi.storage.gke.io +kind: VolumeSnapshotClass +metadata: + name: csi-gce-pd-vsc-images +parameters: + snapshot-type: images diff --git a/assets/overlays/gcp-pd/generated/standalone/controller.yaml b/assets/overlays/gcp-pd/generated/standalone/controller.yaml index ad595ba0c..4aa5d0e2a 100644 --- a/assets/overlays/gcp-pd/generated/standalone/controller.yaml +++ b/assets/overlays/gcp-pd/generated/standalone/controller.yaml @@ -17,6 +17,7 @@ # pod_network_livenessprobe.yaml: Added arguments [--probe-timeout=3s] # Applied strategic merge patch pod_network_livenessprobe.yaml # Applied strategic merge patch common/standalone/controller_add_affinity.yaml +# Applied strategic merge patch common/readOnlyRootFilesystem.yaml # # diff --git a/assets/overlays/gcp-pd/patches/controller_add_hypershift_controller_minter.yaml b/assets/overlays/gcp-pd/patches/controller_add_hypershift_controller_minter.yaml new file mode 100644 index 000000000..f9b2457e5 --- /dev/null +++ b/assets/overlays/gcp-pd/patches/controller_add_hypershift_controller_minter.yaml @@ -0,0 +1,143 @@ +spec: + template: + spec: + # hostNetwork is set unconditionally in controller_add_driver.yaml, but the controller only + # ever needs it to reach a node-local link-local metadata service (e.g. GCE's instance + # metadata server), which HyperShift's controller never does: it authenticates purely via + # WIF through the token-minter sidecar above, over normal outbound networking. Disabling it + # here (HyperShift-only, standalone is left untouched) mirrors the Azure File driver, whose + # controller-side hostNetwork was removed for the same reason (see + # 9e370b7f "Change ports and remove hostNetwork from controller pods"), and is required for + # the controller to schedule at all on GKE Autopilot management clusters, which reject + # hostNetwork pods outright. + hostNetwork: false + # None of these containers write meaningful amounts of data to their writable layer (the + # only on-disk volume is the tiny CSI unix-domain socket in socket-dir); they only need + # room for a termination log. Without an explicit request, GKE Autopilot injects a 1Gi + # ephemeral-storage request per container, and with 11 containers in this pod that pushes + # the total past Autopilot's 10Gi per-workload cap (autogke-pod-limit-constraints), + # blocking the Deployment from ever being created on GKE Autopilot management clusters. + # Setting small explicit requests here (HyperShift-only; standalone is untouched, since it + # doesn't run on GKE Autopilot) avoids the default injection entirely. + containers: + # HyperShift populates the gcp-pd-cloud-credentials secret with a WIF external_account + # config keyed "application_default_credentials.json" (see hypershift-operator's + # GCPPDCloudCredentialsSecret/ReconcileCredentials), not "service_account.json" as used + # by the standalone CCO-managed secret. Override the env var here so the driver reads + # the file that actually exists in HyperShift. + - name: csi-driver + # The driver's --run-node-service defaults to true, so without this flag the + # controller binary also stands up a node service (mount manager, device utils, and a + # metadataservice.NewMetadataService() call that queries the "instance/machine-type" + # GCE metadata attribute). On a real GCE VM with hostNetwork, that query bypasses GKE's + # metadata-server DaemonSet and succeeds; here the pod isn't on hostNetwork (see above) + # and GKE's metadata server only exposes a fixed attribute subset that excludes + # machine-type, so the driver fails fast with "failed to get machine-type: metadata: + # GCE metadata \"instance/machine-type\" not defined". The controller pod never needs a + # node service (it's not the thing that mounts volumes), so disable it outright. This is + # arguably also correct for standalone, but is scoped to HyperShift here to avoid + # touching already-shipped standalone behavior. args replaces the full list (strategic + # merge does not merge unkeyed string slices), so repeat the base args here. + # + # --cloud-config is required for the same reason: with no config file, the driver's + # getProjectAndZone() falls back to the GCE metadata server for both project and zone + # (pkg/gce-cloud-provider/compute/gce.go). On HyperShift the controller pod runs on a + # management-cluster node, so that metadata call resolves to the management cluster's + # own GCP project rather than the tenant's, and every subsequent Compute API call is + # scoped to the wrong project even though WIF is correctly impersonating a + # tenant-project service account. gcp-pd-cloud-config is expected to be created + # out-of-band from HostedControlPlane.Spec.Platform.GCP.Project (analogous to Azure's + # adaptAzureCSIDiskSecret) - not by csi-operator, which has no HostedControlPlane API + # visibility. + args: + - --endpoint=$(CSI_ENDPOINT) + - --logtostderr + - --v=${LOG_LEVEL} + - --enable-storage-pools=true + - --allow-hdha-provisioning=true + - --supports-dynamic-throughput-provisioning=hyperdisk-balanced,hyperdisk-throughput,hyperdisk-ml + - --supports-dynamic-iops-provisioning=hyperdisk-balanced,hyperdisk-extreme + - --run-node-service=false + - --cloud-config=/etc/gcp-cloud-config/cloud.conf + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /etc/cloud-sa/application_default_credentials.json + resources: + requests: + ephemeral-storage: 20Mi + volumeMounts: + - mountPath: /etc/gcp-cloud-config + name: gcp-cloud-config + readOnly: true + + - name: csi-provisioner + resources: + requests: + ephemeral-storage: 10Mi + - name: provisioner-kube-rbac-proxy + resources: + requests: + ephemeral-storage: 10Mi + - name: csi-attacher + resources: + requests: + ephemeral-storage: 10Mi + - name: attacher-kube-rbac-proxy + resources: + requests: + ephemeral-storage: 10Mi + - name: csi-resizer + resources: + requests: + ephemeral-storage: 10Mi + - name: resizer-kube-rbac-proxy + resources: + requests: + ephemeral-storage: 10Mi + - name: csi-snapshotter + resources: + requests: + ephemeral-storage: 10Mi + - name: snapshotter-kube-rbac-proxy + resources: + requests: + ephemeral-storage: 10Mi + - name: csi-liveness-probe + resources: + requests: + ephemeral-storage: 10Mi + + - name: token-minter + securityContext: + readOnlyRootFilesystem: true + args: + - --service-account-namespace=openshift-cluster-csi-drivers + - --service-account-name=gcp-pd-csi-driver-controller-sa + - --token-audience=openshift + - --token-file=/var/run/secrets/openshift/serviceaccount/token + - --kubeconfig=/etc/hosted-kubernetes/kubeconfig + command: + - /usr/bin/control-plane-operator + - token-minter + image: ${HYPERSHIFT_IMAGE} + imagePullPolicy: IfNotPresent + resources: + requests: + cpu: 10m + memory: 10Mi + ephemeral-storage: 10Mi + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/run/secrets/openshift/serviceaccount + name: bound-sa-token + - mountPath: /etc/hosted-kubernetes + name: hosted-kubeconfig + readOnly: true + volumes: + - name: bound-sa-token + emptyDir: + medium: Memory + projected: null # Explicity overwrite existing projected: with null in strategic merge patch + - name: gcp-cloud-config + configMap: + name: gcp-pd-cloud-config diff --git a/cmd/gcp-pd-csi-driver-operator/main.go b/cmd/gcp-pd-csi-driver-operator/main.go index eadc0c94e..7996ac4f7 100644 --- a/cmd/gcp-pd-csi-driver-operator/main.go +++ b/cmd/gcp-pd-csi-driver-operator/main.go @@ -20,6 +20,8 @@ func main() { os.Exit(code) } +var guestKubeconfig *string + func NewOperatorCommand() *cobra.Command { cmd := &cobra.Command{ Use: "gcp-pd-csi-driver-operator", @@ -37,6 +39,8 @@ func NewOperatorCommand() *cobra.Command { clock.RealClock{}, ).NewCommand() + guestKubeconfig = ctrlCmd.Flags().String("guest-kubeconfig", "", "Path to the guest kubeconfig file. This flag enables hypershift integration.") + ctrlCmd.Use = "start" ctrlCmd.Short = "Start the GCP PD CSI Driver Operator" @@ -47,5 +51,5 @@ func NewOperatorCommand() *cobra.Command { func runCSIDriverOperator(ctx context.Context, controllerConfig *controllercmd.ControllerContext) error { opConfig := gcp_pd.GetGCPPDOperatorConfig() - return operator.RunOperator(ctx, controllerConfig, "", opConfig) + return operator.RunOperator(ctx, controllerConfig, *guestKubeconfig, opConfig) } diff --git a/pkg/driver/gcp-pd/gcp_pd.go b/pkg/driver/gcp-pd/gcp_pd.go index 38a9033cd..c1aa465b9 100644 --- a/pkg/driver/gcp-pd/gcp_pd.go +++ b/pkg/driver/gcp-pd/gcp_pd.go @@ -65,7 +65,6 @@ func GetGCPPDGeneratorConfig() *generator.CSIDriverGeneratorConfig { AssetPrefix: "gcp-pd-csi-driver", AssetShortPrefix: "gcp-pd", DriverName: "pd.csi.storage.gke.io", - StandaloneOnly: true, OutputDir: generatedAssetBase, ControllerConfig: &generator.ControlPlaneConfig{ @@ -100,8 +99,8 @@ func GetGCPPDGeneratorConfig() *generator.CSIDriverGeneratorConfig { "base/rbac/kube_rbac_proxy_role.yaml", "base/rbac/kube_rbac_proxy_binding.yaml", ), - AssetPatches: generator.NewAssetPatches(generator.StandaloneOnly, - "controller.yaml", "common/standalone/controller_add_affinity.yaml", + AssetPatches: commongenerator.DefaultAssetPatches.WithPatches(generator.HyperShiftOnly, + "controller.yaml", "overlays/gcp-pd/patches/controller_add_hypershift_controller_minter.yaml", ), }, @@ -157,27 +156,26 @@ func GetGCPPDOperatorConfig() *config.OperatorConfig { // GetGCPPDOperatorControllerConfig returns second half of runtime configuration of the CSI driver operator, // after a client connection + cluster flavour are established. func GetGCPPDOperatorControllerConfig(ctx context.Context, flavour generator.ClusterFlavour, c *clients.Clients) (*config.OperatorControllerConfig, error) { - if flavour != generator.FlavourStandalone { - klog.Error(nil, "Flavour HyperShift is not supported") - return nil, fmt.Errorf("Flavour HyperShift is not supported") - } - cfg := operator.NewDefaultOperatorControllerConfig(flavour, c, "GCPPD") - oldPrivilegedBindingController := staticresourcecontroller.NewStaticResourceController( - cfg.GetControllerName("OldControllerPrivilegedBindingRemoval"), - assets.ReadFile, - nil, - resourceapply.NewKubeClientHolder(c.KubeClient).WithDynamicClient(c.DynamicClient), - c.OperatorClient, - c.EventRecorder, - ).WithConditionalResources( - assets.ReadFile, - []string{customAssetBase + "/old_controller_privileged_binding.yaml"}, - func() bool { return false }, - func() bool { return true }, - ) - cfg.ExtraControlPlaneControllers = append(cfg.ExtraControlPlaneControllers, oldPrivilegedBindingController) + if flavour == generator.FlavourStandalone { + // One-time cleanup of a ClusterRoleBinding used by an old version of the operator. + // Not applicable to HyperShift, which never shipped the old binding. + oldPrivilegedBindingController := staticresourcecontroller.NewStaticResourceController( + cfg.GetControllerName("OldControllerPrivilegedBindingRemoval"), + assets.ReadFile, + nil, + resourceapply.NewKubeClientHolder(c.KubeClient).WithDynamicClient(c.DynamicClient), + c.OperatorClient, + c.EventRecorder, + ).WithConditionalResources( + assets.ReadFile, + []string{customAssetBase + "/old_controller_privileged_binding.yaml"}, + func() bool { return false }, + func() bool { return true }, + ) + cfg.ExtraControlPlaneControllers = append(cfg.ExtraControlPlaneControllers, oldPrivilegedBindingController) + } storageClassFiles, err := getStorageClassFiles(ctx, c.ConfigClientSet) if err != nil { @@ -203,6 +201,13 @@ func GetGCPPDOperatorControllerConfig(ctx context.Context, flavour generator.Clu cfg.DeploymentWatchedSecretNames = append(cfg.DeploymentWatchedSecretNames, cloudCredSecretName, metricsCertSecretName) cfg.AddDaemonSetHookBuilders(c, withCABundleDaemonSetHook, withClusterWideProxyDaemonSetHook) + // GCP HCP uses Workload Identity Federation exclusively: on HyperShift, the controller + // authenticates using a token minted for a guest-cluster service account (trusted by the WIF + // pool) rather than the control-plane pod's own (management-cluster-signed) token. The + // token-minter sidecar and its supporting volumes are added statically via + // controller_add_hypershift_controller_minter.yaml (see GetGCPPDGeneratorConfig), mirroring the + // AWS EBS driver - no runtime hook is needed here. + return cfg, nil } diff --git a/pkg/driver/gcp-pd/hypershift_test.go b/pkg/driver/gcp-pd/hypershift_test.go new file mode 100644 index 000000000..d530bbd76 --- /dev/null +++ b/pkg/driver/gcp-pd/hypershift_test.go @@ -0,0 +1,68 @@ +package gcp_pd + +import ( + "context" + "testing" + + configv1 "github.com/openshift/api/config/v1" + fakeconfig "github.com/openshift/client-go/config/clientset/versioned/fake" + "github.com/openshift/csi-operator/pkg/clients" + "github.com/openshift/csi-operator/pkg/generator" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// newTestClients returns fake Clients with an Infrastructure object already +// registered, so getStorageClassFiles() resolves immediately instead of +// polling. +func newTestClients(t *testing.T) *clients.Clients { + t.Helper() + cr := clients.GetFakeOperatorCR() + c := clients.NewFakeClients("clusters-test", cr) + infra := &configv1.Infrastructure{ + ObjectMeta: metav1.ObjectMeta{Name: globalInfrastructureName}, + Status: configv1.InfrastructureStatus{ + PlatformStatus: &configv1.PlatformStatus{ + GCP: &configv1.GCPPlatformStatus{Region: "us-central1"}, + }, + }, + } + if err := c.ConfigClientSet.(*fakeconfig.Clientset).Tracker().Add(infra); err != nil { + t.Fatalf("failed to seed fake Infrastructure: %v", err) + } + return c +} + +func TestGetGCPPDOperatorControllerConfig(t *testing.T) { + t.Run("When flavour is HyperShift it should no longer return an error", func(t *testing.T) { + c := newTestClients(t) + cfg, err := GetGCPPDOperatorControllerConfig(context.Background(), generator.FlavourHyperShift, c) + if err != nil { + t.Fatalf("expected no error for HyperShift flavour, got: %v", err) + } + if cfg == nil { + t.Fatalf("expected non-nil config for HyperShift flavour") + } + }) + + t.Run("When flavour is Standalone it should still register the old privileged binding cleanup controller", func(t *testing.T) { + c := newTestClients(t) + cfg, err := GetGCPPDOperatorControllerConfig(context.Background(), generator.FlavourStandalone, c) + if err != nil { + t.Fatalf("unexpected error for Standalone flavour: %v", err) + } + if len(cfg.ExtraControlPlaneControllers) != 1 { + t.Errorf("expected 1 extra control plane controller (old binding cleanup) for Standalone, got %d", len(cfg.ExtraControlPlaneControllers)) + } + }) + + t.Run("When flavour is HyperShift it should not register the standalone-only old privileged binding cleanup controller", func(t *testing.T) { + c := newTestClients(t) + cfg, err := GetGCPPDOperatorControllerConfig(context.Background(), generator.FlavourHyperShift, c) + if err != nil { + t.Fatalf("unexpected error for HyperShift flavour: %v", err) + } + if len(cfg.ExtraControlPlaneControllers) != 0 { + t.Errorf("expected 0 extra control plane controllers for HyperShift, got %d", len(cfg.ExtraControlPlaneControllers)) + } + }) +}