7
7
"regexp"
8
8
9
9
admissionv1 "k8s.io/api/admission/v1"
10
+
10
11
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12
+ "k8s.io/apimachinery/pkg/labels"
11
13
"sigs.k8s.io/controller-runtime/pkg/client"
12
14
cnsoperatorv1alpha1 "sigs.k8s.io/vsphere-csi-driver/v3/pkg/apis/cnsoperator"
13
15
@@ -42,6 +44,25 @@ func validateCreateCnsFileAccessConfig(ctx context.Context, clientConfig *rest.C
42
44
}
43
45
}
44
46
47
+ // This validation is not required for PVCSI service account.
48
+ isPvCSIServiceAccount , err := validatePvCSIServiceAccount (req .UserInfo .Username )
49
+ if err != nil {
50
+ // return AdmissionResponse result
51
+ return & admissionv1.AdmissionResponse {
52
+ Allowed : false ,
53
+ Result : & metav1.Status {
54
+ Message : fmt .Sprintf ("failed to validate user information: %v" , err ),
55
+ },
56
+ }
57
+ }
58
+
59
+ // If user is PVCSI service account, allow this request.
60
+ if isPvCSIServiceAccount {
61
+ return & admissionv1.AdmissionResponse {
62
+ Allowed : true ,
63
+ }
64
+ }
65
+
45
66
vm := cnsFileAccessConfig .Spec .VMName
46
67
pvc := cnsFileAccessConfig .Spec .PvcName
47
68
namespace := cnsFileAccessConfig .Namespace
@@ -87,22 +108,31 @@ func cnsFileAccessConfigAlreadyExists(ctx context.Context, clientConfig *rest.Co
87
108
return "" , err
88
109
}
89
110
111
+ // List only that CnsFileAccessConfig CRs which has the same VM name and PVC name labels.
112
+ labelSelector := labels .SelectorFromSet (labels.Set {vmNameLabelKey : vm , pvcNameLabelKey : pvc })
90
113
// Get the list of all CnsFileAccessConfig CRs in the given namespace.
91
114
cnsFileAccessConfigList := & cnsfileaccessconfigv1alpha1.CnsFileAccessConfigList {}
92
- err = cnsOperatorClient .List (ctx , cnsFileAccessConfigList , & client.ListOptions {Namespace : namespace })
115
+ err = cnsOperatorClient .List (ctx , cnsFileAccessConfigList , & client.ListOptions {
116
+ Namespace : namespace ,
117
+ LabelSelector : labelSelector ,
118
+ })
93
119
if err != nil {
94
120
log .Errorf ("failed to list CnsFileAccessConfigList CRs from %s namesapace. Error: %+v" ,
95
121
namespace , err )
96
122
return "" , err
97
123
}
98
124
99
- for _ , cnsFileAccessConfig := range cnsFileAccessConfigList .Items {
100
- if cnsFileAccessConfig .Spec .VMName == vm {
101
- if cnsFileAccessConfig .Spec .PvcName == pvc {
102
- return cnsFileAccessConfig .Name , nil
103
- }
104
- }
125
+ if len (cnsFileAccessConfigList .Items ) == 1 {
126
+ // There should be only 1 CFC CR with the same VM and PVC
127
+ return cnsFileAccessConfigList .Items [0 ].Name , nil
128
+ }
129
+
130
+ if len (cnsFileAccessConfigList .Items ) > 1 {
131
+ // We should never reach here but it's good to have this check.
132
+ return "" , fmt .Errorf ("invalid case, %d CnsFileAccessConfig instances detected " +
133
+ "with the VM %s and PVC %s" , len (cnsFileAccessConfigList .Items ), vm , pvc )
105
134
}
135
+
106
136
return "" , nil
107
137
}
108
138
@@ -125,10 +155,10 @@ func validateDeleteCnsFileAccessConfig(ctx context.Context, clientConfig *rest.C
125
155
},
126
156
}
127
157
}
128
- // If CR has devops user label, allow this request as
158
+ // If CR has VM name label, allow this request as
129
159
// it means that it is created by devops user or K8s admin
130
160
// and not by VKS (CSI service account).
131
- if _ , ok := cnsFileAccessConfig .Labels [devopsUserLabelKey ]; ok {
161
+ if _ , ok := cnsFileAccessConfig .Labels [vmNameLabelKey ]; ok {
132
162
log .Infof ("CnsFileAccessConfig %s has devops user label. Allow this reqeust." ,
133
163
cnsFileAccessConfig .Name )
134
164
return & admissionv1.AdmissionResponse {
0 commit comments