Skip to content

Commit 55536dc

Browse files
authored
Prevent VKS CnsFileAccessConfig CR deletion (#3360)
1 parent 7adedd2 commit 55536dc

File tree

7 files changed

+309
-112
lines changed

7 files changed

+309
-112
lines changed

manifests/supervisorcluster/1.29/cns-csi.yaml

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ rules:
230230
apiVersion: rbac.authorization.k8s.io/v1
231231
kind: RoleBinding
232232
metadata:
233-
name: vsphere-csi-provisioner-configmap-writer
233+
name: vsphere-csi-controller-configmap-writer
234234
namespace: vmware-system-csi
235235
subjects:
236236
- kind: ServiceAccount
@@ -649,13 +649,43 @@ webhooks:
649649
scope: "Namespaced"
650650
- apiGroups: ["cns.vmware.com"]
651651
apiVersions: ["v1alpha1"]
652-
operations: ["CREATE"]
652+
operations: ["CREATE", "DELETE"]
653653
resources: ["cnsfileaccessconfigs"]
654654
scope: "Namespaced"
655655
sideEffects: None
656656
admissionReviewVersions: ["v1"]
657657
failurePolicy: Fail
658658
---
659+
apiVersion: admissionregistration.k8s.io/v1
660+
kind: MutatingWebhookConfiguration
661+
metadata:
662+
name: vmware-system-csi-mutating-webhook-configuration
663+
labels:
664+
app: vsphere-csi-webhook
665+
annotations:
666+
cert-manager.io/inject-ca-from: vmware-system-csi/vmware-system-csi-serving-cert
667+
webhooks:
668+
- name: mutation.csi.vsphere.vmware.com
669+
clientConfig:
670+
service:
671+
name: vmware-system-csi-webhook-service
672+
namespace: vmware-system-csi
673+
path: "/mutate"
674+
rules:
675+
- apiGroups: [""]
676+
apiVersions: ["v1", "v1beta1"]
677+
operations: ["CREATE", "UPDATE"]
678+
resources: ["persistentvolumeclaims"]
679+
scope: "Namespaced"
680+
- apiGroups: ["cns.vmware.com"]
681+
apiVersions: ["v1alpha1"]
682+
operations: ["CREATE"]
683+
resources: ["cnsfileaccessconfigs"]
684+
scope: "Namespaced"
685+
sideEffects: None
686+
admissionReviewVersions: ["v1"]
687+
failurePolicy: Fail
688+
---
659689
kind: ClusterRole
660690
apiVersion: rbac.authorization.k8s.io/v1
661691
metadata:
@@ -667,9 +697,12 @@ rules:
667697
- apiGroups: ["snapshot.storage.k8s.io"]
668698
resources: ["volumesnapshots"]
669699
verbs: ["get", "list"]
700+
- apiGroups: ["encryption.vmware.com"]
701+
resources: ["encryptionclasses"]
702+
verbs: ["get", "list", "watch"]
670703
- apiGroups: ["cns.vmware.com"]
671704
resources: ["cnsfileaccessconfigs"]
672-
verbs: ["get", "list"]
705+
verbs: ["get", "list", "update"]
673706
---
674707
kind: ClusterRoleBinding
675708
apiVersion: rbac.authorization.k8s.io/v1

manifests/supervisorcluster/1.30/cns-csi.yaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ webhooks:
663663
scope: "Namespaced"
664664
- apiGroups: ["cns.vmware.com"]
665665
apiVersions: ["v1alpha1"]
666-
operations: ["CREATE"]
666+
operations: ["CREATE", "DELETE"]
667667
resources: ["cnsfileaccessconfigs"]
668668
scope: "Namespaced"
669669
sideEffects: None
@@ -691,6 +691,11 @@ webhooks:
691691
operations: ["CREATE", "UPDATE"]
692692
resources: ["persistentvolumeclaims"]
693693
scope: "Namespaced"
694+
- apiGroups: ["cns.vmware.com"]
695+
apiVersions: ["v1alpha1"]
696+
operations: ["CREATE"]
697+
resources: ["cnsfileaccessconfigs"]
698+
scope: "Namespaced"
694699
sideEffects: None
695700
admissionReviewVersions: ["v1"]
696701
failurePolicy: Fail
@@ -714,7 +719,7 @@ rules:
714719
verbs: ["get", "list", "watch"]
715720
- apiGroups: ["cns.vmware.com"]
716721
resources: ["cnsfileaccessconfigs"]
717-
verbs: ["get", "list"]
722+
verbs: ["get", "list", "update"]
718723
---
719724
kind: ClusterRoleBinding
720725
apiVersion: rbac.authorization.k8s.io/v1

manifests/supervisorcluster/1.31/cns-csi.yaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ webhooks:
663663
scope: "Namespaced"
664664
- apiGroups: ["cns.vmware.com"]
665665
apiVersions: ["v1alpha1"]
666-
operations: ["CREATE"]
666+
operations: ["CREATE", "DELETE"]
667667
resources: ["cnsfileaccessconfigs"]
668668
scope: "Namespaced"
669669
sideEffects: None
@@ -691,6 +691,11 @@ webhooks:
691691
operations: ["CREATE", "UPDATE"]
692692
resources: ["persistentvolumeclaims"]
693693
scope: "Namespaced"
694+
- apiGroups: ["cns.vmware.com"]
695+
apiVersions: ["v1alpha1"]
696+
operations: ["CREATE"]
697+
resources: ["cnsfileaccessconfigs"]
698+
scope: "Namespaced"
694699
sideEffects: None
695700
admissionReviewVersions: ["v1"]
696701
failurePolicy: Fail
@@ -714,7 +719,7 @@ rules:
714719
verbs: ["get", "list", "watch"]
715720
- apiGroups: ["cns.vmware.com"]
716721
resources: ["cnsfileaccessconfigs"]
717-
verbs: ["get", "list"]
722+
verbs: ["get", "list", "update"]
718723
---
719724
kind: ClusterRoleBinding
720725
apiVersion: rbac.authorization.k8s.io/v1

manifests/supervisorcluster/1.32/cns-csi.yaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ webhooks:
661661
scope: "Namespaced"
662662
- apiGroups: ["cns.vmware.com"]
663663
apiVersions: ["v1alpha1"]
664-
operations: ["CREATE"]
664+
operations: ["CREATE", "DELETE"]
665665
resources: ["cnsfileaccessconfigs"]
666666
scope: "Namespaced"
667667
sideEffects: None
@@ -689,6 +689,11 @@ webhooks:
689689
operations: ["CREATE", "UPDATE"]
690690
resources: ["persistentvolumeclaims"]
691691
scope: "Namespaced"
692+
- apiGroups: ["cns.vmware.com"]
693+
apiVersions: ["v1alpha1"]
694+
operations: ["CREATE"]
695+
resources: ["cnsfileaccessconfigs"]
696+
scope: "Namespaced"
692697
sideEffects: None
693698
admissionReviewVersions: ["v1"]
694699
failurePolicy: Fail
@@ -712,7 +717,7 @@ rules:
712717
verbs: ["get", "list", "watch"]
713718
- apiGroups: ["cns.vmware.com"]
714719
resources: ["cnsfileaccessconfigs"]
715-
verbs: ["get", "list"]
720+
verbs: ["get", "list", "update"]
716721
---
717722
kind: ClusterRoleBinding
718723
apiVersion: rbac.authorization.k8s.io/v1

pkg/syncer/admissionhandler/cnscsi_admissionhandler.go

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"sigs.k8s.io/controller-runtime/pkg/webhook"
2222
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
2323

24+
cnsfileaccessconfigv1alpha1 "sigs.k8s.io/vsphere-csi-driver/v3/pkg/apis/cnsoperator/cnsfileaccessconfig/v1alpha1"
2425
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/cns-lib/crypto"
2526
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/logger"
2627
)
@@ -30,6 +31,7 @@ const (
3031
MutationWebhookPath = "/mutate"
3132
DefaultWebhookPort = 9883
3233
DefaultWebhookMetricsBindAddress = "0"
34+
devopsUserLabelKey = "cns.vmware.com/user-created"
3335
)
3436

3537
var (
@@ -184,9 +186,14 @@ func (h *CSISupervisorWebhook) Handle(ctx context.Context, req admission.Request
184186
}
185187
} else if req.Kind.Kind == "CnsFileAccessConfig" {
186188
if featureFileVolumesWithVmServiceEnabled {
187-
admissionResp := validateCnsFileAccessConfig(ctx, h.clientConfig, &req.AdmissionRequest)
188-
resp.AdmissionResponse = *admissionResp.DeepCopy()
189-
189+
switch req.Operation {
190+
case admissionv1.Create:
191+
admissionResp := validateCreateCnsFileAccessConfig(ctx, h.clientConfig, &req.AdmissionRequest)
192+
resp.AdmissionResponse = *admissionResp.DeepCopy()
193+
case admissionv1.Delete:
194+
admissionResp := validateDeleteCnsFileAccessConfig(ctx, h.clientConfig, &req.AdmissionRequest)
195+
resp.AdmissionResponse = *admissionResp.DeepCopy()
196+
}
190197
}
191198
}
192199
return
@@ -209,11 +216,57 @@ func (h *CSISupervisorMutationWebhook) Handle(ctx context.Context, req admission
209216
case admissionv1.Create:
210217
return h.mutateNewPVC(ctx, req)
211218
}
219+
} else if req.Kind.Kind == "CnsFileAccessConfig" {
220+
if featureFileVolumesWithVmServiceEnabled {
221+
switch req.Operation {
222+
case admissionv1.Create:
223+
return h.mutateNewCnsFileAccessConfig(ctx, req)
224+
}
225+
}
212226
}
213227

214228
return admission.Allowed("")
215229
}
216230

231+
// mutateNewCnsFileAccessConfig adds devops label on a CnsFileAccessConfig CR
232+
// if it is being created by a devops user.
233+
func (h *CSISupervisorMutationWebhook) mutateNewCnsFileAccessConfig(ctx context.Context,
234+
req admission.Request) admission.Response {
235+
log := logger.GetLogger(ctx)
236+
237+
newCnsFileAccessConfig := cnsfileaccessconfigv1alpha1.CnsFileAccessConfig{}
238+
if err := json.Unmarshal(req.Object.Raw, &newCnsFileAccessConfig); err != nil {
239+
return admission.Errored(http.StatusInternalServerError, err)
240+
}
241+
242+
// If CR is created by CSI service account, do not add devops label.
243+
isPvCSIServiceAccount, err := validatePvCSIServiceAccount(req.UserInfo.Username)
244+
if err != nil {
245+
return admission.Errored(http.StatusInternalServerError, err)
246+
}
247+
248+
if isPvCSIServiceAccount {
249+
log.Infof("Skip mutating CnsFileAccessConfig instance %s for PVCSI service account user",
250+
newCnsFileAccessConfig.Name)
251+
return admission.Allowed("")
252+
}
253+
254+
if newCnsFileAccessConfig.Labels == nil {
255+
newCnsFileAccessConfig.Labels = make(map[string]string)
256+
}
257+
if _, ok := newCnsFileAccessConfig.Labels[devopsUserLabelKey]; ok {
258+
log.Debugf("Devops label already present on instance %s", newCnsFileAccessConfig.Name)
259+
return admission.Allowed("")
260+
}
261+
newCnsFileAccessConfig.Labels[devopsUserLabelKey] = "true"
262+
newRawCnsFileAccessConfig, err := json.Marshal(newCnsFileAccessConfig)
263+
if err != nil {
264+
return admission.Errored(http.StatusInternalServerError, err)
265+
}
266+
267+
return admission.PatchResponseFromRaw(req.Object.Raw, newRawCnsFileAccessConfig)
268+
}
269+
217270
func (h *CSISupervisorMutationWebhook) mutateNewPVC(ctx context.Context, req admission.Request) admission.Response {
218271
newPVC := &corev1.PersistentVolumeClaim{}
219272
if err := json.Unmarshal(req.Object.Raw, newPVC); err != nil {

pkg/syncer/admissionhandler/validate_cnffileaccessconfig.go

Lines changed: 0 additions & 100 deletions
This file was deleted.

0 commit comments

Comments
 (0)