in pkg/api/vlabs/validate.go [440:592]
func (a *Properties) validateAgentPoolProfiles(isUpdate bool) error {
profileNames := make(map[string]bool)
for i, agentPoolProfile := range a.AgentPoolProfiles {
if e := validatePoolName(agentPoolProfile.Name); e != nil {
return e
}
// validate os type is linux if dual stack feature is enabled
if a.FeatureFlags.IsIPv6DualStackEnabled() || a.FeatureFlags.IsIPv6OnlyEnabled() {
if agentPoolProfile.OSType == Windows {
if a.FeatureFlags.IsIPv6DualStackEnabled() && !common.IsKubernetesVersionGe(a.OrchestratorProfile.OrchestratorVersion, "1.19.0") {
return errors.Errorf("Dual stack IPv6 feature is supported on Windows only from Kubernetes version 1.19, but OrchestratorProfile.OrchestratorVersion is '%s'", a.OrchestratorProfile.OrchestratorVersion)
}
if a.FeatureFlags.IsIPv6OnlyEnabled() {
return errors.Errorf("Single stack IPv6 feature is supported only with Linux, but agent pool '%s' is of os type %s", agentPoolProfile.Name, agentPoolProfile.OSType)
}
}
if agentPoolProfile.Distro == Flatcar {
return errors.Errorf("Dual stack and single stack IPv6 feature is currently supported only with Ubuntu, but agent pool '%s' is of distro type %s", agentPoolProfile.Name, agentPoolProfile.Distro)
}
}
// validate that each AgentPoolProfile Name is unique
if _, ok := profileNames[agentPoolProfile.Name]; ok {
return errors.Errorf("profile name '%s' already exists, profile names must be unique across pools", agentPoolProfile.Name)
}
profileNames[agentPoolProfile.Name] = true
if e := validatePoolOSType(agentPoolProfile.OSType); e != nil {
return e
}
if to.Bool(agentPoolProfile.AcceleratedNetworkingEnabled) || to.Bool(agentPoolProfile.AcceleratedNetworkingEnabledWindows) {
if a.IsAzureStackCloud() {
return errors.Errorf("AcceleratedNetworkingEnabled or AcceleratedNetworkingEnabledWindows shouldn't be set to true as feature is not yet supported on Azure Stack")
} else if e := validatePoolAcceleratedNetworking(agentPoolProfile.VMSize); e != nil {
return e
}
}
if to.Bool(agentPoolProfile.VMSSOverProvisioningEnabled) {
if agentPoolProfile.AvailabilityProfile == AvailabilitySet {
return errors.Errorf("You have specified VMSS Overprovisioning in agent pool %s, but you did not specify VMSS", agentPoolProfile.Name)
}
}
if to.Bool(agentPoolProfile.AuditDEnabled) {
if agentPoolProfile.Distro != "" && !agentPoolProfile.IsUbuntu() {
return errors.Errorf("You have enabled auditd in agent pool %s, but you did not specify an Ubuntu-based distro", agentPoolProfile.Name)
}
} else {
if a.FeatureFlags.IsEnforceUbuntuDisaStigEnabled() && agentPoolProfile.IsUbuntu() {
return errors.New("AuditD should be enabled in all Ubuntu-based pools if feature flag 'EnforceUbuntu2004DisaStig' or 'EnforceUbuntu2204DisaStig' is set")
}
}
if to.Bool(agentPoolProfile.EnableVMSSNodePublicIP) {
if agentPoolProfile.AvailabilityProfile == AvailabilitySet {
return errors.Errorf("You have enabled VMSS node public IP in agent pool %s, but you did not specify VMSS", agentPoolProfile.Name)
}
if !strings.EqualFold(a.OrchestratorProfile.KubernetesConfig.LoadBalancerSku, BasicLoadBalancerSku) {
return errors.Errorf("You have enabled VMSS node public IP in agent pool %s, but you did not specify Basic Load Balancer SKU", agentPoolProfile.Name)
}
}
if e := agentPoolProfile.validateOrchestratorSpecificProperties(); e != nil {
return e
}
if agentPoolProfile.ImageRef != nil {
if e := agentPoolProfile.ImageRef.validateImageNameAndGroup(); e != nil {
return e
}
}
if e := agentPoolProfile.validateAvailabilityProfile(); e != nil {
return e
}
if e := agentPoolProfile.validateRoles(); e != nil {
return e
}
if e := agentPoolProfile.validateCustomNodeLabels(); e != nil {
return e
}
if agentPoolProfile.AvailabilityProfile != AvailabilitySet {
e := validateVMSS(a.OrchestratorProfile, isUpdate, agentPoolProfile.StorageProfile, a.HasWindows(), a.IsAzureStackCloud())
if e != nil {
return e
}
}
if a.AgentPoolProfiles[i].AvailabilityProfile != a.AgentPoolProfiles[0].AvailabilityProfile {
return errors.New("mixed mode availability profiles are not allowed. Please set either VirtualMachineScaleSets or AvailabilitySet in availabilityProfile for all agent pools")
}
if a.AgentPoolProfiles[i].SinglePlacementGroup != nil && a.AgentPoolProfiles[i].AvailabilityProfile == AvailabilitySet {
return errors.New("singlePlacementGroup is only supported with VirtualMachineScaleSets")
}
distroValues := DistroValues
if isUpdate {
distroValues = append(distroValues, AKSDockerEngine, AKS1604Deprecated, AKS1804Deprecated)
}
if !validateDistro(agentPoolProfile.Distro, distroValues) {
switch agentPoolProfile.Distro {
case AKSDockerEngine, AKS1604Deprecated:
return errors.Errorf("The %s distro is deprecated, please use %s instead", agentPoolProfile.Distro, AKSUbuntu1604)
case AKS1804Deprecated:
return errors.Errorf("The %s distro is deprecated, please use %s instead", agentPoolProfile.Distro, AKSUbuntu1804)
default:
return errors.Errorf("The %s distro is not supported", agentPoolProfile.Distro)
}
}
if e := agentPoolProfile.validateLoadBalancerBackendAddressPoolIDs(); e != nil {
return e
}
if agentPoolProfile.IsEphemeral() {
log.Warnf("Ephemeral disks are enabled for Agent Pool %s. This feature in AKS-Engine is experimental, and data could be lost in some cases.", agentPoolProfile.Name)
}
if e := validateProximityPlacementGroupID(agentPoolProfile.ProximityPlacementGroupID); e != nil {
return e
}
var validOSDiskCachingType, validDataDiskCachingType bool
for _, valid := range cachingTypesValidValues {
if valid == agentPoolProfile.OSDiskCachingType {
validOSDiskCachingType = true
}
if valid == agentPoolProfile.DataDiskCachingType {
validDataDiskCachingType = true
}
}
if !validOSDiskCachingType {
return errors.Errorf("Invalid osDiskCachingType value \"%s\" for agentPoolProfile \"%s\", please use one of the following versions: %s", agentPoolProfile.OSDiskCachingType, agentPoolProfile.Name, cachingTypesValidValues)
}
if !validDataDiskCachingType {
return errors.Errorf("Invalid dataDiskCachingType value \"%s\" for agentPoolProfile \"%s\", please use one of the following versions: %s", agentPoolProfile.DataDiskCachingType, agentPoolProfile.Name, cachingTypesValidValues)
}
if agentPoolProfile.IsEphemeral() {
if agentPoolProfile.OSDiskCachingType != "" && agentPoolProfile.OSDiskCachingType != string(compute.CachingTypesReadOnly) {
return errors.Errorf("Invalid osDiskCachingType value \"%s\" for agentPoolProfile \"%s\" using Ephemeral Disk, you must use: %s", agentPoolProfile.OSDiskCachingType, agentPoolProfile.Name, string(compute.CachingTypesReadOnly))
}
}
}
return nil
}