diff --git a/charts/internal/shoot-system-components/charts/csi-alicloud/templates/auth/csi-plugin-psp.yaml b/charts/internal/shoot-system-components/charts/csi-alicloud/templates/auth/csi-plugin-psp.yaml index 4a7e1d535..d2eb542f3 100644 --- a/charts/internal/shoot-system-components/charts/csi-alicloud/templates/auth/csi-plugin-psp.yaml +++ b/charts/internal/shoot-system-components/charts/csi-alicloud/templates/auth/csi-plugin-psp.yaml @@ -1,3 +1,4 @@ +{{- if not .Values.pspDisabled }} apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: @@ -22,3 +23,4 @@ spec: fsGroup: rule: RunAsAny readOnlyRootFilesystem: false +{{- end }} diff --git a/charts/internal/shoot-system-components/charts/csi-alicloud/templates/auth/csi-plugin-rbac.yaml b/charts/internal/shoot-system-components/charts/csi-alicloud/templates/auth/csi-plugin-rbac.yaml index ee2a63b32..40cfde24c 100644 --- a/charts/internal/shoot-system-components/charts/csi-alicloud/templates/auth/csi-plugin-rbac.yaml +++ b/charts/internal/shoot-system-components/charts/csi-alicloud/templates/auth/csi-plugin-rbac.yaml @@ -8,7 +8,11 @@ automountServiceAccountToken: false kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: + {{- if not .Values.pspDisabled }} name: {{ include "csi-disk-plugin.extensionsGroup" . }}:psp:kube-system:csi-disk-plugin-alicloud + {{- else }} + name: {{ include "csi-disk-plugin.extensionsGroup" . }}:kube-system:csi-disk-plugin-alicloud + {{- end }} rules: - apiGroups: [""] resources: ["nodes"] @@ -22,6 +26,7 @@ rules: - apiGroups: ["storage.k8s.io"] resources: ["volumeattachments"] verbs: ["get", "list", "watch", "update"] +{{- if not .Values.pspDisabled }} - apiGroups: - policy - extensions @@ -31,16 +36,25 @@ rules: - podsecuritypolicies verbs: - use +{{- end }} --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: + {{- if not .Values.pspDisabled }} name: {{ include "csi-disk-plugin.extensionsGroup" . }}:psp:csi-disk-plugin-alicloud + {{- else }} + name: {{ include "csi-disk-plugin.extensionsGroup" . }}:csi-disk-plugin-alicloud + {{- end }} subjects: - kind: ServiceAccount name: csi-disk-plugin-alicloud namespace: kube-system roleRef: kind: ClusterRole + {{- if not .Values.pspDisabled }} name: {{ include "csi-disk-plugin.extensionsGroup" . }}:psp:kube-system:csi-disk-plugin-alicloud + {{- else }} + name: {{ include "csi-disk-plugin.extensionsGroup" . }}:kube-system:csi-disk-plugin-alicloud + {{- end }} apiGroup: rbac.authorization.k8s.io diff --git a/charts/internal/shoot-system-components/charts/csi-alicloud/values.yaml b/charts/internal/shoot-system-components/charts/csi-alicloud/values.yaml index 5b540a21d..789c6d007 100644 --- a/charts/internal/shoot-system-components/charts/csi-alicloud/values.yaml +++ b/charts/internal/shoot-system-components/charts/csi-alicloud/values.yaml @@ -37,3 +37,5 @@ resources: memory: 32Mi limits: memory: 300Mi + +pspDisabled: false diff --git a/example/10-fake-shoot-controlplane.yaml b/example/10-fake-shoot-controlplane.yaml index b0ec8c7b4..96428960a 100644 --- a/example/10-fake-shoot-controlplane.yaml +++ b/example/10-fake-shoot-controlplane.yaml @@ -128,7 +128,7 @@ spec: - command: - /hyperkube - apiserver - - --enable-admission-plugins=Priority,NamespaceLifecycle,LimitRanger,PodSecurityPolicy,ServiceAccount,NodeRestriction,DefaultStorageClass,Initializers,DefaultTolerationSeconds,ResourceQuota,StorageObjectInUseProtection,MutatingAdmissionWebhook,ValidatingAdmissionWebhook + - --enable-admission-plugins=Priority,NamespaceLifecycle,LimitRanger,ServiceAccount,NodeRestriction,DefaultStorageClass,Initializers,DefaultTolerationSeconds,ResourceQuota,StorageObjectInUseProtection,MutatingAdmissionWebhook,ValidatingAdmissionWebhook - --disable-admission-plugins=PersistentVolumeLabel - --allow-privileged=true - --anonymous-auth=false diff --git a/pkg/controller/controlplane/valuesprovider.go b/pkg/controller/controlplane/valuesprovider.go index c343aed33..938702d32 100644 --- a/pkg/controller/controlplane/valuesprovider.go +++ b/pkg/controller/controlplane/valuesprovider.go @@ -474,6 +474,7 @@ func (vp *valuesProvider) getControlPlaneShootChartValues( "url": "https://" + alicloud.CSISnapshotValidation + "." + cp.Namespace + "/volumesnapshot", "caBundle": string(caSecret.Data[secretutils.DataKeyCertificateBundle]), }, + "pspDisabled": gardencorev1beta1helper.IsPSPDisabled(cluster.Shoot), }, } diff --git a/pkg/controller/controlplane/valuesprovider_test.go b/pkg/controller/controlplane/valuesprovider_test.go index 3b9eeb641..ea0d4caba 100644 --- a/pkg/controller/controlplane/valuesprovider_test.go +++ b/pkg/controller/controlplane/valuesprovider_test.go @@ -23,6 +23,7 @@ import ( "github.com/gardener/gardener-extension-provider-alicloud/pkg/apis/config" extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller" + "github.com/gardener/gardener/extensions/pkg/controller/controlplane/genericactuator" gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants" extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1" @@ -56,6 +57,9 @@ var _ = Describe("ValuesProvider", func() { fakeClient client.Client fakeSecretsManager secretsmanager.Interface + vp genericactuator.ValuesProvider + c *mockclient.MockClient + cp = &extensionsv1alpha1.ControlPlane{ ObjectMeta: metav1.ObjectMeta{ Name: "control-plane", @@ -194,6 +198,7 @@ var _ = Describe("ValuesProvider", func() { "url": "https://" + alicloud.CSISnapshotValidation + "." + cp.Namespace + "/volumesnapshot", "caBundle": "", }, + "pspDisabled": false, }, } @@ -204,6 +209,15 @@ var _ = Describe("ValuesProvider", func() { ctrl = gomock.NewController(GinkgoT()) fakeClient = fakeclient.NewClientBuilder().Build() fakeSecretsManager = fakesecretsmanager.New(fakeClient, namespace) + + // Create mock client + c = mockclient.NewMockClient(ctrl) + // Create valuesProvider + vp = NewValuesProvider(csi) + err := vp.(inject.Scheme).InjectScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + err = vp.(inject.Client).InjectClient(c) + Expect(err).NotTo(HaveOccurred()) }) AfterEach(func() { @@ -212,22 +226,14 @@ var _ = Describe("ValuesProvider", func() { Describe("#GetControlPlaneChartValues", func() { BeforeEach(func() { + c.EXPECT().Get(context.TODO(), cpSecretKey, &corev1.Secret{}).DoAndReturn(clientGet(cpSecret)) + By("creating secrets managed outside of this package for whose secretsmanager.Get() will be called") Expect(fakeClient.Create(context.TODO(), &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "ca-provider-alicloud-controlplane", Namespace: namespace}})).To(Succeed()) Expect(fakeClient.Create(context.TODO(), &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "csi-snapshot-validation-server", Namespace: namespace}})).To(Succeed()) }) It("should return correct control plane chart values", func() { - // Create mock client - client := mockclient.NewMockClient(ctrl) - client.EXPECT().Get(context.TODO(), cpSecretKey, &corev1.Secret{}).DoAndReturn(clientGet(cpSecret)) - // Create valuesProvider - vp := NewValuesProvider(csi) - err := vp.(inject.Scheme).InjectScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - err = vp.(inject.Client).InjectClient(client) - Expect(err).NotTo(HaveOccurred()) - // Call GetControlPlaneChartValues method and check the result values, err := vp.GetControlPlaneChartValues(context.TODO(), cp, cluster, fakeSecretsManager, checksums, false) Expect(err).NotTo(HaveOccurred()) @@ -237,28 +243,87 @@ var _ = Describe("ValuesProvider", func() { Describe("#GetControlPlaneShootChartValues", func() { BeforeEach(func() { + c.EXPECT().Get(context.TODO(), cpSecretKey, &corev1.Secret{}).DoAndReturn(clientGet(cpSecret)) + By("creating secrets managed outside of this package for whose secretsmanager.Get() will be called") Expect(fakeClient.Create(context.TODO(), &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "ca-provider-alicloud-controlplane", Namespace: namespace}})).To(Succeed()) Expect(fakeClient.Create(context.TODO(), &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "csi-snapshot-validation-server", Namespace: namespace}})).To(Succeed()) }) It("should return correct control plane shoot chart values", func() { - // Create mock client - client := mockclient.NewMockClient(ctrl) - client.EXPECT().Get(context.TODO(), cpSecretKey, &corev1.Secret{}).DoAndReturn(clientGet(cpSecret)) - - // Create valuesProvider - vp := NewValuesProvider(csi) - err := vp.(inject.Scheme).InjectScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - err = vp.(inject.Client).InjectClient(client) - Expect(err).NotTo(HaveOccurred()) - // Call GetControlPlaneShootChartValues method and check the result values, err := vp.GetControlPlaneShootChartValues(context.TODO(), cp, cluster, fakeSecretsManager, checksums) Expect(err).NotTo(HaveOccurred()) Expect(values).To(Equal(controlPlaneShootChartValues)) }) + + Context("podSecurityPolicy", func() { + It("should return correct shoot control plane chart when PodSecurityPolicy admission plugin is not disabled in the shoot", func() { + cluster.Shoot.Spec.Kubernetes.KubeAPIServer = &gardencorev1beta1.KubeAPIServerConfig{ + AdmissionPlugins: []gardencorev1beta1.AdmissionPlugin{ + { + Name: "PodSecurityPolicy", + }, + }, + } + + // Call GetControlPlaneShootChartValues method and check the result + values, err := vp.GetControlPlaneShootChartValues(context.TODO(), cp, cluster, fakeSecretsManager, checksums) + Expect(err).NotTo(HaveOccurred()) + + controlPlaneShootChartValues := map[string]interface{}{ + "csi-alicloud": map[string]interface{}{ + "credential": map[string]interface{}{ + "accessKeyID": "Zm9v", + "accessKeySecret": "YmFy", + }, + "kubernetesVersion": "1.20.0", + "enableADController": true, + "vpaEnabled": true, + "webhookConfig": map[string]interface{}{ + "url": "https://" + alicloud.CSISnapshotValidation + "." + cp.Namespace + "/volumesnapshot", + "caBundle": "", + }, + "pspDisabled": false, + }, + } + + Expect(values).To(Equal(controlPlaneShootChartValues)) + }) + + It("should return correct shoot control plane chart when PodSecurityPolicy admission plugin is disabled in the shoot", func() { + cluster.Shoot.Spec.Kubernetes.KubeAPIServer = &gardencorev1beta1.KubeAPIServerConfig{ + AdmissionPlugins: []gardencorev1beta1.AdmissionPlugin{ + { + Name: "PodSecurityPolicy", + Disabled: pointer.Bool(true), + }, + }, + } + + // Call GetControlPlaneShootChartValues method and check the result + values, err := vp.GetControlPlaneShootChartValues(context.TODO(), cp, cluster, fakeSecretsManager, checksums) + Expect(err).NotTo(HaveOccurred()) + + controlPlaneShootChartValues := map[string]interface{}{ + "csi-alicloud": map[string]interface{}{ + "credential": map[string]interface{}{ + "accessKeyID": "Zm9v", + "accessKeySecret": "YmFy", + }, + "kubernetesVersion": "1.20.0", + "enableADController": true, + "vpaEnabled": true, + "webhookConfig": map[string]interface{}{ + "url": "https://" + alicloud.CSISnapshotValidation + "." + cp.Namespace + "/volumesnapshot", + "caBundle": "", + }, + "pspDisabled": true, + }, + } + Expect(values).To(Equal(controlPlaneShootChartValues)) + }) + }) }) Describe("#GetControlPlaneShootCRDsChartValues", func() {