github.com/openshift/installer@v1.4.17/pkg/types/openstack/validation/machinepool.go (about)

     1  package validation
     2  
     3  import (
     4  	"k8s.io/apimachinery/pkg/util/validation/field"
     5  
     6  	"github.com/openshift/installer/pkg/types/openstack"
     7  )
     8  
     9  var validServerGroupPolicies = []string{
    10  	string(openstack.SGPolicyAffinity),
    11  	string(openstack.SGPolicyAntiAffinity),
    12  	string(openstack.SGPolicySoftAffinity),
    13  	string(openstack.SGPolicySoftAntiAffinity),
    14  }
    15  
    16  // ValidateMachinePool validates Control plane and Compute MachinePools
    17  func ValidateMachinePool(_ *openstack.Platform, machinePool *openstack.MachinePool, role string, fldPath *field.Path) field.ErrorList {
    18  	if machinePool == nil {
    19  		return nil
    20  	}
    21  	var errs field.ErrorList
    22  	switch machinePool.ServerGroupPolicy {
    23  	case openstack.SGPolicyUnset, openstack.SGPolicyAffinity, openstack.SGPolicyAntiAffinity, openstack.SGPolicySoftAffinity, openstack.SGPolicySoftAntiAffinity:
    24  	default:
    25  		errs = append(errs, field.NotSupported(fldPath.Child("serverGroupPolicy"), machinePool.ServerGroupPolicy, validServerGroupPolicies))
    26  	}
    27  
    28  	if machinePool.RootVolume != nil {
    29  		if len(machinePool.Zones) > 0 && len(machinePool.RootVolume.Zones) == 0 {
    30  			errs = append(errs, field.Required(fldPath.Child("rootVolume").Child("zones"), "root volume availability zones must be specified when compute availability zones are specified"))
    31  		}
    32  
    33  		rootVolumeType := machinePool.RootVolume.DeprecatedType
    34  		rootVolumeTypes := machinePool.RootVolume.Types
    35  		typePath := fldPath.Child("rootVolume").Child("type")
    36  		typesPath := fldPath.Child("rootVolume").Child("types")
    37  
    38  		if rootVolumeType != "" && len(rootVolumeTypes) > 0 {
    39  			errs = append(errs, field.Invalid(typePath, rootVolumeType, "Only one of type or types can be specified"))
    40  			errs = append(errs, field.Invalid(typesPath, rootVolumeTypes, "Only one of type or types can be specified"))
    41  		}
    42  
    43  		if rootVolumeType == "" && len(rootVolumeTypes) == 0 {
    44  			errs = append(errs, field.Invalid(typePath, rootVolumeType, "Either type or types must be specified"))
    45  			errs = append(errs, field.Invalid(typesPath, rootVolumeTypes, "Either type or types must be specified"))
    46  		}
    47  
    48  		// When distributing the Root volumes across multiple failure domains, we suggest using multiple Storage types so they use a different backend.
    49  		// Storage availability zones are purely cosmetic for now and can also be used to define where a volume should be created, however
    50  		// we don't want to force a user to define a Storage availability zone when using multiple Storage types.
    51  		// Therefore we decided to require as many Storage types as there are Compute availability zones, if there are multiple Compute availability zones
    52  		// and more than one Storage type is defined.
    53  		// Even if we support a single Storage type across multiple failure domains, we still allow doing it.
    54  		// e.g. it would not make sense to have 3 Compute availability zones and 2 Storage types, because one of the Storage types would be used twice and
    55  		// therefore the number of failure domains would not be 3 anymore.
    56  		if machinePool.RootVolume.Types != nil {
    57  			if computes, volumes := len(machinePool.Zones), len(machinePool.RootVolume.Types); computes > 1 && volumes > 1 && volumes != computes {
    58  				errs = append(errs, field.Invalid(typesPath, rootVolumeTypes, "Compute and Storage availability zones in a MachinePool should have been validated to have equal length when more than one Storage type is defined"))
    59  			}
    60  		}
    61  	}
    62  
    63  	return errs
    64  }