aks-node-controller/parser/parser.go (187 lines of code) (raw):
package parser
import (
"bytes"
"context"
_ "embed"
"fmt"
"os"
"os/exec"
"sort"
"strings"
"text/template"
aksnodeconfigv1 "github.com/Azure/agentbaker/aks-node-controller/pkg/gen/aksnodeconfig/v1"
)
var (
//go:embed templates/cse_cmd.sh.gtpl
bootstrapTrigger string
bootstrapTriggerTemplate = template.Must(template.New("triggerBootstrapScript").Funcs(getFuncMap()).Parse(bootstrapTrigger)) //nolint:gochecknoglobals
)
func executeBootstrapTemplate(inputContract *aksnodeconfigv1.Configuration) (string, error) {
var buffer bytes.Buffer
if err := bootstrapTriggerTemplate.Execute(&buffer, inputContract); err != nil {
return "", err
}
return buffer.String(), nil
}
//nolint:funlen
func getCSEEnv(config *aksnodeconfigv1.Configuration) map[string]string {
env := map[string]string{
"PROVISION_OUTPUT": "/var/log/azure/cluster-provision.log",
"MOBY_VERSION": "",
"CLOUDPROVIDER_BACKOFF": "true",
"CLOUDPROVIDER_BACKOFF_MODE": "v2",
"CLOUDPROVIDER_BACKOFF_RETRIES": "6",
"CLOUDPROVIDER_BACKOFF_EXPONENT": "0",
"CLOUDPROVIDER_BACKOFF_DURATION": "5",
"CLOUDPROVIDER_BACKOFF_JITTER": "0",
"CLOUDPROVIDER_RATELIMIT": "true",
"CLOUDPROVIDER_RATELIMIT_QPS": "10",
"CLOUDPROVIDER_RATELIMIT_QPS_WRITE": "10",
"CLOUDPROVIDER_RATELIMIT_BUCKET": "100",
"CLOUDPROVIDER_RATELIMIT_BUCKET_WRITE": "100",
"CONTAINER_RUNTIME": "containerd",
"CLI_TOOL": "ctr",
"NETWORK_MODE": "transparent",
"NEEDS_CONTAINERD": "true",
"NEEDS_DOCKER_LOGIN": "false",
"ADMINUSER": getLinuxAdminUsername(config.GetLinuxAdminUsername()),
"TENANT_ID": config.GetAuthConfig().GetTenantId(),
"KUBERNETES_VERSION": config.GetKubernetesVersion(),
"KUBE_BINARY_URL": config.GetKubeBinaryConfig().GetKubeBinaryUrl(),
"CUSTOM_KUBE_BINARY_URL": config.GetKubeBinaryConfig().GetCustomKubeBinaryUrl(),
"PRIVATE_KUBE_BINARY_URL": config.GetKubeBinaryConfig().GetPrivateKubeBinaryUrl(),
"KUBEPROXY_URL": config.GetKubeProxyUrl(),
"APISERVER_PUBLIC_KEY": config.GetApiServerConfig().GetApiServerPublicKey(),
"SUBSCRIPTION_ID": config.GetAuthConfig().GetSubscriptionId(),
"RESOURCE_GROUP": config.GetClusterConfig().GetResourceGroup(),
"LOCATION": config.GetClusterConfig().GetLocation(),
"VM_TYPE": getStringFromVMType(config.GetClusterConfig().GetVmType()),
"SUBNET": config.GetClusterConfig().GetClusterNetworkConfig().GetSubnet(),
"NETWORK_SECURITY_GROUP": config.GetClusterConfig().GetClusterNetworkConfig().GetSecurityGroupName(),
"VIRTUAL_NETWORK": config.GetClusterConfig().GetClusterNetworkConfig().GetVnetName(),
"VIRTUAL_NETWORK_RESOURCE_GROUP": config.GetClusterConfig().GetClusterNetworkConfig().GetVnetResourceGroup(),
"ROUTE_TABLE": config.GetClusterConfig().GetClusterNetworkConfig().GetRouteTable(),
"PRIMARY_AVAILABILITY_SET": config.GetClusterConfig().GetPrimaryAvailabilitySet(),
"PRIMARY_SCALE_SET": config.GetClusterConfig().GetPrimaryScaleSet(),
"SERVICE_PRINCIPAL_CLIENT_ID": config.GetAuthConfig().GetServicePrincipalId(),
"NETWORK_PLUGIN": getStringFromNetworkPluginType(config.GetNetworkConfig().GetNetworkPlugin()),
"VNET_CNI_PLUGINS_URL": config.GetNetworkConfig().GetVnetCniPluginsUrl(),
"LOAD_BALANCER_DISABLE_OUTBOUND_SNAT": fmt.Sprintf("%v", config.GetClusterConfig().GetLoadBalancerConfig().GetDisableOutboundSnat()),
"USE_MANAGED_IDENTITY_EXTENSION": fmt.Sprintf("%v", config.GetAuthConfig().GetUseManagedIdentityExtension()),
"USE_INSTANCE_METADATA": fmt.Sprintf("%v", config.GetClusterConfig().GetUseInstanceMetadata()),
"LOAD_BALANCER_SKU": getStringFromLoadBalancerSkuType(config.GetClusterConfig().GetLoadBalancerConfig().GetLoadBalancerSku()),
"EXCLUDE_MASTER_FROM_STANDARD_LB": fmt.Sprintf("%v", getExcludeMasterFromStandardLB(config.GetClusterConfig().GetLoadBalancerConfig())),
"MAXIMUM_LOADBALANCER_RULE_COUNT": fmt.Sprintf("%v", getMaxLBRuleCount(config.GetClusterConfig().GetLoadBalancerConfig())),
"CONTAINERD_DOWNLOAD_URL_BASE": config.GetContainerdConfig().GetContainerdDownloadUrlBase(),
"USER_ASSIGNED_IDENTITY_ID": config.GetAuthConfig().GetAssignedIdentityId(),
"API_SERVER_NAME": config.GetApiServerConfig().GetApiServerName(),
"IS_VHD": fmt.Sprintf("%v", getIsVHD(config.IsVhd)),
"GPU_NODE": fmt.Sprintf("%v", getEnableNvidia(config)),
"SGX_NODE": fmt.Sprintf("%v", getIsSgxEnabledSKU(config.GetVmSize())),
"MIG_NODE": fmt.Sprintf("%v", getIsMIGNode(config.GetGpuConfig().GetGpuInstanceProfile())),
"CONFIG_GPU_DRIVER_IF_NEEDED": fmt.Sprintf("%v", config.GetGpuConfig().GetConfigGpuDriver()),
"ENABLE_GPU_DEVICE_PLUGIN_IF_NEEDED": fmt.Sprintf("%v", config.GetGpuConfig().GetGpuDevicePlugin()),
"TELEPORTD_PLUGIN_DOWNLOAD_URL": config.GetTeleportConfig().GetTeleportdPluginDownloadUrl(),
"CREDENTIAL_PROVIDER_DOWNLOAD_URL": config.GetKubeBinaryConfig().GetLinuxCredentialProviderUrl(),
"CONTAINERD_VERSION": config.GetContainerdConfig().GetContainerdVersion(),
"CONTAINERD_PACKAGE_URL": config.GetContainerdConfig().GetContainerdPackageUrl(),
"RUNC_VERSION": config.GetRuncConfig().GetRuncVersion(),
"RUNC_PACKAGE_URL": config.GetRuncConfig().GetRuncPackageUrl(),
"ENABLE_HOSTS_CONFIG_AGENT": fmt.Sprintf("%v", config.GetEnableHostsConfigAgent()),
"DISABLE_SSH": fmt.Sprintf("%v", getDisableSSH(config)),
"TELEPORT_ENABLED": fmt.Sprintf("%v", config.GetTeleportConfig().GetStatus()),
"SHOULD_CONFIGURE_HTTP_PROXY": fmt.Sprintf("%v", getShouldConfigureHTTPProxy(config.GetHttpProxyConfig())),
"SHOULD_CONFIGURE_HTTP_PROXY_CA": fmt.Sprintf("%v", getShouldConfigureHTTPProxyCA(config.GetHttpProxyConfig())),
"HTTP_PROXY_TRUSTED_CA": config.GetHttpProxyConfig().GetProxyTrustedCa(),
"SHOULD_CONFIGURE_CUSTOM_CA_TRUST": fmt.Sprintf("%v", getCustomCACertsStatus(config.GetCustomCaCerts())),
"CUSTOM_CA_TRUST_COUNT": fmt.Sprintf("%v", len(config.GetCustomCaCerts())),
"IS_KRUSTLET": fmt.Sprintf("%v", getIsKrustlet(config.GetWorkloadRuntime())),
"GPU_NEEDS_FABRIC_MANAGER": fmt.Sprintf("%v", getGPUNeedsFabricManager(config.GetVmSize())),
"IPV6_DUAL_STACK_ENABLED": fmt.Sprintf("%v", config.GetIpv6DualStackEnabled()),
"OUTBOUND_COMMAND": config.GetOutboundCommand(),
"ENABLE_UNATTENDED_UPGRADES": fmt.Sprintf("%v", config.GetEnableUnattendedUpgrade()),
"ENSURE_NO_DUPE_PROMISCUOUS_BRIDGE": fmt.Sprintf("%v", getEnsureNoDupePromiscuousBridge(config.GetNetworkConfig())),
"SHOULD_CONFIG_SWAP_FILE": fmt.Sprintf("%v", getEnableSwapConfig(config.GetCustomLinuxOsConfig())),
"SHOULD_CONFIG_TRANSPARENT_HUGE_PAGE": fmt.Sprintf("%v", getShouldConfigTransparentHugePage(config.GetCustomLinuxOsConfig())),
"SHOULD_CONFIG_CONTAINERD_ULIMITS": fmt.Sprintf("%v", getShouldConfigContainerdUlimits(config.GetCustomLinuxOsConfig().GetUlimitConfig())),
"CONTAINERD_ULIMITS": getUlimitContent(config.GetCustomLinuxOsConfig().GetUlimitConfig()),
"TARGET_CLOUD": getTargetCloud(config),
"TARGET_ENVIRONMENT": getTargetEnvironment(config),
"CUSTOM_ENV_JSON": config.GetCustomCloudConfig().GetCustomEnvJsonContent(),
"IS_CUSTOM_CLOUD": fmt.Sprintf("%v", getIsAksCustomCloud(config.GetCustomCloudConfig())),
"AKS_CUSTOM_CLOUD_CONTAINER_REGISTRY_DNS_SUFFIX": config.GetCustomCloudConfig().GetContainerRegistryDnsSuffix(),
"CSE_HELPERS_FILEPATH": getCSEHelpersFilepath(),
"CSE_DISTRO_HELPERS_FILEPATH": getCSEDistroHelpersFilepath(),
"CSE_INSTALL_FILEPATH": getCSEInstallFilepath(),
"CSE_DISTRO_INSTALL_FILEPATH": getCSEDistroInstallFilepath(),
"CSE_CONFIG_FILEPATH": getCSEConfigFilepath(),
"AZURE_PRIVATE_REGISTRY_SERVER": config.GetAzurePrivateRegistryServer(),
"HAS_CUSTOM_SEARCH_DOMAIN": fmt.Sprintf("%v", getHasSearchDomain(config.GetCustomSearchDomainConfig())),
"CUSTOM_SEARCH_DOMAIN_FILEPATH": getCustomSearchDomainFilepath(),
"HTTP_PROXY_URLS": config.GetHttpProxyConfig().GetHttpProxy(),
"HTTPS_PROXY_URLS": config.GetHttpProxyConfig().GetHttpsProxy(),
"NO_PROXY_URLS": getStringifiedStringArray(config.GetHttpProxyConfig().GetNoProxyEntries(), ","),
"PROXY_VARS": getProxyVariables(config.GetHttpProxyConfig()),
"ENABLE_SECURE_TLS_BOOTSTRAPPING": fmt.Sprintf("%v", getEnableSecureTLSBootstrap(config.GetBootstrappingConfig())),
"CUSTOM_SECURE_TLS_BOOTSTRAP_AAD_SERVER_APP_ID": getCustomSecureTLSBootstrapAADServerAppID(config.GetBootstrappingConfig()),
"ENABLE_KUBELET_SERVING_CERTIFICATE_ROTATION": fmt.Sprintf("%v", config.GetKubeletConfig().GetKubeletConfigFileConfig().GetServerTlsBootstrap()),
"DHCPV6_SERVICE_FILEPATH": getDHCPV6ServiceFilepath(),
"DHCPV6_CONFIG_FILEPATH": getDHCPV6ConfigFilepath(),
"THP_ENABLED": config.GetCustomLinuxOsConfig().GetTransparentHugepageSupport(),
"THP_DEFRAG": config.GetCustomLinuxOsConfig().GetTransparentDefrag(),
"SERVICE_PRINCIPAL_FILE_CONTENT": getServicePrincipalFileContent(config.AuthConfig),
"KUBELET_CLIENT_CONTENT": config.GetKubeletConfig().GetKubeletClientKey(),
"KUBELET_CLIENT_CERT_CONTENT": config.GetKubeletConfig().GetKubeletClientCertContent(),
"KUBELET_CONFIG_FILE_ENABLED": fmt.Sprintf("%v", config.GetKubeletConfig().GetEnableKubeletConfigFile()),
"KUBELET_CONFIG_FILE_CONTENT": getKubeletConfigFileContentBase64(config.GetKubeletConfig()),
"SWAP_FILE_SIZE_MB": fmt.Sprintf("%v", config.GetCustomLinuxOsConfig().GetSwapFileSize()),
"GPU_DRIVER_VERSION": getGpuDriverVersion(config.GetVmSize()),
"GPU_IMAGE_SHA": getGpuImageSha(config.GetVmSize()),
"GPU_INSTANCE_PROFILE": config.GetGpuConfig().GetGpuInstanceProfile(),
"GPU_DRIVER_TYPE": getGpuDriverType(config.GetVmSize()),
"CUSTOM_SEARCH_DOMAIN_NAME": config.GetCustomSearchDomainConfig().GetDomainName(),
"CUSTOM_SEARCH_REALM_USER": config.GetCustomSearchDomainConfig().GetRealmUser(),
"CUSTOM_SEARCH_REALM_PASSWORD": config.GetCustomSearchDomainConfig().GetRealmPassword(),
"MESSAGE_OF_THE_DAY": config.GetMessageOfTheDay(),
"HAS_KUBELET_DISK_TYPE": fmt.Sprintf("%v", getHasKubeletDiskType(config.GetKubeletConfig())),
"NEEDS_CGROUPV2": fmt.Sprintf("%v", config.GetNeedsCgroupv2()),
"TLS_BOOTSTRAP_TOKEN": getTLSBootstrapToken(config.GetBootstrappingConfig()),
"KUBELET_FLAGS": getKubeletFlags(config.GetKubeletConfig()),
"NETWORK_POLICY": getStringFromNetworkPolicyType(config.GetNetworkConfig().GetNetworkPolicy()),
"KUBELET_NODE_LABELS": createSortedKeyValuePairs(config.GetKubeletConfig().GetKubeletNodeLabels(), ","),
"AZURE_ENVIRONMENT_FILEPATH": getAzureEnvironmentFilepath(config),
"KUBE_CA_CRT": config.GetKubernetesCaCert(),
"KUBENET_TEMPLATE": getKubenetTemplate(),
"CONTAINERD_CONFIG_CONTENT": getContainerdConfigBase64(config),
"CONTAINERD_CONFIG_NO_GPU_CONTENT": getNoGPUContainerdConfigBase64(config),
"IS_KATA": fmt.Sprintf("%v", config.GetIsKata()),
"ARTIFACT_STREAMING_ENABLED": fmt.Sprintf("%v", config.GetEnableArtifactStreaming()),
"SYSCTL_CONTENT": getSysctlContent(config.GetCustomLinuxOsConfig().GetSysctlConfig()),
"PRIVATE_EGRESS_PROXY_ADDRESS": config.GetPrivateEgressProxyAddress(),
"BOOTSTRAP_PROFILE_CONTAINER_REGISTRY_SERVER": config.GetBootstrapProfileContainerRegistryServer(),
"ENABLE_IMDS_RESTRICTION": fmt.Sprintf("%v", config.GetImdsRestrictionConfig().GetEnableImdsRestriction()),
"INSERT_IMDS_RESTRICTION_RULE_TO_MANGLE_TABLE": fmt.Sprintf("%v", config.GetImdsRestrictionConfig().GetInsertImdsRestrictionRuleToMangleTable()),
}
for i, cert := range config.CustomCaCerts {
env[fmt.Sprintf("CUSTOM_CA_CERT_%d", i)] = cert
}
return env
}
func mapToEnviron(input map[string]string) []string {
var env []string
for k, v := range input {
env = append(env, fmt.Sprintf("%s=%s", k, v))
}
sort.Strings(env) // produce deterministic output
return env
}
func BuildCSECmd(ctx context.Context, config *aksnodeconfigv1.Configuration) (*exec.Cmd, error) {
triggerBootstrapScript, err := executeBootstrapTemplate(config)
if err != nil {
return nil, fmt.Errorf("failed to execute the template: %w", err)
}
// Convert to one-liner
triggerBootstrapScript = strings.ReplaceAll(triggerBootstrapScript, "\n", " ")
cmd := exec.CommandContext(ctx, "/bin/bash", "-c", triggerBootstrapScript)
env := mapToEnviron(getCSEEnv(config))
cmd.Env = append(os.Environ(), env...) // append existing environment variables
sort.Strings(cmd.Env)
return cmd, nil
}