pkg/agent/params.go (159 lines of code) (raw):

// "copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. package agent import ( "encoding/base64" "strconv" "strings" "github.com/Azure/agentbaker/pkg/agent/datamodel" ) func getParameters(config *datamodel.NodeBootstrappingConfiguration) paramsMap { cs := config.ContainerService profile := config.AgentPoolProfile properties := cs.Properties parametersMap := paramsMap{} cloudSpecConfig := config.CloudSpecConfig linuxProfile := properties.LinuxProfile if linuxProfile != nil { addValue(parametersMap, "linuxAdminUsername", linuxProfile.AdminUsername) } // masterEndpointDNSNamePrefix is the basis for storage account creation across dcos, swarm, and k8s // looks like masterEndpointDNSNamePrefix is only used in windows cse kubeconfig cluster/context name and it's not // required since linux uses static value for that. if properties.HostedMasterProfile != nil { // Agents only, use cluster DNS prefix switch { case properties.HostedMasterProfile.DNSPrefix != "": addValue(parametersMap, "masterEndpointDNSNamePrefix", properties.HostedMasterProfile.DNSPrefix) case properties.HostedMasterProfile.FQDNSubdomain != "": addValue(parametersMap, "masterEndpointDNSNamePrefix", properties.HostedMasterProfile.FQDNSubdomain) default: // should not happen but just in case, we fill in value "localcluster" just like linux addValue(parametersMap, "masterEndpointDNSNamePrefix", "localcluster") } } if properties.HostedMasterProfile != nil { addValue(parametersMap, "vnetCidr", DefaultVNETCIDR) } // Kubernetes Parameters if properties.OrchestratorProfile.IsKubernetes() { assignKubernetesParameters(properties, parametersMap, cloudSpecConfig, config.K8sComponents, config) if profile != nil { assignKubernetesParametersFromAgentProfile(profile, parametersMap, config) } } // Agent parameters // We should always use profile to remove the dependency on cs.Properties.AgentPoolProfiles since RP always set // config.AgentPoolProfile to the target agent pool if len(profile.VnetCidrs) != 0 { // For AKS (properties.HostedMasterProfile != nil), set vnetCidr if a custom vnet is used so the address space can be // added into the ExceptionList of Windows nodes. Otherwise, the default value `10.0.0.0/8` will // be added into the ExceptionList and it does not work if users use other ip address ranges. // All agent pools in the same cluster share a same VnetCidrs addValue(parametersMap, "vnetCidr", strings.Join(profile.VnetCidrs, ",")) } if properties.CustomConfiguration != nil && properties.CustomConfiguration.KubernetesConfigurations != nil { if configuration, ok := properties.CustomConfiguration.KubernetesConfigurations["kubelet"]; ok && configuration.DownloadURL != nil { addValue(parametersMap, "customKubeBinaryURL", configuration.DownloadURL) } } // Windows parameters if properties.HasWindows() { addValue(parametersMap, "windowsDockerVersion", properties.WindowsProfile.GetWindowsDockerVersion()) addValue(parametersMap, "defaultContainerdWindowsSandboxIsolation", properties.WindowsProfile.GetDefaultContainerdWindowsSandboxIsolation()) addValue(parametersMap, "containerdWindowsRuntimeHandlers", properties.WindowsProfile.GetContainerdWindowsRuntimeHandlers()) } return parametersMap } func assignKubernetesParametersFromAgentProfile(profile *datamodel.AgentPoolProfile, parametersMap paramsMap, config *datamodel.NodeBootstrappingConfiguration) { if config.RuncVersion != "" { addValue(parametersMap, "runcVersion", config.RuncVersion) } addValue(parametersMap, "runcPackageURL", config.RuncPackageURL) if profile.KubernetesConfig == nil || profile.KubernetesConfig.ContainerRuntime == "" { return } // override containerRuntime parameter value if specified in AgentPoolProfile // this allows for heteregenous clusters addValue(parametersMap, "containerRuntime", profile.KubernetesConfig.ContainerRuntime) if profile.KubernetesConfig.ContainerRuntime == "containerd" { addValue(parametersMap, "cliTool", "ctr") if config.ContainerdVersion != "" { addValue(parametersMap, "containerdVersion", config.ContainerdVersion) } if config.TeleportdPluginURL != "" { addValue(parametersMap, "teleportdPluginURL", config.TeleportdPluginURL) } addValue(parametersMap, "containerdPackageURL", config.ContainerdPackageURL) } else { addValue(parametersMap, "cliTool", "docker") } } func assignKubernetesParametersfromKubernetesConfig(properties *datamodel.Properties, parametersMap paramsMap, cloudSpecConfig *datamodel.AzureEnvironmentSpecConfig, k8sComponents *datamodel.K8sComponents, config *datamodel.NodeBootstrappingConfiguration) { orchestratorProfile := properties.OrchestratorProfile if !orchestratorProfile.IsKubernetes() { return } k8sVersion := orchestratorProfile.OrchestratorVersion addValue(parametersMap, "kubernetesVersion", k8sVersion) kubernetesConfig := orchestratorProfile.KubernetesConfig if kubernetesConfig == nil { return } if kubernetesConfig.CustomKubeProxyImage != "" { // kubernetesConfig.CustomKubeProxyImage is ap level property, AKS default CustomKubeProxyImage // is 'multi-arch', no need to differentiate amd64/arm64 ap addValue(parametersMap, "kubeProxySpec", kubernetesConfig.CustomKubeProxyImage) } if kubernetesConfig.CustomKubeBinaryURL != "" { // kubernetesConfig.CustomKubeBinaryURL is ap level property, CustomKubeBinaryURL is // set to different for amd64/arm64 ap in RP side. addValue(parametersMap, "kubeBinaryURL", kubernetesConfig.CustomKubeBinaryURL) } addValue(parametersMap, "kubernetesHyperkubeSpec", k8sComponents.HyperkubeImageURL) addValue(parametersMap, "kubeDNSServiceIP", kubernetesConfig.DNSServiceIP) addValue(parametersMap, "cloudproviderConfig", paramsMap{ "cloudProviderBackoffMode": kubernetesConfig.CloudProviderBackoffMode, "cloudProviderBackoff": kubernetesConfig.CloudProviderBackoff, "cloudProviderBackoffRetries": kubernetesConfig.CloudProviderBackoffRetries, "cloudProviderBackoffJitter": strconv.FormatFloat(kubernetesConfig.CloudProviderBackoffJitter, 'f', -1, 64), "cloudProviderBackoffDuration": kubernetesConfig.CloudProviderBackoffDuration, "cloudProviderBackoffExponent": strconv.FormatFloat(kubernetesConfig.CloudProviderBackoffExponent, 'f', -1, 64), "cloudProviderRateLimit": kubernetesConfig.CloudProviderRateLimit, "cloudProviderRateLimitQPS": strconv.FormatFloat(kubernetesConfig.CloudProviderRateLimitQPS, 'f', -1, 64), "cloudProviderRateLimitQPSWrite": strconv.FormatFloat(kubernetesConfig.CloudProviderRateLimitQPSWrite, 'f', -1, 64), "cloudProviderRateLimitBucket": kubernetesConfig.CloudProviderRateLimitBucket, "cloudProviderRateLimitBucketWrite": kubernetesConfig.CloudProviderRateLimitBucketWrite, "cloudProviderDisableOutboundSNAT": kubernetesConfig.CloudProviderDisableOutboundSNAT, }) addValue(parametersMap, "kubeClusterCidr", kubernetesConfig.ClusterSubnet) addValue(parametersMap, "dockerBridgeCidr", kubernetesConfig.DockerBridgeSubnet) addValue(parametersMap, "networkPolicy", kubernetesConfig.NetworkPolicy) addValue(parametersMap, "networkPlugin", kubernetesConfig.NetworkPlugin) addValue(parametersMap, "networkMode", kubernetesConfig.NetworkMode) addValue(parametersMap, "containerRuntime", kubernetesConfig.ContainerRuntime) addValue(parametersMap, "containerdDownloadURLBase", cloudSpecConfig.KubernetesSpecConfig.ContainerdDownloadURLBase) if config.IsARM64 { addValue(parametersMap, "vnetCniLinuxPluginsURL", kubernetesConfig.GetAzureCNIURLARM64Linux(cloudSpecConfig)) } else { addValue(parametersMap, "vnetCniLinuxPluginsURL", kubernetesConfig.GetAzureCNIURLLinux(cloudSpecConfig)) } addValue(parametersMap, "vnetCniWindowsPluginsURL", kubernetesConfig.GetAzureCNIURLWindows(cloudSpecConfig)) addValue(parametersMap, "linuxCredentialProviderURL", k8sComponents.LinuxCredentialProviderURL) if properties.HasWindows() { addValue(parametersMap, "kubeBinariesSASURL", k8sComponents.WindowsPackageURL) addValue(parametersMap, "windowsContainerdURL", kubernetesConfig.WindowsContainerdURL) addValue(parametersMap, "kubeServiceCidr", kubernetesConfig.ServiceCIDR) addValue(parametersMap, "kubeBinariesVersion", k8sVersion) addValue(parametersMap, "windowsTelemetryGUID", cloudSpecConfig.KubernetesSpecConfig.WindowsTelemetryGUID) addValue(parametersMap, "windowsSdnPluginURL", kubernetesConfig.WindowsSdnPluginURL) addValue(parametersMap, "windowsCredentialProviderURL", k8sComponents.WindowsCredentialProviderURL) } } func assignKubernetesParameters(properties *datamodel.Properties, parametersMap paramsMap, cloudSpecConfig *datamodel.AzureEnvironmentSpecConfig, k8sComponents *datamodel.K8sComponents, config *datamodel.NodeBootstrappingConfiguration) { orchestratorProfile := properties.OrchestratorProfile if orchestratorProfile.IsKubernetes() { k8sVersion := orchestratorProfile.OrchestratorVersion addValue(parametersMap, "kubernetesVersion", k8sVersion) assignKubernetesParametersfromKubernetesConfig(properties, parametersMap, cloudSpecConfig, k8sComponents, config) servicePrincipalProfile := properties.ServicePrincipalProfile if servicePrincipalProfile != nil { addValue(parametersMap, "servicePrincipalClientId", servicePrincipalProfile.ClientID) encodedServicePrincipalClientSecret := base64.StdEncoding.EncodeToString([]byte(servicePrincipalProfile.Secret)) addValue(parametersMap, "servicePrincipalClientSecret", servicePrincipalProfile.Secret) // base64 encoding is to escape special characters like quotes in service principal // reference: https://github.com/Azure/aks-engine/pull/1174 addValue(parametersMap, "encodedServicePrincipalClientSecret", encodedServicePrincipalClientSecret) } /** The following parameters could be either a plain text, or referenced to a secret in a keyvault: - apiServerCertificate - clientCertificate - clientPrivateKey - kubeConfigCertificate - kubeConfigPrivateKey - servicePrincipalClientSecret To refer to a keyvault secret, the value of the parameter in the api model file should be formatted as: "<PARAMETER>": "/subscriptions/<SUB_ID>/resourceGroups/<RG_NAME>/providers/Microsoft.KeyVault/vaults/<KV_NAME>/secrets/<NAME>[/<VERSION>]" where: <SUB_ID> is the subscription ID of the keyvault <RG_NAME> is the resource group of the keyvault <KV_NAME> is the name of the keyvault <NAME> is the name of the secret. <VERSION> (optional) is the version of the secret (default: the latest version) This will generate a reference block in the parameters file: "reference": { "keyVault": { "id": "/subscriptions/<SUB_ID>/resourceGroups/<RG_NAME>/providers/Microsoft.KeyVault/vaults/<KV_NAME>" }, "secretName": "<NAME>" "secretVersion": "<VERSION>" } **/ certificateProfile := properties.CertificateProfile if certificateProfile != nil { addSecret(parametersMap, "apiServerCertificate", certificateProfile.APIServerCertificate, true) addSecret(parametersMap, "caCertificate", certificateProfile.CaCertificate, true) addSecret(parametersMap, "clientCertificate", certificateProfile.ClientCertificate, true) addSecret(parametersMap, "clientPrivateKey", certificateProfile.ClientPrivateKey, true) } } }