mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 05:57:25 +00:00
storage: validate CSIDriver.Spec.VolumeLifecycleModes
This ensures that users get a good error message early on when trying to do something that isn't okay: $ kubectl create -f csi-hostpath-driverinfo.yaml The CSIDriver "hostpath.csi.k8s.io" is invalid: spec.volumeLifecycleModes: Unsupported value: "foobar": supported values: "persistent", "ephemeral"
This commit is contained in:
parent
f7742fd31a
commit
b60f08e24b
@ -419,6 +419,7 @@ func validateCSIDriverSpec(
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, validateAttachRequired(spec.AttachRequired, fldPath.Child("attachedRequired"))...)
|
||||
allErrs = append(allErrs, validatePodInfoOnMount(spec.PodInfoOnMount, fldPath.Child("podInfoOnMount"))...)
|
||||
allErrs = append(allErrs, validateVolumeLifecycleModes(spec.VolumeLifecycleModes, fldPath.Child("volumeLifecycleModes"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@ -441,3 +442,21 @@ func validatePodInfoOnMount(podInfoOnMount *bool, fldPath *field.Path) field.Err
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validateVolumeLifecycleModes tests if mode has one of the allowed values.
|
||||
func validateVolumeLifecycleModes(modes []storage.VolumeLifecycleMode, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for _, mode := range modes {
|
||||
switch mode {
|
||||
case storage.VolumeLifecyclePersistent, storage.VolumeLifecycleEphemeral:
|
||||
default:
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath, mode,
|
||||
[]string{
|
||||
string(storage.VolumeLifecyclePersistent),
|
||||
string(storage.VolumeLifecycleEphemeral),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
@ -1726,6 +1726,49 @@ func TestCSIDriverValidation(t *testing.T) {
|
||||
PodInfoOnMount: ¬PodInfoOnMount,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: driverName},
|
||||
Spec: storage.CSIDriverSpec{
|
||||
AttachRequired: &attachNotRequired,
|
||||
PodInfoOnMount: ¬PodInfoOnMount,
|
||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{
|
||||
storage.VolumeLifecyclePersistent,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: driverName},
|
||||
Spec: storage.CSIDriverSpec{
|
||||
AttachRequired: &attachNotRequired,
|
||||
PodInfoOnMount: ¬PodInfoOnMount,
|
||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{
|
||||
storage.VolumeLifecycleEphemeral,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: driverName},
|
||||
Spec: storage.CSIDriverSpec{
|
||||
AttachRequired: &attachNotRequired,
|
||||
PodInfoOnMount: ¬PodInfoOnMount,
|
||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{
|
||||
storage.VolumeLifecycleEphemeral,
|
||||
storage.VolumeLifecyclePersistent,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: driverName},
|
||||
Spec: storage.CSIDriverSpec{
|
||||
AttachRequired: &attachNotRequired,
|
||||
PodInfoOnMount: ¬PodInfoOnMount,
|
||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{
|
||||
storage.VolumeLifecycleEphemeral,
|
||||
storage.VolumeLifecyclePersistent,
|
||||
storage.VolumeLifecycleEphemeral,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, csiDriver := range successCases {
|
||||
@ -1764,6 +1807,17 @@ func TestCSIDriverValidation(t *testing.T) {
|
||||
PodInfoOnMount: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
// invalid mode
|
||||
ObjectMeta: metav1.ObjectMeta{Name: driverName},
|
||||
Spec: storage.CSIDriverSpec{
|
||||
AttachRequired: &attachNotRequired,
|
||||
PodInfoOnMount: ¬PodInfoOnMount,
|
||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{
|
||||
"no-such-mode",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, csiDriver := range errorCases {
|
||||
|
@ -296,6 +296,71 @@ func TestCSIDriverValidation(t *testing.T) {
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid volume mode",
|
||||
&storage.CSIDriver{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: storage.CSIDriverSpec{
|
||||
AttachRequired: &attachRequired,
|
||||
PodInfoOnMount: &podInfoOnMount,
|
||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{
|
||||
storage.VolumeLifecycleMode("no-such-mode"),
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"persistent volume mode",
|
||||
&storage.CSIDriver{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: storage.CSIDriverSpec{
|
||||
AttachRequired: &attachRequired,
|
||||
PodInfoOnMount: &podInfoOnMount,
|
||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{
|
||||
storage.VolumeLifecyclePersistent,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"ephemeral volume mode",
|
||||
&storage.CSIDriver{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: storage.CSIDriverSpec{
|
||||
AttachRequired: &attachRequired,
|
||||
PodInfoOnMount: &podInfoOnMount,
|
||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{
|
||||
storage.VolumeLifecycleEphemeral,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"both volume modes",
|
||||
&storage.CSIDriver{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: storage.CSIDriverSpec{
|
||||
AttachRequired: &attachRequired,
|
||||
PodInfoOnMount: &podInfoOnMount,
|
||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{
|
||||
storage.VolumeLifecyclePersistent,
|
||||
storage.VolumeLifecycleEphemeral,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
Loading…
Reference in New Issue
Block a user