func getContainerServiceFuncMap()

in pkg/agent/baker.go [362:1025]


func getContainerServiceFuncMap(config *datamodel.NodeBootstrappingConfiguration) template.FuncMap {
	cs := config.ContainerService
	profile := config.AgentPoolProfile
	return template.FuncMap{
		"Disable1804SystemdResolved": func() bool {
			return config.Disable1804SystemdResolved
		},
		// This was DisableUnattendedUpgrade when we had UU enabled by default in image.
		// Now we don't, so we have to deliberately enable it.
		// Someone smarter than me can fix the API.
		"EnableUnattendedUpgrade": func() bool {
			return !config.DisableUnattendedUpgrades
		},
		"IsIPMasqAgentEnabled": func() bool {
			return cs.Properties.IsIPMasqAgentEnabled()
		},
		"IsKubernetesVersionGe": func(version string) bool {
			return cs.Properties.OrchestratorProfile.IsKubernetes() && IsKubernetesVersionGe(cs.Properties.OrchestratorProfile.OrchestratorVersion, version)
		},
		"GetAgentKubernetesLabels": func(profile *datamodel.AgentPoolProfile) string {
			return profile.GetKubernetesLabels()
		},
		"GetAgentKubernetesLabelsDeprecated": func(profile *datamodel.AgentPoolProfile) string {
			return profile.GetKubernetesLabels()
		},
		"GetGPUInstanceProfile": func() string {
			return config.GPUInstanceProfile
		},
		"IsMIGEnabledNode": func() bool {
			return config.GPUInstanceProfile != ""
		},
		"GetKubeletConfigFileContent": func() string {
			return GetKubeletConfigFileContent(config.KubeletConfig, profile.CustomKubeletConfig)
		},
		"GetKubeletConfigFileContentBase64": func() string {
			return base64.StdEncoding.EncodeToString([]byte(GetKubeletConfigFileContent(config.KubeletConfig, profile.CustomKubeletConfig)))
		},
		"IsKubeletConfigFileEnabled": func() bool {
			return IsKubeletConfigFileEnabled(cs, profile, config.EnableKubeletConfigFile)
		},
		"EnableSecureTLSBootstrapping": func() bool {
			// this will be true when we can perform TLS bootstrapping without the use of a hard-coded bootstrap token.
			return config.EnableSecureTLSBootstrapping
		},
		"GetCustomSecureTLSBootstrapAADServerAppID": func() string {
			return config.CustomSecureTLSBootstrapAADServerAppID
		},
		"GetTLSBootstrapTokenForKubeConfig": func() string {
			return GetTLSBootstrapTokenForKubeConfig(config.KubeletClientTLSBootstrapToken)
		},
		"EnableKubeletServingCertificateRotation": func() bool {
			return IsKubeletServingCertificateRotationEnabled(config)
		},
		"GetKubeletConfigKeyVals": func() string {
			return GetOrderedKubeletConfigFlagString(config)
		},
		"GetKubeletConfigKeyValsPsh": func() string {
			return config.GetOrderedKubeletConfigStringForPowershell(profile.CustomKubeletConfig)
		},
		"GetKubeproxyConfigKeyValsPsh": func() string {
			return config.GetOrderedKubeproxyConfigStringForPowershell()
		},
		"IsCgroupV2": func() bool {
			return profile.Is2204VHDDistro() || profile.IsAzureLinuxCgroupV2VHDDistro() || profile.Is2404VHDDistro()
		},
		"GetKubeProxyFeatureGatesPsh": func() string {
			return cs.Properties.GetKubeProxyFeatureGatesWindowsArguments()
		},
		"ShouldConfigCustomSysctl": func() bool {
			return profile.CustomLinuxOSConfig != nil && profile.CustomLinuxOSConfig.Sysctls != nil
		},
		"GetCustomSysctlConfigByName": func(fn string) interface{} {
			if profile.CustomLinuxOSConfig != nil && profile.CustomLinuxOSConfig.Sysctls != nil {
				v := reflect.ValueOf(*profile.CustomLinuxOSConfig.Sysctls)
				return v.FieldByName(fn).Interface()
			}
			return nil
		},
		"ShouldConfigTransparentHugePage": func() bool {
			return profile.CustomLinuxOSConfig != nil && (profile.CustomLinuxOSConfig.TransparentHugePageEnabled != "" ||
				profile.CustomLinuxOSConfig.TransparentHugePageDefrag != "")
		},
		"GetTransparentHugePageEnabled": func() string {
			if profile.CustomLinuxOSConfig == nil {
				return ""
			}
			return profile.CustomLinuxOSConfig.TransparentHugePageEnabled
		},
		"GetTransparentHugePageDefrag": func() string {
			if profile.CustomLinuxOSConfig == nil {
				return ""
			}
			return profile.CustomLinuxOSConfig.TransparentHugePageDefrag
		},
		"ShouldConfigSwapFile": func() bool {
			// only configure swap file when FailSwapOn is false and SwapFileSizeMB is valid
			return profile.CustomKubeletConfig != nil && profile.CustomKubeletConfig.FailSwapOn != nil && !*profile.CustomKubeletConfig.FailSwapOn &&
				profile.CustomLinuxOSConfig != nil && profile.CustomLinuxOSConfig.SwapFileSizeMB != nil && *profile.CustomLinuxOSConfig.SwapFileSizeMB > 0
		},
		"GetSwapFileSizeMB": func() int32 {
			if profile.CustomLinuxOSConfig != nil && profile.CustomLinuxOSConfig.SwapFileSizeMB != nil {
				return *profile.CustomLinuxOSConfig.SwapFileSizeMB
			}
			return 0
		},
		"ShouldConfigContainerdUlimits": func() bool {
			return profile.GetCustomLinuxOSConfig().GetUlimitConfig() != nil
		},
		"GetContainerdUlimitString": func() string {
			ulimitConfig := profile.GetCustomLinuxOSConfig().GetUlimitConfig()
			if ulimitConfig == nil {
				return ""
			}
			var sb strings.Builder
			sb.WriteString("[Service]\n")
			if ulimitConfig.MaxLockedMemory != "" {
				sb.WriteString(fmt.Sprintf("LimitMEMLOCK=%s\n", ulimitConfig.MaxLockedMemory))
			}
			if ulimitConfig.NoFile != "" {
				// ulimit is removed in containerd 2.0+, which is available only in ubuntu2404 distro
				// https://github.com/containerd/containerd/blob/main/docs/containerd-2.0.md#limitnofile-configuration-has-been-removed
				if !profile.Is2404VHDDistro() {
					sb.WriteString(fmt.Sprintf("LimitNOFILE=%s\n", ulimitConfig.NoFile))
				}
			}
			return sb.String()
		},
		"IsKubernetes": func() bool {
			return cs.Properties.OrchestratorProfile.IsKubernetes()
		},
		"GetKubernetesEndpoint": func() string {
			return GetKubernetesEndpoint(cs)
		},
		"IsAzureCNI": func() bool {
			return cs.Properties.OrchestratorProfile.IsAzureCNI()
		},
		"IsNoneCNI": func() bool {
			return cs.Properties.OrchestratorProfile.IsNoneCNI()
		},
		"IsMariner": func() bool {
			// TODO(ace): do we care about both? 2nd one should be more general and catch custom VHD for mariner
			return profile.Distro.IsAzureLinuxDistro() || isMariner(config.OSSKU)
		},
		"IsKata": func() bool {
			return profile.Distro.IsKataDistro()
		},
		"IsCustomImage": func() bool {
			return profile.Distro == datamodel.CustomizedImage || profile.Distro == datamodel.CustomizedImageKata
		},
		"EnableHostsConfigAgent": func() bool {
			return cs.Properties.OrchestratorProfile.KubernetesConfig != nil &&
				cs.Properties.OrchestratorProfile.KubernetesConfig.PrivateCluster != nil &&
				to.Bool(cs.Properties.OrchestratorProfile.KubernetesConfig.PrivateCluster.EnableHostsConfigAgent)
		},
		"UseManagedIdentity": func() bool {
			return cs.Properties.OrchestratorProfile.KubernetesConfig.UseManagedIdentity
		},
		"GetSshPublicKeysPowerShell": func() string {
			return getSSHPublicKeysPowerShell(cs.Properties.LinuxProfile)
		},
		"GetKubernetesAgentPreprovisionYaml": func(profile *datamodel.AgentPoolProfile) string {
			str := ""
			if profile.PreprovisionExtension != nil {
				str += "\n"
				str += makeAgentExtensionScriptCommands(cs, profile)
			}
			return str
		},
		"GetKubernetesWindowsAgentFunctions": func() string {
			// Collect all the parts into a zip
			neededParts := []string{
				kubernetesWindowsCSEHelperPS1,
				kubernetesWindowsSendLogsPS1,
			}

			// Create a buffer, new zip
			buf := new(bytes.Buffer)
			zw := zip.NewWriter(buf)

			for _, part := range neededParts {
				f, err := zw.Create(part)
				if err != nil {
					panic(err)
				}
				partContents, err := parts.Templates.ReadFile(part)
				if err != nil {
					panic(err)
				}
				_, err = f.Write(partContents)
				if err != nil {
					panic(err)
				}
			}
			err := zw.Close()
			if err != nil {
				panic(err)
			}
			return base64.StdEncoding.EncodeToString(buf.Bytes())
		},
		"IsNSeriesSKU": func() bool {
			return config.EnableNvidia
		},
		"HasCustomSearchDomain": func() bool {
			return cs.Properties.LinuxProfile != nil && cs.Properties.LinuxProfile.HasSearchDomain()
		},
		"GetSearchDomainName": func() string {
			if cs.Properties.LinuxProfile != nil && cs.Properties.LinuxProfile.HasSearchDomain() {
				return cs.Properties.LinuxProfile.CustomSearchDomain.Name
			}
			return ""
		},
		"GetSearchDomainRealmUser": func() string {
			if cs.Properties.LinuxProfile != nil && cs.Properties.LinuxProfile.HasSearchDomain() {
				return cs.Properties.LinuxProfile.CustomSearchDomain.RealmUser
			}
			return ""
		},
		"GetSearchDomainRealmPassword": func() string {
			if cs.Properties.LinuxProfile != nil && cs.Properties.LinuxProfile.HasSearchDomain() {
				return cs.Properties.LinuxProfile.CustomSearchDomain.RealmPassword
			}
			return ""
		},
		"HasCalicoNetworkPolicy": func() bool {
			return cs.Properties.OrchestratorProfile.KubernetesConfig.NetworkPolicy == NetworkPolicyCalico
		},
		"HasAntreaNetworkPolicy": func() bool {
			return cs.Properties.OrchestratorProfile.KubernetesConfig.NetworkPolicy == NetworkPolicyAntrea
		},
		"HasFlannelNetworkPlugin": func() bool {
			return cs.Properties.OrchestratorProfile.KubernetesConfig.NetworkPlugin == NetworkPluginFlannel
		},
		"HasKubeletClientKey": func() bool {
			return cs.Properties.CertificateProfile != nil && cs.Properties.CertificateProfile.ClientPrivateKey != ""
		},
		"GetKubeletClientKey": func() string {
			if cs.Properties.CertificateProfile != nil && cs.Properties.CertificateProfile.ClientPrivateKey != "" {
				encoded := base64.StdEncoding.EncodeToString([]byte(cs.Properties.CertificateProfile.ClientPrivateKey))
				return encoded
			}
			return ""
		},
		"GetKubeletClientCert": func() string {
			if cs.Properties.CertificateProfile != nil && cs.Properties.CertificateProfile.ClientCertificate != "" {
				encoded := base64.StdEncoding.EncodeToString([]byte(cs.Properties.CertificateProfile.ClientCertificate))
				return encoded
			}
			return ""
		},
		"HasServicePrincipalSecret": func() bool {
			return cs.Properties.ServicePrincipalProfile != nil && cs.Properties.ServicePrincipalProfile.Secret != ""
		},
		"GetServicePrincipalSecret": func() string {
			if cs.Properties.ServicePrincipalProfile != nil && cs.Properties.ServicePrincipalProfile.Secret != "" {
				encoded := base64.StdEncoding.EncodeToString([]byte(cs.Properties.ServicePrincipalProfile.Secret))
				return encoded
			}
			return ""
		},
		"WindowsSSHEnabled": func() bool {
			return cs.Properties.WindowsProfile.GetSSHEnabled()
		},
		"IsIPv6DualStackFeatureEnabled": func() bool {
			return cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack")
		},
		"IsAzureCNIOverlayFeatureEnabled": func() bool {
			return cs.Properties.OrchestratorProfile.KubernetesConfig.IsUsingNetworkPluginMode("overlay")
		},
		"CiliumDataplaneEnabled": func() bool {
			return cs.Properties.OrchestratorProfile.KubernetesConfig.EbpfDataplane == datamodel.EbpfDataplane_cilium
		},
		"GetBase64EncodedEnvironmentJSON": func() string {
			customEnvironmentJSON, _ := cs.Properties.GetCustomEnvironmentJSON(false)
			return base64.StdEncoding.EncodeToString([]byte(customEnvironmentJSON))
		},
		"GetIdentitySystem": func() string {
			return datamodel.AzureADIdentitySystem
		},
		"GetPodInfraContainerSpec": func() string {
			return config.K8sComponents.PodInfraContainerImageURL
		},
		"IsKubenet": func() bool {
			return cs.Properties.OrchestratorProfile.KubernetesConfig.NetworkPlugin == NetworkPluginKubenet
		},
		"NeedsContainerd": func() bool {
			if profile != nil && profile.KubernetesConfig != nil && profile.KubernetesConfig.ContainerRuntime != "" {
				return profile.KubernetesConfig.NeedsContainerd()
			}
			return cs.Properties.OrchestratorProfile.KubernetesConfig.NeedsContainerd()
		},
		"UseRuncShimV2": func() bool {
			return config.EnableRuncShimV2
		},
		"IsDockerContainerRuntime": func() bool {
			if profile != nil && profile.KubernetesConfig != nil && profile.KubernetesConfig.ContainerRuntime != "" {
				return profile.KubernetesConfig.ContainerRuntime == datamodel.Docker
			}
			return cs.Properties.OrchestratorProfile.KubernetesConfig.ContainerRuntime == datamodel.Docker
		},
		"RequiresDocker": func() bool {
			if profile != nil && profile.KubernetesConfig != nil && profile.KubernetesConfig.ContainerRuntime != "" {
				return profile.KubernetesConfig.RequiresDocker()
			}
			return cs.Properties.OrchestratorProfile.KubernetesConfig.RequiresDocker()
		},
		"HasDataDir": func() bool {
			return HasDataDir(config)
		},
		"GetDataDir": func() string {
			return GetDataDir(config)
		},
		"HasKubeletDiskType": func() bool {
			return profile != nil && profile.KubeletDiskType != "" && profile.KubeletDiskType != datamodel.OSDisk
		},
		"GetKubeletDiskType": func() string {
			if profile != nil && profile.KubeletDiskType != "" && profile.KubeletDiskType != datamodel.OSDisk {
				return string(profile.KubeletDiskType)
			}
			return ""
		},
		"IsKrustlet": func() bool {
			return strings.EqualFold(string(profile.WorkloadRuntime), string(datamodel.WasmWasi))
		},
		"GetBase64CertificateAuthorityData": func() string {
			if cs != nil && cs.Properties != nil && cs.Properties.CertificateProfile != nil && cs.Properties.CertificateProfile.CaCertificate != "" {
				data := cs.Properties.CertificateProfile.CaCertificate
				return base64.StdEncoding.EncodeToString([]byte(data))
			}
			return ""
		},
		"GetKubenetTemplate": func() string {
			return base64.StdEncoding.EncodeToString([]byte(kubenetCniTemplate))
		},
		"GetContainerdConfigContent": func() string {
			output, err := containerdConfigFromTemplate(config, profile, func(profile *datamodel.AgentPoolProfile) ContainerdConfigTemplate {
				if profile.Is2404VHDDistro() {
					return containerdV2ConfigTemplate
				}
				return containerdV1ConfigTemplate
			}(profile))
			if err != nil {
				panic(err)
			}
			return output
		},
		"GetContainerdConfigNoGPUContent": func() string {
			output, err := containerdConfigFromTemplate(config, profile, func(profile *datamodel.AgentPoolProfile) ContainerdConfigTemplate {
				if profile.Is2404VHDDistro() {
					return containerdV2NoGPUConfigTemplate
				}
				return containerdV1NoGPUConfigTemplate
			}(profile))

			if err != nil {
				panic(err)
			}
			return output
		},
		"TeleportEnabled": func() bool {
			return config.EnableACRTeleportPlugin
		},
		"HasDCSeriesSKU": func() bool {
			return cs.Properties.HasDCSeriesSKU()
		},
		"GetHyperkubeImageReference": func() string {
			return config.K8sComponents.HyperkubeImageURL
		},
		"GetLinuxPrivatePackageURL": func() string {
			return config.K8sComponents.LinuxPrivatePackageURL
		},
		"GetTargetEnvironment": func() string {
			if cs.IsAKSCustomCloud() {
				return cs.Properties.CustomCloudEnv.Name
			}
			return GetCloudTargetEnv(cs.Location)
		},
		"IsAKSCustomCloud": func() bool {
			return cs.IsAKSCustomCloud()
		},
		"GetInitAKSCustomCloudFilepath": func() string {
			return initAKSCustomCloudFilepath
		},
		"AKSCustomCloudRepoDepotEndpoint": func() string {
			return cs.Properties.CustomCloudEnv.RepoDepotEndpoint
		},
		"AKSCustomCloudManagementPortalURL": func() string {
			return cs.Properties.CustomCloudEnv.ManagementPortalURL
		},
		"AKSCustomCloudPublishSettingsURL": func() string {
			return cs.Properties.CustomCloudEnv.PublishSettingsURL
		},
		"AKSCustomCloudServiceManagementEndpoint": func() string {
			return cs.Properties.CustomCloudEnv.ServiceManagementEndpoint
		},
		"AKSCustomCloudResourceManagerEndpoint": func() string {
			return cs.Properties.CustomCloudEnv.ResourceManagerEndpoint
		},
		"AKSCustomCloudActiveDirectoryEndpoint": func() string {
			return cs.Properties.CustomCloudEnv.ActiveDirectoryEndpoint
		},
		"AKSCustomCloudGalleryEndpoint": func() string {
			return cs.Properties.CustomCloudEnv.GalleryEndpoint
		},
		"AKSCustomCloudKeyVaultEndpoint": func() string {
			return cs.Properties.CustomCloudEnv.KeyVaultEndpoint
		},
		"AKSCustomCloudGraphEndpoint": func() string {
			return cs.Properties.CustomCloudEnv.GraphEndpoint
		},
		"AKSCustomCloudServiceBusEndpoint": func() string {
			return cs.Properties.CustomCloudEnv.ServiceBusEndpoint
		},
		"AKSCustomCloudBatchManagementEndpoint": func() string {
			return cs.Properties.CustomCloudEnv.BatchManagementEndpoint
		},
		"AKSCustomCloudStorageEndpointSuffix": func() string {
			return cs.Properties.CustomCloudEnv.StorageEndpointSuffix
		},
		"AKSCustomCloudSqlDatabaseDNSSuffix": func() string {
			return cs.Properties.CustomCloudEnv.SQLDatabaseDNSSuffix
		},
		"AKSCustomCloudTrafficManagerDNSSuffix": func() string {
			return cs.Properties.CustomCloudEnv.TrafficManagerDNSSuffix
		},
		"AKSCustomCloudKeyVaultDNSSuffix": func() string {
			return cs.Properties.CustomCloudEnv.KeyVaultDNSSuffix
		},
		"AKSCustomCloudServiceBusEndpointSuffix": func() string {
			return cs.Properties.CustomCloudEnv.ServiceBusEndpointSuffix
		},
		"AKSCustomCloudServiceManagementVMDNSSuffix": func() string {
			return cs.Properties.CustomCloudEnv.ServiceManagementVMDNSSuffix
		},
		"AKSCustomCloudResourceManagerVMDNSSuffix": func() string {
			return cs.Properties.CustomCloudEnv.ResourceManagerVMDNSSuffix
		},
		"AKSCustomCloudContainerRegistryDNSSuffix": func() string {
			return cs.Properties.CustomCloudEnv.ContainerRegistryDNSSuffix
		},
		"AKSCustomCloudCosmosDBDNSSuffix": func() string {
			return cs.Properties.CustomCloudEnv.CosmosDBDNSSuffix
		},
		"AKSCustomCloudTokenAudience": func() string {
			return cs.Properties.CustomCloudEnv.TokenAudience
		},
		"AKSCustomCloudResourceIdentifiersGraph": func() string {
			return cs.Properties.CustomCloudEnv.ResourceIdentifiers.Graph
		},
		"AKSCustomCloudResourceIdentifiersKeyVault": func() string {
			return cs.Properties.CustomCloudEnv.ResourceIdentifiers.KeyVault
		},
		"AKSCustomCloudResourceIdentifiersDatalake": func() string {
			return cs.Properties.CustomCloudEnv.ResourceIdentifiers.Datalake
		},
		"AKSCustomCloudResourceIdentifiersBatch": func() string {
			return cs.Properties.CustomCloudEnv.ResourceIdentifiers.Batch
		},
		"AKSCustomCloudResourceIdentifiersOperationalInsights": func() string {
			return cs.Properties.CustomCloudEnv.ResourceIdentifiers.OperationalInsights
		},
		"AKSCustomCloudResourceIdentifiersStorage": func() string {
			return cs.Properties.CustomCloudEnv.ResourceIdentifiers.Storage
		},
		"GetCSEHelpersScriptFilepath": func() string {
			return cseHelpersScriptFilepath
		},
		"GetCSEHelpersScriptDistroFilepath": func() string {
			return cseHelpersScriptDistroFilepath
		},
		"GetCSEInstallScriptFilepath": func() string {
			return cseInstallScriptFilepath
		},
		"GetCSEInstallScriptDistroFilepath": func() string {
			return cseInstallScriptDistroFilepath
		},
		"GetCSEConfigScriptFilepath": func() string {
			return cseConfigScriptFilepath
		},
		"GetCustomSearchDomainsCSEScriptFilepath": func() string {
			return customSearchDomainsCSEScriptFilepath
		},
		"GetDHCPv6ServiceCSEScriptFilepath": func() string {
			return dhcpV6ServiceCSEScriptFilepath
		},
		"GetDHCPv6ConfigCSEScriptFilepath": func() string {
			return dhcpV6ConfigCSEScriptFilepath
		},
		"HasPrivateAzureRegistryServer": func() bool {
			return cs.Properties.OrchestratorProfile.KubernetesConfig.PrivateAzureRegistryServer != ""
		},
		"GetPrivateAzureRegistryServer": func() string {
			return cs.Properties.OrchestratorProfile.KubernetesConfig.PrivateAzureRegistryServer
		},
		"OpenBraces": func() string {
			return "{{"
		},
		"CloseBraces": func() string {
			return "}}"
		},
		"BoolPtrToInt": func(p *bool) int {
			if p == nil {
				return 0
			}
			if v := *p; v {
				return 1
			}
			return 0
		},
		"UserAssignedIDEnabled": func() bool {
			// TODO(qinhao): we need to move this to NodeBootstrappingConfiguration as cs.Properties
			//               is to be moved away from NodeBootstrappingConfiguration
			return cs.Properties.OrchestratorProfile.KubernetesConfig.UserAssignedIDEnabled()
		},
		// HTTP proxy related funcs
		"ShouldConfigureHTTPProxy": func() bool {
			return config.HTTPProxyConfig != nil && (config.HTTPProxyConfig.HTTPProxy != nil || config.HTTPProxyConfig.HTTPSProxy != nil)
		},
		"HasHTTPProxy": func() bool {
			return config.HTTPProxyConfig != nil && config.HTTPProxyConfig.HTTPProxy != nil
		},
		"HasHTTPSProxy": func() bool {
			return config.HTTPProxyConfig != nil && config.HTTPProxyConfig.HTTPSProxy != nil
		},
		"HasNoProxy": func() bool {
			return config.HTTPProxyConfig != nil && config.HTTPProxyConfig.NoProxy != nil
		},
		"GetHTTPProxy": func() string {
			if config.HTTPProxyConfig != nil && config.HTTPProxyConfig.HTTPProxy != nil {
				return *config.HTTPProxyConfig.HTTPProxy
			}
			return ""
		},
		"GetHTTPSProxy": func() string {
			if config.HTTPProxyConfig != nil && config.HTTPProxyConfig.HTTPSProxy != nil {
				return *config.HTTPProxyConfig.HTTPSProxy
			}
			return ""
		},
		"GetNoProxy": func() string {
			if config.HTTPProxyConfig != nil && config.HTTPProxyConfig.NoProxy != nil {
				return strings.Join(*config.HTTPProxyConfig.NoProxy, ",")
			}
			return ""
		},
		"ShouldConfigureHTTPProxyCA": func() bool {
			return config.HTTPProxyConfig != nil && config.HTTPProxyConfig.TrustedCA != nil
		},
		"GetHTTPProxyCA": func() string {
			if config.HTTPProxyConfig != nil && config.HTTPProxyConfig.TrustedCA != nil {
				return *config.HTTPProxyConfig.TrustedCA
			}
			return ""
		},
		"FIPSEnabled": func() bool {
			return config.FIPSEnabled
		},
		"GetMessageOfTheDay": func() string {
			return profile.MessageOfTheDay
		},
		"GetProxyVariables": func() string {
			return getProxyVariables(config)
		},
		"GetOutboundCommand": func() string {
			return getOutBoundCmd(config, config.CloudSpecConfig)
		},
		"BlockOutboundNetwork": func() bool {
			if config.OutboundType == datamodel.OutboundTypeBlock || config.OutboundType == datamodel.OutboundTypeNone {
				return true
			}
			return false
		},
		"GPUNeedsFabricManager": func() bool {
			return GPUNeedsFabricManager(profile.VMSize)
		},
		"GPUDriverVersion": func() string {
			return GetGPUDriverVersion(profile.VMSize)
		},
		"GPUImageSHA": func() string {
			return GetAKSGPUImageSHA(profile.VMSize)
		},
		"GPUDriverType": func() string {
			return GetGPUDriverType(profile.VMSize)
		},
		"GetHnsRemediatorIntervalInMinutes": func() uint32 {
			// Only need to enable HNSRemediator for Windows 2019
			if cs.Properties.WindowsProfile != nil && profile.Distro == datamodel.AKSWindows2019Containerd {
				return cs.Properties.WindowsProfile.GetHnsRemediatorIntervalInMinutes()
			}
			return 0
		},
		"ShouldConfigureCustomCATrust": func() bool {
			return areCustomCATrustCertsPopulated(*config)
		},
		"GetCustomCATrustConfigCerts": func() []string {
			if areCustomCATrustCertsPopulated(*config) {
				return config.CustomCATrustConfig.CustomCATrustCerts
			}
			return []string{}
		},
		"GetLogGeneratorIntervalInMinutes": func() uint32 {
			if cs.Properties.WindowsProfile != nil {
				return cs.Properties.WindowsProfile.GetLogGeneratorIntervalInMinutes()
			}
			return 0
		},
		"ShouldDisableSSH": func() bool {
			return config.SSHStatus == datamodel.SSHOff
		},
		"GetSysctlContent": func() (string, error) {
			templateFuncMap := make(template.FuncMap)
			templateFuncMap["getPortRangeEndValue"] = getPortRangeEndValue
			sysctlTemplate, err := template.New("sysctl").Funcs(templateFuncMap).Parse(sysctlTemplateString)
			if err != nil {
				return "", fmt.Errorf("failed to parse sysctl template: %w", err)
			}

			var b bytes.Buffer
			if err = sysctlTemplate.Execute(&b, profile); err != nil {
				return "", fmt.Errorf("failed to execute sysctl template: %w", err)
			}
			return base64.StdEncoding.EncodeToString(b.Bytes()), nil
		},
		"ShouldEnableCustomData": func() bool {
			return !config.DisableCustomData
		},
		"GetPrivateEgressProxyAddress": func() string {
			return config.ContainerService.Properties.SecurityProfile.GetProxyAddress()
		},
		"GetBootstrapProfileContainerRegistryServer": func() string {
			return config.ContainerService.Properties.SecurityProfile.GetPrivateEgressContainerRegistryServer()
		},
		"GetMCRRepositoryBase": func() string {
			if config.CloudSpecConfig.KubernetesSpecConfig.MCRKubernetesImageBase == "" {
				return "mcr.microsoft.com"
			}
			return config.CloudSpecConfig.KubernetesSpecConfig.MCRKubernetesImageBase
		},
		"IsArtifactStreamingEnabled": func() bool {
			return config.EnableArtifactStreaming
		},
		"EnableIMDSRestriction": func() bool {
			return config.EnableIMDSRestriction
		},
		"InsertIMDSRestrictionRuleToMangleTable": func() bool {
			return config.InsertIMDSRestrictionRuleToMangleTable
		},
		"ShouldEnableLocalDNS": func() bool {
			return profile.ShouldEnableLocalDNS()
		},
		"GetGeneratedLocalDNSCoreFile": func() (string, error) {
			output, err := GenerateLocalDNSCoreFile(config, profile, localDNSCoreFileTemplateString)
			if err != nil {
				return "", fmt.Errorf("failed generate corefile for localdns using template: %w", err)
			}
			return output, nil
		},
		"GetLocalDNSCPULimitInPercentage": func() string {
			return profile.GetLocalDNSCPULimitInPercentage()
		},
		"GetLocalDNSMemoryLimitInMB": func() string {
			return profile.GetLocalDNSMemoryLimitInMB()
		},
	}
}