@@ -13,6 +13,7 @@ import (
13
13
"strconv"
14
14
"strings"
15
15
16
+ vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5"
16
17
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/common/commonco/k8sorchestrator"
17
18
18
19
admissionv1 "k8s.io/api/admission/v1"
@@ -29,9 +30,12 @@ import (
29
30
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/common"
30
31
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/common/commonco"
31
32
33
+ apitypes "k8s.io/apimachinery/pkg/types"
32
34
cnsfileaccessconfigv1alpha1 "sigs.k8s.io/vsphere-csi-driver/v3/pkg/apis/cnsoperator/cnsfileaccessconfig/v1alpha1"
33
35
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/cns-lib/crypto"
36
+ "sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/utils"
34
37
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/logger"
38
+ k8s "sigs.k8s.io/vsphere-csi-driver/v3/pkg/kubernetes"
35
39
)
36
40
37
41
const (
@@ -40,8 +44,8 @@ const (
40
44
DefaultWebhookPort = 9883
41
45
DefaultWebhookMetricsBindAddress = "0"
42
46
devopsUserLabelKey = "cns.vmware.com/user-created"
43
- vmNameLabelKey = "cns.vmware.com/vm-name "
44
- pvcNameLabelKey = "cns.vmware.com/pvc-name "
47
+ vmUIDLabelKey = "cns.vmware.com/vm-uid "
48
+ pvcUIDLabelKey = "cns.vmware.com/pvc-uid "
45
49
)
46
50
47
51
var (
@@ -248,6 +252,71 @@ func (h *CSISupervisorMutationWebhook) Handle(ctx context.Context, req admission
248
252
return admission .Allowed ("" )
249
253
}
250
254
255
+ // getVmUID returns the VM UID for the given VM
256
+ func getVmUID (ctx context.Context ,
257
+ vmName string , namespace string ) (string , error ) {
258
+ log := logger .GetLogger (ctx )
259
+
260
+ restClientConfig , err := k8s .GetKubeConfig (ctx )
261
+ if err != nil {
262
+ log .Errorf ("failed to initialize rest clientconfig. Error: %s" , err )
263
+ return "" , err
264
+ }
265
+
266
+ vmOperatorClient , err := k8s .NewClientForGroup (ctx , restClientConfig , vmoperatortypes .GroupName )
267
+ if err != nil {
268
+ log .Error ("failed to initialize vmOperatorClient. Error: %s" , err )
269
+ return "" , err
270
+ }
271
+
272
+ vm , _ , err := getVirtualMachine (ctx , vmOperatorClient , vmName , namespace )
273
+ if err != nil {
274
+ log .Error ("failed to get virtualmachine. Error: %s" , err )
275
+ return "" , err
276
+ }
277
+
278
+ log .Infof ("Found UID %s for VM %s" , string (vm .ObjectMeta .UID ), vm .Name )
279
+ return string (vm .ObjectMeta .UID ), nil
280
+ }
281
+
282
+ // getVirtualMachine returns the VM object for the given vmName and namespace.
283
+ func getVirtualMachine (ctx context.Context , vmOperatorClient client.Client ,
284
+ vmName string , namespace string ) (* vmoperatortypes.VirtualMachine , string , error ) {
285
+ log := logger .GetLogger (ctx )
286
+ vmKey := apitypes.NamespacedName {
287
+ Namespace : namespace ,
288
+ Name : vmName ,
289
+ }
290
+ virtualMachine , apiVersion , err := utils .GetVirtualMachineAllApiVersions (ctx ,
291
+ vmKey , vmOperatorClient )
292
+ if err != nil {
293
+ log .Error ("failed to get virtualmachine instance for the VM with name: %q. Error: %+v" , vmName , err )
294
+ return nil , apiVersion , err
295
+ }
296
+ return virtualMachine , apiVersion , nil
297
+ }
298
+
299
+ // getPVCUID retrieves the UID of a PersistentVolumeClaim by name and namespace.
300
+ func getPVCUID (ctx context.Context , pvcName , namespace string ) (string , error ) {
301
+ log := logger .GetLogger (ctx )
302
+
303
+ k8sClient , err := k8s .NewClient (ctx )
304
+ if err != nil {
305
+ log .Errorf ("failed to create k8s client. Errror: %s" , err )
306
+ return "" , err
307
+ }
308
+
309
+ pvc , err := k8sClient .CoreV1 ().PersistentVolumeClaims (namespace ).Get (ctx , pvcName ,
310
+ v1.GetOptions {})
311
+ if err != nil {
312
+ log .Errorf ("failed to obtain PVC %s. Errror: %s" , pvcName , err )
313
+ return "" , err
314
+ }
315
+
316
+ log .Infof ("Found UID %s for PVC %s" , string (pvc .UID ), pvcName )
317
+ return string (pvc .UID ), nil
318
+ }
319
+
251
320
// mutateNewCnsFileAccessConfig adds devops label on a CnsFileAccessConfig CR
252
321
// if it is being created by a devops user.
253
322
func (h * CSISupervisorMutationWebhook ) mutateNewCnsFileAccessConfig (ctx context.Context ,
@@ -275,12 +344,26 @@ func (h *CSISupervisorMutationWebhook) mutateNewCnsFileAccessConfig(ctx context.
275
344
newCnsFileAccessConfig .Labels = make (map [string ]string )
276
345
}
277
346
347
+ // Obtain VM's UID
348
+ vmUID , err := getVmUID (ctx , newCnsFileAccessConfig .Spec .VMName , newCnsFileAccessConfig .Namespace )
349
+ if err != nil {
350
+ log .Errorf ("faield to get VM UID for VM %s. Err: %s" , newCnsFileAccessConfig .Spec .VMName , err )
351
+ return admission .Errored (http .StatusInternalServerError , err )
352
+ }
353
+
354
+ // Obtain PVC's UID
355
+ pvcUID , err := getPVCUID (ctx , newCnsFileAccessConfig .Spec .PvcName , newCnsFileAccessConfig .Namespace )
356
+ if err != nil {
357
+ log .Errorf ("faield to get PVC UID for PVC %s. Err: %s" , newCnsFileAccessConfig .Spec .PvcName , err )
358
+ return admission .Errored (http .StatusInternalServerError , err )
359
+ }
360
+
278
361
// Add VM name and PVC name label.
279
362
// If someone created this CR with these labels already present, CSI will overrite on them
280
363
// with the correct values.
281
364
newCnsFileAccessConfig .Labels [devopsUserLabelKey ] = "true"
282
- newCnsFileAccessConfig .Labels [vmNameLabelKey ] = newCnsFileAccessConfig . Spec . VMName
283
- newCnsFileAccessConfig .Labels [pvcNameLabelKey ] = newCnsFileAccessConfig . Spec . PvcName
365
+ newCnsFileAccessConfig .Labels [vmUIDLabelKey ] = vmUID
366
+ newCnsFileAccessConfig .Labels [pvcUIDLabelKey ] = pvcUID
284
367
285
368
newRawCnsFileAccessConfig , err := json .Marshal (newCnsFileAccessConfig )
286
369
if err != nil {
0 commit comments