Merge pull request #48789 from mtanino/issue/47311
Automatic merge from submit-queue (batch tested with PRs 50806, 48789, 49922, 49935, 50438) iSCSI volume plugin: iSCSI initiatorname support **What this PR does / why we need it**: This PR adds iSCSI initiatorname parameter to ISCSIVolumeSource to enable automatic configuration of initiator name per volume. This would allow for more fine grained configuration, and remove the need to configure the initiator name on the host by administrator. **Which issue this PR fixes**: fixes #47311 **Special notes for your reviewer**: /cc @rootfs @jsafrane @msau42 **Release note**: ``` iSCSI volume plugin: Support customization of iSCSI initiator name per volume ```
This commit is contained in:
@@ -69,6 +69,10 @@ var volumeModeErrorMsg string = "must be a number between 0 and 0777 (octal), bo
|
||||
// BannedOwners is a black list of object that are not allowed to be owners.
|
||||
var BannedOwners = genericvalidation.BannedOwners
|
||||
|
||||
var iscsiInitiatorIqnRegex = regexp.MustCompile(`iqn\.\d{4}-\d{2}\.([[:alnum:]-.]+)(:[^,;*&$|\s]+)$`)
|
||||
var iscsiInitiatorEuiRegex = regexp.MustCompile(`^eui.[[:alnum:]]{16}$`)
|
||||
var iscsiInitiatorNaaRegex = regexp.MustCompile(`^naa.[[:alnum:]]{32}$`)
|
||||
|
||||
// ValidateHasLabel requires that metav1.ObjectMeta has a Label with key and expectedValue
|
||||
func ValidateHasLabel(meta metav1.ObjectMeta, fldPath *field.Path, key, expectedValue string) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
@@ -358,7 +362,7 @@ func ValidateVolumes(volumes []api.Volume, fldPath *field.Path) (sets.String, fi
|
||||
for i, vol := range volumes {
|
||||
idxPath := fldPath.Index(i)
|
||||
namePath := idxPath.Child("name")
|
||||
el := validateVolumeSource(&vol.VolumeSource, idxPath)
|
||||
el := validateVolumeSource(&vol.VolumeSource, idxPath, vol.Name)
|
||||
if len(vol.Name) == 0 {
|
||||
el = append(el, field.Required(namePath, ""))
|
||||
} else {
|
||||
@@ -377,7 +381,7 @@ func ValidateVolumes(volumes []api.Volume, fldPath *field.Path) (sets.String, fi
|
||||
return allNames, allErrs
|
||||
}
|
||||
|
||||
func validateVolumeSource(source *api.VolumeSource, fldPath *field.Path) field.ErrorList {
|
||||
func validateVolumeSource(source *api.VolumeSource, fldPath *field.Path, volName string) field.ErrorList {
|
||||
numVolumes := 0
|
||||
allErrs := field.ErrorList{}
|
||||
if source.EmptyDir != nil {
|
||||
@@ -444,6 +448,10 @@ func validateVolumeSource(source *api.VolumeSource, fldPath *field.Path) field.E
|
||||
numVolumes++
|
||||
allErrs = append(allErrs, validateISCSIVolumeSource(source.ISCSI, fldPath.Child("iscsi"))...)
|
||||
}
|
||||
if source.ISCSI.InitiatorName != nil && len(volName+":"+source.ISCSI.TargetPortal) > 64 {
|
||||
tooLongErr := "Total length of <volume name>:<iscsi.targetPortal> must be under 64 characters if iscsi.initiatorName is specified."
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), volName, tooLongErr))
|
||||
}
|
||||
}
|
||||
if source.Glusterfs != nil {
|
||||
if numVolumes > 0 {
|
||||
@@ -636,6 +644,16 @@ func validateISCSIVolumeSource(iscsi *api.ISCSIVolumeSource, fldPath *field.Path
|
||||
}
|
||||
if len(iscsi.IQN) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("iqn"), ""))
|
||||
} else {
|
||||
if !strings.HasPrefix(iscsi.IQN, "iqn") && !strings.HasPrefix(iscsi.IQN, "eui") && !strings.HasPrefix(iscsi.IQN, "naa") {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("iqn"), iscsi.IQN, "must be valid format"))
|
||||
} else if strings.HasPrefix(iscsi.IQN, "iqn") && !iscsiInitiatorIqnRegex.MatchString(iscsi.IQN) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("iqn"), iscsi.IQN, "must be valid format"))
|
||||
} else if strings.HasPrefix(iscsi.IQN, "eui") && !iscsiInitiatorEuiRegex.MatchString(iscsi.IQN) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("iqn"), iscsi.IQN, "must be valid format"))
|
||||
} else if strings.HasPrefix(iscsi.IQN, "naa") && !iscsiInitiatorNaaRegex.MatchString(iscsi.IQN) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("iqn"), iscsi.IQN, "must be valid format"))
|
||||
}
|
||||
}
|
||||
if iscsi.Lun < 0 || iscsi.Lun > 255 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("lun"), iscsi.Lun, validation.InclusiveRangeError(0, 255)))
|
||||
@@ -643,6 +661,19 @@ func validateISCSIVolumeSource(iscsi *api.ISCSIVolumeSource, fldPath *field.Path
|
||||
if (iscsi.DiscoveryCHAPAuth || iscsi.SessionCHAPAuth) && iscsi.SecretRef == nil {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("secretRef"), ""))
|
||||
}
|
||||
if iscsi.InitiatorName != nil {
|
||||
initiator := *iscsi.InitiatorName
|
||||
if !strings.HasPrefix(initiator, "iqn") && !strings.HasPrefix(initiator, "eui") && !strings.HasPrefix(initiator, "naa") {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("initiatorname"), initiator, "must be valid format"))
|
||||
}
|
||||
if strings.HasPrefix(initiator, "iqn") && !iscsiInitiatorIqnRegex.MatchString(initiator) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("initiatorname"), initiator, "must be valid format"))
|
||||
} else if strings.HasPrefix(initiator, "eui") && !iscsiInitiatorEuiRegex.MatchString(initiator) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("initiatorname"), initiator, "must be valid format"))
|
||||
} else if strings.HasPrefix(initiator, "naa") && !iscsiInitiatorNaaRegex.MatchString(initiator) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("initiatorname"), initiator, "must be valid format"))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@@ -1292,6 +1323,10 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
|
||||
numVolumes++
|
||||
allErrs = append(allErrs, validateISCSIVolumeSource(pv.Spec.ISCSI, specPath.Child("iscsi"))...)
|
||||
}
|
||||
if pv.Spec.ISCSI.InitiatorName != nil && len(pv.ObjectMeta.Name+":"+pv.Spec.ISCSI.TargetPortal) > 64 {
|
||||
tooLongErr := "Total length of <volume name>:<iscsi.targetPortal> must be under 64 characters if iscsi.initiatorName is specified."
|
||||
allErrs = append(allErrs, field.Invalid(metaPath.Child("name"), pv.ObjectMeta.Name, tooLongErr))
|
||||
}
|
||||
}
|
||||
if pv.Spec.Cinder != nil {
|
||||
if numVolumes > 0 {
|
||||
|
Reference in New Issue
Block a user