in pkg/api/vlabs/validate.go [187:360]
func (a *Properties) ValidateOrchestratorProfile(isUpdate bool) error {
o := a.OrchestratorProfile
// On updates we only need to make sure there is a supported patch version for the minor version
if !isUpdate {
version := common.RationalizeReleaseAndVersion(
o.OrchestratorType,
o.OrchestratorRelease,
o.OrchestratorVersion,
isUpdate,
a.HasWindows(),
a.IsAzureStackCloud())
if a.IsAzureStackCloud() {
if version == "" && a.HasWindows() {
return errors.Errorf("the following OrchestratorProfile configuration is not supported on Azure Stack with OsType \"Windows\": OrchestratorType: \"%s\", OrchestratorRelease: \"%s\", OrchestratorVersion: \"%s\". Please use one of the following versions: %v", o.OrchestratorType, o.OrchestratorRelease, o.OrchestratorVersion, common.GetAllSupportedKubernetesVersions(false, true, true))
} else if version == "" {
return errors.Errorf("the following OrchestratorProfile configuration is not supported on Azure Stack: OrchestratorType: \"%s\", OrchestratorRelease: \"%s\", OrchestratorVersion: \"%s\". Please use one of the following versions: %v", o.OrchestratorType, o.OrchestratorRelease, o.OrchestratorVersion, common.GetAllSupportedKubernetesVersions(false, false, true))
}
} else {
if version == "" && a.HasWindows() {
return errors.Errorf("the following OrchestratorProfile configuration is not supported with OsType \"Windows\": OrchestratorType: \"%s\", OrchestratorRelease: \"%s\", OrchestratorVersion: \"%s\". Please use one of the following versions: %v", o.OrchestratorType, o.OrchestratorRelease, o.OrchestratorVersion, common.GetAllSupportedKubernetesVersions(false, true, false))
} else if version == "" {
return errors.Errorf("the following OrchestratorProfile configuration is not supported: OrchestratorType: \"%s\", OrchestratorRelease: \"%s\", OrchestratorVersion: \"%s\". Please use one of the following versions: %v", o.OrchestratorType, o.OrchestratorRelease, o.OrchestratorVersion, common.GetAllSupportedKubernetesVersions(false, false, false))
}
}
sv, err := semver.Make(version)
if err != nil {
return errors.Errorf("could not validate version %s", version)
}
if a.HasAvailabilityZones() {
minVersion, err := semver.Make("1.12.0")
if err != nil {
return errors.New("could not validate version")
}
if sv.LT(minVersion) {
return errors.New("availabilityZone is only available in Kubernetes version 1.12 or greater")
}
}
if o.KubernetesConfig != nil {
err := o.KubernetesConfig.Validate(version, a.HasWindows(), a.FeatureFlags.IsIPv6DualStackEnabled(), a.FeatureFlags.IsIPv6OnlyEnabled(), isUpdate)
if err != nil {
return err
}
if o.KubernetesConfig.EnableAggregatedAPIs {
if !o.KubernetesConfig.IsRBACEnabled() {
return errors.New("enableAggregatedAPIs requires the enableRbac feature as a prerequisite")
}
}
if to.Bool(o.KubernetesConfig.EnableDataEncryptionAtRest) {
if o.KubernetesConfig.EtcdEncryptionKey != "" {
_, err = base64.StdEncoding.DecodeString(o.KubernetesConfig.EtcdEncryptionKey)
if err != nil {
return errors.New("etcdEncryptionKey must be base64 encoded. Please provide a valid base64 encoded value or leave the etcdEncryptionKey empty to auto-generate the value")
}
}
}
if to.Bool(o.KubernetesConfig.EnableEncryptionWithExternalKms) {
if to.Bool(a.OrchestratorProfile.KubernetesConfig.UseManagedIdentity) && a.OrchestratorProfile.KubernetesConfig.UserAssignedID == "" {
log.Warnf("Clusters with enableEncryptionWithExternalKms=true and system-assigned identity are not upgradable! You will not be able to upgrade your cluster using `aks-engine-azurestack upgrade`")
}
}
if to.Bool(o.KubernetesConfig.EnablePodSecurityPolicy) {
log.Warnf("EnablePodSecurityPolicy is deprecated in favor of the addon pod-security-policy.")
if !o.KubernetesConfig.IsRBACEnabled() {
return errors.Errorf("enablePodSecurityPolicy requires the enableRbac feature as a prerequisite")
}
if len(o.KubernetesConfig.PodSecurityPolicyConfig) > 0 {
log.Warnf("Raw manifest for PodSecurityPolicy using PodSecurityPolicyConfig is deprecated in favor of the addon pod-security-policy. This will be ignored.")
}
}
if o.KubernetesConfig.LoadBalancerSku != "" {
if !strings.EqualFold(o.KubernetesConfig.LoadBalancerSku, StandardLoadBalancerSku) && !strings.EqualFold(o.KubernetesConfig.LoadBalancerSku, BasicLoadBalancerSku) {
return errors.Errorf("Invalid value for loadBalancerSku, only %s and %s are supported", StandardLoadBalancerSku, BasicLoadBalancerSku)
}
}
if o.KubernetesConfig.LoadBalancerSku == StandardLoadBalancerSku {
if !to.Bool(a.OrchestratorProfile.KubernetesConfig.ExcludeMasterFromStandardLB) {
return errors.Errorf("standard loadBalancerSku should exclude master nodes. Please set KubernetesConfig \"ExcludeMasterFromStandardLB\" to \"true\"")
}
}
if o.KubernetesConfig.LoadBalancerSku == BasicLoadBalancerSku {
if o.KubernetesConfig.LoadBalancerOutboundIPs != nil {
return errors.Errorf("kubernetesConfig.loadBalancerOutboundIPs configuration only supported for Standard loadBalancerSku=Standard")
}
}
if o.KubernetesConfig.DockerEngineVersion != "" {
log.Warnf("docker-engine is deprecated in favor of moby, but you passed in a dockerEngineVersion configuration. This will be ignored.")
}
if o.KubernetesConfig.MaximumLoadBalancerRuleCount < 0 {
return errors.New("maximumLoadBalancerRuleCount shouldn't be less than 0")
}
if o.KubernetesConfig.LoadBalancerOutboundIPs != nil {
if to.Int(o.KubernetesConfig.LoadBalancerOutboundIPs) > common.MaxLoadBalancerOutboundIPs {
return errors.Errorf("kubernetesConfig.loadBalancerOutboundIPs was set to %d, the maximum allowed is %d", to.Int(o.KubernetesConfig.LoadBalancerOutboundIPs), common.MaxLoadBalancerOutboundIPs)
}
}
// https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-outbound-rules-overview
if o.KubernetesConfig.LoadBalancerSku == StandardLoadBalancerSku && o.KubernetesConfig.OutboundRuleIdleTimeoutInMinutes != 0 && (o.KubernetesConfig.OutboundRuleIdleTimeoutInMinutes < 4 || o.KubernetesConfig.OutboundRuleIdleTimeoutInMinutes > 120) {
return errors.New("outboundRuleIdleTimeoutInMinutes shouldn't be less than 4 or greater than 120")
}
if a.IsAzureStackCloud() {
if common.IsKubernetesVersionGe(a.OrchestratorProfile.OrchestratorVersion, "1.21.0") && !to.Bool(o.KubernetesConfig.UseCloudControllerManager) {
return errors.New("useCloudControllerManager should be set to true for Kubernetes v1.21+ clusters on Azure Stack Hub")
}
if common.IsKubernetesVersionGe(a.OrchestratorProfile.OrchestratorVersion, "1.24.0") && o.KubernetesConfig.ContainerRuntime == Docker {
return errors.Errorf("Docker runtime is no longer supported for v1.24+ clusters, use %s containerRuntime value instead", Containerd)
}
if to.Bool(o.KubernetesConfig.UseInstanceMetadata) {
return errors.New("useInstanceMetadata shouldn't be set to true as feature not yet supported on Azure Stack")
}
if o.KubernetesConfig.EtcdDiskSizeGB != "" {
etcdDiskSizeGB, err := strconv.Atoi(o.KubernetesConfig.EtcdDiskSizeGB)
if err != nil {
return errors.Errorf("could not convert EtcdDiskSizeGB to int")
}
if etcdDiskSizeGB > MaxAzureStackManagedDiskSize {
return errors.Errorf("EtcdDiskSizeGB max size supported on Azure Stack is %d", MaxAzureStackManagedDiskSize)
}
}
}
if o.KubernetesConfig.EtcdStorageLimitGB != 0 {
if o.KubernetesConfig.EtcdStorageLimitGB > 8 {
log.Warnf("EtcdStorageLimitGB of %d is larger than the recommended maximum of 8", o.KubernetesConfig.EtcdStorageLimitGB)
}
if o.KubernetesConfig.EtcdStorageLimitGB < 2 {
return errors.Errorf("EtcdStorageLimitGB value of %d is too small, the minimum allowed is 2", o.KubernetesConfig.EtcdStorageLimitGB)
}
}
}
} else {
version := common.RationalizeReleaseAndVersion(
o.OrchestratorType,
o.OrchestratorRelease,
o.OrchestratorVersion,
false,
a.HasWindows(),
a.IsAzureStackCloud())
if version == "" {
patchVersion := common.GetValidPatchVersion(o.OrchestratorType, o.OrchestratorVersion, isUpdate, a.HasWindows(), a.IsAzureStackCloud())
// if there isn't a supported patch version for this version fail
if patchVersion == "" {
if a.HasWindows() {
return errors.Errorf("the following OrchestratorProfile configuration is not supported with Windows agentpools: OrchestratorType: \"%s\", OrchestratorRelease: \"%s\", OrchestratorVersion: \"%s\". Please check supported Release or Version for this build of aks-engine", o.OrchestratorType, o.OrchestratorRelease, o.OrchestratorVersion)
}
return errors.Errorf("the following OrchestratorProfile configuration is not supported: OrchestratorType: \"%s\", OrchestratorRelease: \"%s\", OrchestratorVersion: \"%s\". Please check supported Release or Version for this build of aks-engine", o.OrchestratorType, o.OrchestratorRelease, o.OrchestratorVersion)
}
}
}
if a.HasFlatcar() && o.KubernetesConfig.NetworkPlugin == "azure" && o.KubernetesConfig.NetworkMode == NetworkModeBridge {
return errors.Errorf("Flatcar node pools require 'transparent' networkMode with Azure CNI")
}
return a.validateContainerRuntime(isUpdate)
}