Skip to content

Commit 9bc9208

Browse files
authored
Remove validations for batch attach (#3622)
1 parent b700b23 commit 9bc9208

File tree

6 files changed

+4
-315
lines changed

6 files changed

+4
-315
lines changed

pkg/apis/cnsoperator/cnsnodevmbatchattachment/v1alpha1/cnsnodebatchvmattachment_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ const (
2929
IndependentPersistent DiskMode = "independent_persistent"
3030
// Changes are immediately and permanently written to the virtual disk.
3131
Persistent DiskMode = "persistent"
32+
// Changes to virtual disk are made to a redo log and discarded at power off.
33+
// It is not affected by snapshots.
34+
IndependentNonPersistent = "independent_nonpersistent"
3235
)
3336

3437
// The sharing mode of the virtual disk.

pkg/csi/service/wcp/controller.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -516,16 +516,6 @@ func (c *controller) createBlockVolume(ctx context.Context, req *csi.CreateVolum
516516
"failed to get vCenter from Manager. Error: %v", err)
517517
}
518518

519-
if commonco.ContainerOrchestratorUtility.IsFSSEnabled(ctx,
520-
common.SharedDiskFss) && isSharedRawBlockRequest(ctx, req.VolumeCapabilities) {
521-
log.Infof("Volume request is for shared RWX volume. Validatig if policy is compatible for VMFS datastores.")
522-
err := validateStoragePolicyForVmfs(ctx, vc, storagePolicyID)
523-
if err != nil {
524-
log.Errorf("failed validation for policy %s", storagePolicyID)
525-
return nil, csifault.CSIInternalFault, err
526-
}
527-
}
528-
529519
// Fetch the accessibility requirements from the request.
530520
topologyRequirement = req.GetAccessibilityRequirements()
531521
filterSuspendedDatastores := commonco.ContainerOrchestratorUtility.IsFSSEnabled(ctx, common.CnsMgrSuspendCreateVolume)

pkg/csi/service/wcp/controller_helper.go

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,6 @@ import (
5050
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/syncer/k8scloudoperator"
5151
)
5252

53-
var (
54-
vmfsNamespace = "com.vmware.storage.volumeallocation"
55-
vmfsNamespaceEztValue = "Fully initialized"
56-
vmfsClusteredVmdk = "Clustered"
57-
)
58-
5953
// validateCreateBlockReqParam is a helper function used to validate the parameter
6054
// name received in the CreateVolume request for block volumes on WCP CSI driver.
6155
// Returns true if the parameter name is valid, false otherwise.
@@ -92,64 +86,6 @@ func validateCreateFileReqParam(paramName, value string) bool {
9286
paramName == common.AttributeIsLinkedCloneKey
9387
}
9488

95-
// verifyStoragePolicyForVmfsUtil goes through each rule in the policy to
96-
// find out if it is fully intialized and has clustered VMDK enabled for VMFS datastores.
97-
// This check is required for RWX shared block volumes as for VMFS, the policy must be EZT
98-
// and clustered.
99-
func verifyStoragePolicyForVmfsUtil(ctx context.Context,
100-
spbmPolicyContentList []vsphere.SpbmPolicyContent,
101-
storagePolicyId string) error {
102-
log := logger.GetLogger(ctx)
103-
104-
isEzt := false
105-
isClustered := false
106-
isVmfsNamespace := false
107-
108-
for _, polictContent := range spbmPolicyContentList {
109-
for _, profile := range polictContent.Profiles {
110-
for _, rule := range profile.Rules {
111-
if rule.Ns == vmfsNamespace {
112-
isVmfsNamespace = true
113-
switch rule.Value {
114-
case vmfsNamespaceEztValue:
115-
isEzt = true
116-
case vmfsClusteredVmdk:
117-
isClustered = true
118-
}
119-
}
120-
}
121-
}
122-
}
123-
124-
// If any policy is for VMFS and it is not EZT or clustered, then send back error.
125-
if isVmfsNamespace && (!isEzt || !isClustered) {
126-
msg := fmt.Sprintf("Policy %s is for VMFS datastores. "+
127-
"It must be fully initialized and must have clustered VMDK enabled for "+
128-
"RWX block volumes", storagePolicyId)
129-
err := errors.New(msg)
130-
log.Errorf(msg)
131-
return err
132-
}
133-
134-
log.Debugf("Policy %s validated correctly", storagePolicyId)
135-
return nil
136-
}
137-
138-
// validateStoragePolicyForVmfs checks whether the policy is compatible for VMFS datastores.
139-
// This function is only called for RWX shared block volumes.
140-
func validateStoragePolicyForVmfs(ctx context.Context,
141-
vc *vsphere.VirtualCenter, storagePolicyId string) error {
142-
log := logger.GetLogger(ctx)
143-
144-
spbmPolicyContentList, err := vc.PbmRetrieveContent(ctx, []string{storagePolicyId})
145-
if err != nil {
146-
log.Errorf("failed to retrieve policy %s", storagePolicyId)
147-
return err
148-
}
149-
150-
return verifyStoragePolicyForVmfsUtil(ctx, spbmPolicyContentList, storagePolicyId)
151-
}
152-
15389
// validateWCPCreateVolumeRequest is the helper function to validate
15490
// CreateVolumeRequest for WCP CSI driver.
15591
// Function returns error if validation fails otherwise returns nil.

pkg/csi/service/wcp/controller_helper_test.go

Lines changed: 0 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"k8s.io/client-go/kubernetes"
1212
"k8s.io/client-go/kubernetes/fake"
1313
k8stesting "k8s.io/client-go/testing"
14-
cnsvsphere "sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/cns-lib/vsphere"
1514
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/unittestcommon"
1615
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/common/commonco"
1716
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/logger"
@@ -133,95 +132,6 @@ func TestGetPodVMUUID(t *testing.T) {
133132
})
134133
}
135134

136-
func TestVerifyStoragePolicyForVmfsUtil(t *testing.T) {
137-
ctx := context.TODO()
138-
policyId := "policy-123"
139-
140-
tests := []struct {
141-
name string
142-
input []cnsvsphere.SpbmPolicyContent
143-
expectError bool
144-
}{
145-
{
146-
name: "Valid VMFS policy with EZT and Clustered VMDK",
147-
input: []cnsvsphere.SpbmPolicyContent{
148-
{
149-
Profiles: []cnsvsphere.SpbmPolicySubProfile{
150-
{
151-
Rules: []cnsvsphere.SpbmPolicyRule{
152-
{Ns: vmfsNamespace, Value: vmfsNamespaceEztValue},
153-
{Ns: vmfsNamespace, Value: vmfsClusteredVmdk},
154-
},
155-
},
156-
},
157-
},
158-
},
159-
expectError: false,
160-
},
161-
{
162-
name: "VMFS policy missing EZT",
163-
input: []cnsvsphere.SpbmPolicyContent{
164-
{
165-
Profiles: []cnsvsphere.SpbmPolicySubProfile{
166-
{
167-
Rules: []cnsvsphere.SpbmPolicyRule{
168-
{Ns: vmfsNamespace, Value: vmfsClusteredVmdk},
169-
},
170-
},
171-
},
172-
},
173-
},
174-
expectError: true,
175-
},
176-
{
177-
name: "VMFS policy missing Clustered VMDK",
178-
input: []cnsvsphere.SpbmPolicyContent{
179-
{
180-
Profiles: []cnsvsphere.SpbmPolicySubProfile{
181-
{
182-
Rules: []cnsvsphere.SpbmPolicyRule{
183-
{Ns: vmfsNamespace, Value: vmfsNamespaceEztValue},
184-
},
185-
},
186-
},
187-
},
188-
},
189-
expectError: true,
190-
},
191-
{
192-
name: "Non-VMFS policy should pass",
193-
input: []cnsvsphere.SpbmPolicyContent{
194-
{
195-
Profiles: []cnsvsphere.SpbmPolicySubProfile{
196-
{
197-
Rules: []cnsvsphere.SpbmPolicyRule{
198-
{Ns: "non-vmfs", Value: "some-value"},
199-
},
200-
},
201-
},
202-
},
203-
},
204-
expectError: false,
205-
},
206-
{
207-
name: "Empty policy list should pass",
208-
input: []cnsvsphere.SpbmPolicyContent{},
209-
expectError: false,
210-
},
211-
}
212-
213-
for _, tt := range tests {
214-
t.Run(tt.name, func(t *testing.T) {
215-
err := verifyStoragePolicyForVmfsUtil(ctx, tt.input, policyId)
216-
if tt.expectError {
217-
assert.Error(t, err)
218-
} else {
219-
assert.NoError(t, err)
220-
}
221-
})
222-
}
223-
}
224-
225135
func newMockPod(name, namespace, nodeName string, volumes []string,
226136
annotations map[string]string, phase v1.PodPhase) *v1.Pod {
227137
vols := make([]v1.Volume, len(volumes))

pkg/syncer/cnsoperator/controller/cnsnodevmbatchattachment/cnsnodevmbatchattachment_helper.go

Lines changed: 1 addition & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"slices"
2424

2525
vimtypes "github.com/vmware/govmomi/vim25/types"
26-
v1 "k8s.io/api/core/v1"
2726
"sigs.k8s.io/controller-runtime/pkg/client"
2827
v1alpha1 "sigs.k8s.io/vsphere-csi-driver/v3/pkg/apis/cnsoperator/cnsnodevmbatchattachment/v1alpha1"
2928
volumes "sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/cns-lib/volume"
@@ -361,82 +360,11 @@ func constructBatchAttachRequest(ctx context.Context,
361360
ControllerKey: volume.PersistentVolumeClaim.ControllerKey,
362361
UnitNumber: volume.PersistentVolumeClaim.UnitNumber,
363362
}
364-
// Validate each attach request before proceeding.
365-
updateBatchAttachRequest, err := validateBatchAttachRequest(ctx,
366-
currentBatchAttachRequest, instance.Namespace, pvcName)
367-
if err != nil {
368-
log.Errorf("failed to validate attach request for PVC %s in namespace %s. Err: %s",
369-
pvcName, instance.Namespace, err)
370-
return pvcsInSpec, volumeIdsInSpec, batchAttachRequest, err
371-
}
372-
batchAttachRequest = append(batchAttachRequest, updateBatchAttachRequest)
363+
batchAttachRequest = append(batchAttachRequest, currentBatchAttachRequest)
373364
}
374365
return pvcsInSpec, volumeIdsInSpec, batchAttachRequest, nil
375366
}
376367

377-
// validateBatchAttachRequest ensures that the right combination for the input request.
378-
// This is the validation criteria:
379-
// RWX accessMode -> ControllerKey and UnitNumber are required, DiskMode must be IndependentPersistent.
380-
// RWO accessMode -> DiskMode must not be IndependentPersistent, SharingMode must not be SharingMultiWriter.
381-
func validateBatchAttachRequest(ctx context.Context,
382-
batchAttachRequest volumes.BatchAttachRequest, namespace string, pvcName string) (volumes.BatchAttachRequest, error) {
383-
log := logger.GetLogger(ctx)
384-
385-
log.Infof("Verifying if PVC %s has correct input parameters for batch attach", pvcName)
386-
387-
// Get PVC object from informer cache
388-
pvc, err := commonco.ContainerOrchestratorUtility.GetPvcObjectByName(ctx, pvcName, namespace)
389-
if err != nil {
390-
log.Errorf("failed to get PVC object for PVC %s. Err: %s", pvcName, err)
391-
return batchAttachRequest, err
392-
}
393-
394-
for _, accessMode := range pvc.Spec.AccessModes {
395-
// RWX accessMode -> ControllerKey and UnitNumber are required, DiskMode must be IndependentPersistent.
396-
if accessMode == v1.ReadWriteMany || accessMode == v1.ReadOnlyMany {
397-
if batchAttachRequest.DiskMode == "" {
398-
batchAttachRequest.DiskMode = string(v1alpha1.IndependentPersistent)
399-
}
400-
if batchAttachRequest.DiskMode != string(v1alpha1.IndependentPersistent) {
401-
return batchAttachRequest, fmt.Errorf("incorrect input for PVC %s in namespace %s with accessMode %s. "+
402-
"DiskMode cannot be %s", pvcName, namespace, accessMode, batchAttachRequest.DiskMode)
403-
}
404-
if batchAttachRequest.ControllerKey == "" {
405-
return batchAttachRequest, fmt.Errorf("incorrect input for PVC %s in namespace %s with accessMode %s. "+
406-
"ControllerKey cannot be empty", pvcName, namespace, accessMode)
407-
}
408-
if batchAttachRequest.UnitNumber == "" {
409-
return batchAttachRequest, fmt.Errorf("incorrect input for PVC %s in namespace %s with accessMode %s. "+
410-
" UnitNumber cannot be empty", pvcName, namespace, accessMode)
411-
}
412-
if batchAttachRequest.SharingMode == "" {
413-
return batchAttachRequest, fmt.Errorf("incorrect input for PVC %s in namespace %s with accessMode %s. "+
414-
" SharingMode cannot be empty", pvcName, namespace, accessMode)
415-
}
416-
}
417-
418-
// RWO accessMode -> DiskMode, SharingMode and ControllerNumber and Unit Number must be empty.
419-
if accessMode == v1.ReadWriteOnce {
420-
if batchAttachRequest.DiskMode != "" {
421-
return batchAttachRequest, fmt.Errorf("incorrect input for PVC %s in namespace %s with accessMode %s. "+
422-
"DiskMode cannot be %s", pvcName, namespace, accessMode, batchAttachRequest.DiskMode)
423-
}
424-
if batchAttachRequest.SharingMode != "" {
425-
return batchAttachRequest, fmt.Errorf("incorrect input for PVC %s in namespace %s with accessMode %s. "+
426-
"SharingMode cannot be %s", pvcName, namespace, accessMode, batchAttachRequest.SharingMode)
427-
}
428-
if batchAttachRequest.ControllerKey != "" || batchAttachRequest.UnitNumber != "" {
429-
return batchAttachRequest, fmt.Errorf("incorrect input for PVC %s in namespace %s with accessMode %s. "+
430-
"ControllerNumber and UnitNumber must not be provided with RWO accessMode", pvcName, namespace, accessMode)
431-
}
432-
}
433-
}
434-
435-
log.Infof("Validated request for PVC %s in namespace %s", pvcName, namespace)
436-
437-
return batchAttachRequest, nil
438-
}
439-
440368
// getVmObject find the VM object on vCenter.
441369
// If VM retrieval from vCenter fails with NotFound error,
442370
// then it is not considered an error because VM CR is probably being deleted.

pkg/syncer/cnsoperator/controller/cnsnodevmbatchattachment/cnsnodevmbatchattachment_test.go

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import (
3434
"sigs.k8s.io/controller-runtime/pkg/client/fake"
3535
"sigs.k8s.io/controller-runtime/pkg/reconcile"
3636

37-
volumes "sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/cns-lib/volume"
3837
cnsvsphere "sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/cns-lib/vsphere"
3938
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/config"
4039
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/unittestcommon"
@@ -367,83 +366,6 @@ func TestReconcileWithoutDeletionTimestampWhenAttachFails(t *testing.T) {
367366
})
368367
}
369368

370-
func TestValidateBatchAttachRequestWithRwoPvc(t *testing.T) {
371-
372-
t.Run("TestValidateBatchAttachRequestWithRwoPvc", func(t *testing.T) {
373-
374-
batchAttachRequest := volumes.BatchAttachRequest{
375-
DiskMode: "IndependentPersistent",
376-
}
377-
378-
commonco.ContainerOrchestratorUtility = &unittestcommon.FakeK8SOrchestrator{}
379-
_, err := validateBatchAttachRequest(context.TODO(), batchAttachRequest, testNamespace, "pvc-1")
380-
expectedEr := fmt.Errorf("incorrect input for PVC pvc-1 in namespace test-ns with accessMode ReadWriteOnce. " +
381-
"DiskMode cannot be IndependentPersistent")
382-
assert.EqualError(t, expectedEr, err.Error())
383-
384-
batchAttachRequest = volumes.BatchAttachRequest{
385-
SharingMode: "sharingMultiWriter",
386-
}
387-
388-
commonco.ContainerOrchestratorUtility = &unittestcommon.FakeK8SOrchestrator{}
389-
_, err = validateBatchAttachRequest(context.TODO(), batchAttachRequest, testNamespace, "pvc-1")
390-
expectedEr = fmt.Errorf("incorrect input for PVC pvc-1 in namespace test-ns with accessMode ReadWriteOnce. " +
391-
"SharingMode cannot be sharingMultiWriter")
392-
assert.EqualError(t, expectedEr, err.Error())
393-
394-
batchAttachRequest = volumes.BatchAttachRequest{
395-
SharingMode: "",
396-
}
397-
398-
commonco.ContainerOrchestratorUtility = &unittestcommon.FakeK8SOrchestrator{}
399-
_, err = validateBatchAttachRequest(context.TODO(), batchAttachRequest, testNamespace, "pvc-1")
400-
assert.NoError(t, err)
401-
402-
})
403-
}
404-
405-
func TestValidateBatchAttachRequestWithRwxPvc(t *testing.T) {
406-
407-
t.Run("TestValidateBatchAttachRequestWithRwxPvc", func(t *testing.T) {
408-
409-
batchAttachRequest := volumes.BatchAttachRequest{
410-
DiskMode: "persistent",
411-
ControllerKey: "12345",
412-
UnitNumber: "9",
413-
}
414-
415-
commonco.ContainerOrchestratorUtility = &unittestcommon.FakeK8SOrchestrator{}
416-
_, err := validateBatchAttachRequest(context.TODO(), batchAttachRequest, testNamespace, "pvc-rwx")
417-
expectedErr := fmt.Errorf("incorrect input for PVC pvc-rwx in namespace test-ns with accessMode ReadWriteMany. " +
418-
"DiskMode cannot be persistent")
419-
assert.EqualError(t, expectedErr, err.Error())
420-
421-
batchAttachRequest = volumes.BatchAttachRequest{
422-
ControllerKey: "",
423-
UnitNumber: "12",
424-
DiskMode: "independent_persistent",
425-
}
426-
427-
commonco.ContainerOrchestratorUtility = &unittestcommon.FakeK8SOrchestrator{}
428-
_, err = validateBatchAttachRequest(context.TODO(), batchAttachRequest, testNamespace, "pvc-rwx")
429-
expectedErr = fmt.Errorf("incorrect input for PVC pvc-rwx in namespace test-ns with accessMode ReadWriteMany. " +
430-
"ControllerKey cannot be empty")
431-
assert.EqualError(t, expectedErr, err.Error())
432-
433-
batchAttachRequest = volumes.BatchAttachRequest{
434-
ControllerKey: "1001",
435-
UnitNumber: "12",
436-
DiskMode: "",
437-
SharingMode: "None",
438-
}
439-
440-
commonco.ContainerOrchestratorUtility = &unittestcommon.FakeK8SOrchestrator{}
441-
attacheReq, err := validateBatchAttachRequest(context.TODO(), batchAttachRequest, testNamespace, "pvc-rwx")
442-
assert.NoError(t, err)
443-
assert.Equal(t, "independent_persistent", attacheReq.DiskMode)
444-
})
445-
}
446-
447369
func MockGetVMFromVcenter(ctx context.Context, nodeUUID string,
448370
configInfo config.ConfigurationInfo) (*cnsvsphere.VirtualMachine, error) {
449371
var vm *cnsvsphere.VirtualMachine

0 commit comments

Comments
 (0)