func()

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)
}