Validate that PersistentVolumeSource is not changed during PV Update.

pull/6/head
Ian Chakeres 2017-10-29 07:09:00 -07:00
parent 1bc5f7cfa3
commit b396cd6f8f
2 changed files with 67 additions and 0 deletions

View File

@ -1554,6 +1554,12 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
func ValidatePersistentVolumeUpdate(newPv, oldPv *api.PersistentVolume) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = ValidatePersistentVolume(newPv)
// PersistentVolumeSource should be immutable after creation.
if !apiequality.Semantic.DeepEqual(newPv.Spec.PersistentVolumeSource, oldPv.Spec.PersistentVolumeSource) {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "persistentvolumesource"), "is immutable after creation"))
}
newPv.Status = oldPv.Status
return allErrs
}

View File

@ -349,6 +349,67 @@ func TestValidatePersistentVolumes(t *testing.T) {
}
func TestValidatePersistentVolumeSourceUpdate(t *testing.T) {
validVolume := testVolume("foo", "", api.PersistentVolumeSpec{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceStorage): resource.MustParse("1G"),
},
AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
PersistentVolumeSource: api.PersistentVolumeSource{
HostPath: &api.HostPathVolumeSource{
Path: "/foo",
Type: newHostPathType(string(api.HostPathDirectory)),
},
},
StorageClassName: "valid",
})
validPvSourceNoUpdate := validVolume.DeepCopy()
invalidPvSourceUpdateType := validVolume.DeepCopy()
invalidPvSourceUpdateType.Spec.PersistentVolumeSource = api.PersistentVolumeSource{
FlexVolume: &api.FlexVolumeSource{
Driver: "kubernetes.io/blue",
FSType: "ext4",
},
}
invalidPvSourceUpdateDeep := validVolume.DeepCopy()
invalidPvSourceUpdateDeep.Spec.PersistentVolumeSource = api.PersistentVolumeSource{
HostPath: &api.HostPathVolumeSource{
Path: "/updated",
Type: newHostPathType(string(api.HostPathDirectory)),
},
}
scenarios := map[string]struct {
isExpectedFailure bool
oldVolume *api.PersistentVolume
newVolume *api.PersistentVolume
}{
"condition-no-update": {
isExpectedFailure: false,
oldVolume: validVolume,
newVolume: validPvSourceNoUpdate,
},
"condition-update-source-type": {
isExpectedFailure: true,
oldVolume: validVolume,
newVolume: invalidPvSourceUpdateType,
},
"condition-update-source-deep": {
isExpectedFailure: true,
oldVolume: validVolume,
newVolume: invalidPvSourceUpdateDeep,
},
}
for name, scenario := range scenarios {
errs := ValidatePersistentVolumeUpdate(scenario.newVolume, scenario.oldVolume)
if len(errs) == 0 && scenario.isExpectedFailure {
t.Errorf("Unexpected success for scenario: %s", name)
}
if len(errs) > 0 && !scenario.isExpectedFailure {
t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs)
}
}
}
func TestValidateLocalVolumes(t *testing.T) {
scenarios := map[string]struct {
isExpectedFailure bool