Skip to content

Commit 5003041

Browse files
authored
Ensure that for RWX volumes for VMFS, clusteredVmdk is enabled (#3551)
1 parent f431590 commit 5003041

File tree

2 files changed

+100
-59
lines changed

2 files changed

+100
-59
lines changed

pkg/csi/service/wcp/controller_helper.go

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import (
5353
var (
5454
vmfsNamespace = "com.vmware.storage.volumeallocation"
5555
vmfsNamespaceEztValue = "Fully initialized"
56+
vmfsClusteredVmdk = "Clustered"
5657
)
5758

5859
// validateCreateBlockReqParam is a helper function used to validate the parameter
@@ -91,32 +92,45 @@ func validateCreateFileReqParam(paramName, value string) bool {
9192
paramName == common.AttributeIsLinkedCloneKey
9293
}
9394

94-
// verifyStoragePolicyForVmfsWithEageredZeroThick goes through each rule in the policy to
95-
// find out if it is fully intialized for VMFS datastores.
96-
// This check is required for RWX shared block volumes as for VMFS, the policy must be EZT.
97-
func verifyStoragePolicyForVmfsWithEageredZeroThick(ctx context.Context,
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,
98100
spbmPolicyContentList []vsphere.SpbmPolicyContent,
99101
storagePolicyId string) error {
100102
log := logger.GetLogger(ctx)
101103

104+
isEzt := false
105+
isClustered := false
106+
isVmfsNamespace := false
107+
102108
for _, polictContent := range spbmPolicyContentList {
103109
for _, profile := range polictContent.Profiles {
104110
for _, rule := range profile.Rules {
105111
if rule.Ns == vmfsNamespace {
106-
if rule.Value != vmfsNamespaceEztValue {
107-
msg := fmt.Sprintf("Policy %s is for VMFS datastores. It must be fully initialized for "+
108-
"RWX block volumes", storagePolicyId)
109-
err := errors.New(msg)
110-
log.Errorf(msg)
111-
return err
112+
isVmfsNamespace = true
113+
switch rule.Value {
114+
case vmfsNamespaceEztValue:
115+
isEzt = true
116+
case vmfsClusteredVmdk:
117+
isClustered = true
112118
}
113-
log.Infof("Policy %s is for VMFS and is fully initialized", storagePolicyId)
114-
return nil
115119
}
116120
}
117121
}
118122
}
119123

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+
120134
log.Debugf("Policy %s validated correctly", storagePolicyId)
121135
return nil
122136
}
@@ -133,7 +147,7 @@ func validateStoragePolicyForVmfs(ctx context.Context,
133147
return err
134148
}
135149

136-
return verifyStoragePolicyForVmfsWithEageredZeroThick(ctx, spbmPolicyContentList, storagePolicyId)
150+
return verifyStoragePolicyForVmfsUtil(ctx, spbmPolicyContentList, storagePolicyId)
137151
}
138152

139153
// validateWCPCreateVolumeRequest is the helper function to validate

pkg/csi/service/wcp/controller_helper_test.go

Lines changed: 73 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -133,66 +133,93 @@ func TestGetPodVMUUID(t *testing.T) {
133133
})
134134
}
135135

136-
func TestVerifyStoragePolicyForVmfsWithEageredZeroThick(t *testing.T) {
136+
func TestVerifyStoragePolicyForVmfsUtil(t *testing.T) {
137137
ctx := context.TODO()
138-
139-
t.Run("Valid VMFS EZT policy", func(t *testing.T) {
140-
policyList := []cnsvsphere.SpbmPolicyContent{
141-
{
142-
Profiles: []cnsvsphere.SpbmPolicySubProfile{
143-
{
144-
Rules: []cnsvsphere.SpbmPolicyRule{
145-
{Ns: vmfsNamespace, Value: vmfsNamespaceEztValue},
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+
},
146155
},
147156
},
148157
},
149158
},
150-
}
151-
152-
err := verifyStoragePolicyForVmfsWithEageredZeroThick(ctx, policyList, "valid-policy-id")
153-
assert.NoError(t, err)
154-
})
155-
156-
t.Run("Invalid VMFS policy - not EZT", func(t *testing.T) {
157-
policyList := []cnsvsphere.SpbmPolicyContent{
158-
{
159-
Profiles: []cnsvsphere.SpbmPolicySubProfile{
160-
{
161-
Rules: []cnsvsphere.SpbmPolicyRule{
162-
{Ns: vmfsNamespace, Value: "Thin"},
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+
},
163170
},
164171
},
165172
},
166173
},
167-
}
168-
169-
err := verifyStoragePolicyForVmfsWithEageredZeroThick(ctx, policyList, "invalid-policy-id")
170-
assert.Error(t, err)
171-
assert.Contains(t, err.Error(), "must be fully initialized")
172-
})
173-
174-
t.Run("Policy with no VMFS rule", func(t *testing.T) {
175-
policyList := []cnsvsphere.SpbmPolicyContent{
176-
{
177-
Profiles: []cnsvsphere.SpbmPolicySubProfile{
178-
{
179-
Rules: []cnsvsphere.SpbmPolicyRule{
180-
{Ns: "VSAN", Value: "Whatever"},
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+
},
181185
},
182186
},
183187
},
184188
},
185-
}
186-
187-
err := verifyStoragePolicyForVmfsWithEageredZeroThick(ctx, policyList, "no-vmfs-rule-policy")
188-
assert.NoError(t, err)
189-
})
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+
}
190212

191-
t.Run("Empty policy list", func(t *testing.T) {
192-
var policyList []cnsvsphere.SpbmPolicyContent
193-
err := verifyStoragePolicyForVmfsWithEageredZeroThick(ctx, policyList, "empty-policy")
194-
assert.NoError(t, err)
195-
})
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+
}
196223
}
197224

198225
func newMockPod(name, namespace, nodeName string, volumes []string,

0 commit comments

Comments
 (0)