mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +00:00
Add StorageClassName validation
This commit is contained in:
parent
916a0a63dd
commit
39fa63d0a4
@ -247,6 +247,11 @@ var ValidateEndpointsName = NameIsDNSSubdomain
|
|||||||
// ValidateClusterName can be used to check whether the given cluster name is valid.
|
// ValidateClusterName can be used to check whether the given cluster name is valid.
|
||||||
var ValidateClusterName = genericvalidation.ValidateClusterName
|
var ValidateClusterName = genericvalidation.ValidateClusterName
|
||||||
|
|
||||||
|
// ValidateClassName can be used to check whether the given class name is valid.
|
||||||
|
// It is defined here to avoid import cycle between pkg/apis/storage/validation
|
||||||
|
// (where it should be) and this file.
|
||||||
|
var ValidateClassName = NameIsDNSSubdomain
|
||||||
|
|
||||||
// TODO update all references to these functions to point to the genericvalidation ones
|
// TODO update all references to these functions to point to the genericvalidation ones
|
||||||
// NameIsDNSSubdomain is a ValidateNameFunc for names that must be a DNS subdomain.
|
// NameIsDNSSubdomain is a ValidateNameFunc for names that must be a DNS subdomain.
|
||||||
func NameIsDNSSubdomain(name string, prefix bool) []string {
|
func NameIsDNSSubdomain(name string, prefix bool) []string {
|
||||||
@ -1194,6 +1199,12 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
|
|||||||
allErrs = append(allErrs, field.Forbidden(specPath.Child("persistentVolumeReclaimPolicy"), "may not be 'recycle' for a hostPath mount of '/'"))
|
allErrs = append(allErrs, field.Forbidden(specPath.Child("persistentVolumeReclaimPolicy"), "may not be 'recycle' for a hostPath mount of '/'"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(pv.Spec.StorageClassName) > 0 {
|
||||||
|
for _, msg := range ValidateClassName(pv.Spec.StorageClassName, false) {
|
||||||
|
allErrs = append(allErrs, field.Invalid(specPath.Child("storageClassName"), pv.Spec.StorageClassName, msg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1244,6 +1255,12 @@ func ValidatePersistentVolumeClaimSpec(spec *api.PersistentVolumeClaimSpec, fldP
|
|||||||
} else {
|
} else {
|
||||||
allErrs = append(allErrs, ValidateResourceQuantityValue(string(api.ResourceStorage), storageValue, fldPath.Child("resources").Key(string(api.ResourceStorage)))...)
|
allErrs = append(allErrs, ValidateResourceQuantityValue(string(api.ResourceStorage), storageValue, fldPath.Child("resources").Key(string(api.ResourceStorage)))...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if spec.StorageClassName != nil && len(*spec.StorageClassName) > 0 {
|
||||||
|
for _, msg := range ValidateClassName(*spec.StorageClassName, false) {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("storageClassName"), *spec.StorageClassName, msg))
|
||||||
|
}
|
||||||
|
}
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ func TestValidatePersistentVolumes(t *testing.T) {
|
|||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||||
HostPath: &api.HostPathVolumeSource{Path: "/foo"},
|
HostPath: &api.HostPathVolumeSource{Path: "/foo"},
|
||||||
},
|
},
|
||||||
|
StorageClassName: "valid",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
"good-volume-with-retain-policy": {
|
"good-volume-with-retain-policy": {
|
||||||
@ -230,6 +231,19 @@ func TestValidatePersistentVolumes(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
"invalid-storage-class-name": {
|
||||||
|
isExpectedFailure: true,
|
||||||
|
volume: testVolume("invalid-storage-class-name", "", api.PersistentVolumeSpec{
|
||||||
|
Capacity: api.ResourceList{
|
||||||
|
api.ResourceName(api.ResourceStorage): resource.MustParse("10G"),
|
||||||
|
},
|
||||||
|
AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
|
||||||
|
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||||
|
HostPath: &api.HostPathVolumeSource{Path: "/foo"},
|
||||||
|
},
|
||||||
|
StorageClassName: "-invalid-",
|
||||||
|
}),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, scenario := range scenarios {
|
for name, scenario := range scenarios {
|
||||||
@ -301,6 +315,8 @@ func testVolumeClaimAnnotation(name string, namespace string, ann string, annval
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestValidatePersistentVolumeClaim(t *testing.T) {
|
func TestValidatePersistentVolumeClaim(t *testing.T) {
|
||||||
|
invalidClassName := "-invalid-"
|
||||||
|
validClassName := "valid"
|
||||||
scenarios := map[string]struct {
|
scenarios := map[string]struct {
|
||||||
isExpectedFailure bool
|
isExpectedFailure bool
|
||||||
claim *api.PersistentVolumeClaim
|
claim *api.PersistentVolumeClaim
|
||||||
@ -325,6 +341,7 @@ func TestValidatePersistentVolumeClaim(t *testing.T) {
|
|||||||
api.ResourceName(api.ResourceStorage): resource.MustParse("10G"),
|
api.ResourceName(api.ResourceStorage): resource.MustParse("10G"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
StorageClassName: &validClassName,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
"invalid-label-selector": {
|
"invalid-label-selector": {
|
||||||
@ -428,6 +445,29 @@ func TestValidatePersistentVolumeClaim(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
"invalid-storage-class-name": {
|
||||||
|
isExpectedFailure: true,
|
||||||
|
claim: testVolumeClaim("foo", "ns", api.PersistentVolumeClaimSpec{
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchExpressions: []metav1.LabelSelectorRequirement{
|
||||||
|
{
|
||||||
|
Key: "key2",
|
||||||
|
Operator: "Exists",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AccessModes: []api.PersistentVolumeAccessMode{
|
||||||
|
api.ReadWriteOnce,
|
||||||
|
api.ReadOnlyMany,
|
||||||
|
},
|
||||||
|
Resources: api.ResourceRequirements{
|
||||||
|
Requests: api.ResourceList{
|
||||||
|
api.ResourceName(api.ResourceStorage): resource.MustParse("10G"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
StorageClassName: &invalidClassName,
|
||||||
|
}),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, scenario := range scenarios {
|
for name, scenario := range scenarios {
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
|
|
||||||
// ValidateStorageClass validates a StorageClass.
|
// ValidateStorageClass validates a StorageClass.
|
||||||
func ValidateStorageClass(storageClass *storage.StorageClass) field.ErrorList {
|
func ValidateStorageClass(storageClass *storage.StorageClass) field.ErrorList {
|
||||||
allErrs := apivalidation.ValidateObjectMeta(&storageClass.ObjectMeta, false, apivalidation.NameIsDNSSubdomain, field.NewPath("metadata"))
|
allErrs := apivalidation.ValidateObjectMeta(&storageClass.ObjectMeta, false, apivalidation.ValidateClassName, field.NewPath("metadata"))
|
||||||
allErrs = append(allErrs, validateProvisioner(storageClass.Provisioner, field.NewPath("provisioner"))...)
|
allErrs = append(allErrs, validateProvisioner(storageClass.Provisioner, field.NewPath("provisioner"))...)
|
||||||
allErrs = append(allErrs, validateParameters(storageClass.Parameters, field.NewPath("parameters"))...)
|
allErrs = append(allErrs, validateParameters(storageClass.Parameters, field.NewPath("parameters"))...)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user