pkg/api/vlabs/types.go (801 lines of code) (raw):

// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. package vlabs import ( "encoding/json" "strings" "github.com/Azure/aks-engine-azurestack/pkg/api/common" "github.com/Azure/aks-engine-azurestack/pkg/helpers/to" "github.com/pkg/errors" ) // ResourcePurchasePlan defines resource plan as required by ARM // for billing purposes. type ResourcePurchasePlan struct { Name string `json:"name,omitempty"` Product string `json:"product,omitempty"` PromotionCode string `json:"promotionCode,omitempty"` Publisher string `json:"publisher,omitempty"` } // ContainerService complies with the ARM model of // resource definition in a JSON template. type ContainerService struct { ID string `json:"id,omitempty"` Location string `json:"location,omitempty"` Name string `json:"name,omitempty"` Plan *ResourcePurchasePlan `json:"plan,omitempty"` Tags map[string]string `json:"tags,omitempty"` Type string `json:"type,omitempty"` Properties *Properties `json:"properties" validate:"required"` } // Properties represents the AKS cluster definition type Properties struct { ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` OrchestratorProfile *OrchestratorProfile `json:"orchestratorProfile,omitempty"` MasterProfile *MasterProfile `json:"masterProfile,omitempty" validate:"required"` AgentPoolProfiles []*AgentPoolProfile `json:"agentPoolProfiles,omitempty" validate:"dive,required"` LinuxProfile *LinuxProfile `json:"linuxProfile,omitempty" validate:"required"` ExtensionProfiles []*ExtensionProfile `json:"extensionProfiles,omitempty"` WindowsProfile *WindowsProfile `json:"windowsProfile,omitempty"` ServicePrincipalProfile *ServicePrincipalProfile `json:"servicePrincipalProfile,omitempty"` CertificateProfile *CertificateProfile `json:"certificateProfile,omitempty"` AADProfile *AADProfile `json:"aadProfile,omitempty"` FeatureFlags *FeatureFlags `json:"featureFlags,omitempty"` CustomCloudProfile *CustomCloudProfile `json:"customCloudProfile,omitempty"` TelemetryProfile *TelemetryProfile `json:"telemetryProfile,omitempty"` } // FeatureFlags defines feature-flag restricted functionality type FeatureFlags struct { EnableCSERunInBackground bool `json:"enableCSERunInBackground,omitempty"` BlockOutboundInternet bool `json:"blockOutboundInternet,omitempty"` EnableIPv6DualStack bool `json:"enableIPv6DualStack,omitempty"` EnableTelemetry bool `json:"enableTelemetry,omitempty"` EnableIPv6Only bool `json:"enableIPv6Only,omitempty"` EnableWinDSR bool `json:"enableWinDSR,omitempty"` EnforceUbuntu2004DisaStig bool `json:"enforceUbuntu2004DisaStig,omitempty"` EnforceUbuntu2204DisaStig bool `json:"enforceUbuntu2204DisaStig,omitempty"` EnforceKubernetesDisaStig bool `json:"enforceKubernetesDisaStig,omitempty"` } // ServicePrincipalProfile contains the client and secret used by the cluster for Azure Resource CRUD // The 'Secret' and 'KeyvaultSecretRef' parameters are mutually exclusive // The 'Secret' parameter should be a secret in plain text. // The 'KeyvaultSecretRef' parameter is a reference to a secret in a keyvault. type ServicePrincipalProfile struct { ClientID string `json:"clientId,omitempty"` Secret string `json:"secret,omitempty"` ObjectID string `json:"objectId,omitempty"` KeyvaultSecretRef *KeyvaultSecretRef `json:"keyvaultSecretRef,omitempty"` } // KeyvaultSecretRef is a reference to a secret in a keyvault. // The format of 'VaultID' value should be // "/subscriptions/<SUB_ID>/resourceGroups/<RG_NAME>/providers/Microsoft.KeyVault/vaults/<KV_NAME>" // 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 // The 'SecretName' is the name of the secret in the keyvault // The 'SecretVersion' (optional) is the version of the secret (default: the latest version) type KeyvaultSecretRef struct { VaultID string `json:"vaultID" validate:"required"` SecretName string `json:"secretName" validate:"required"` SecretVersion string `json:"version,omitempty"` } // CertificateProfile represents the definition of the master cluster // The JSON parameters could be either a plain text, or referenced to a secret in a keyvault. // In the latter case, the format of the parameter's value should be // "/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) type CertificateProfile struct { // CaCertificate is the certificate authority certificate. CaCertificate string `json:"caCertificate,omitempty"` // CaPrivateKey is the certificate authority key. CaPrivateKey string `json:"caPrivateKey,omitempty"` // ApiServerCertificate is the rest api server certificate, and signed by the CA APIServerCertificate string `json:"apiServerCertificate,omitempty"` // ApiServerPrivateKey is the rest api server private key, and signed by the CA APIServerPrivateKey string `json:"apiServerPrivateKey,omitempty"` // ClientCertificate is the certificate used by the client kubelet services and signed by the CA ClientCertificate string `json:"clientCertificate,omitempty"` // ClientPrivateKey is the private key used by the client kubelet services and signed by the CA ClientPrivateKey string `json:"clientPrivateKey,omitempty"` // KubeConfigCertificate is the client certificate used for kubectl cli and signed by the CA KubeConfigCertificate string `json:"kubeConfigCertificate,omitempty"` // KubeConfigPrivateKey is the client private key used for kubectl cli and signed by the CA KubeConfigPrivateKey string `json:"kubeConfigPrivateKey,omitempty"` // EtcdServerCertificate is the server certificate for etcd, and signed by the CA EtcdServerCertificate string `json:"etcdServerCertificate,omitempty"` // EtcdServerPrivateKey is the server private key for etcd, and signed by the CA EtcdServerPrivateKey string `json:"etcdServerPrivateKey,omitempty"` // EtcdClientCertificate is etcd client certificate, and signed by the CA EtcdClientCertificate string `json:"etcdClientCertificate,omitempty"` // EtcdClientPrivateKey is the etcd client private key, and signed by the CA EtcdClientPrivateKey string `json:"etcdClientPrivateKey,omitempty"` // EtcdPeerCertificates is list of etcd peer certificates, and signed by the CA EtcdPeerCertificates []string `json:"etcdPeerCertificates,omitempty"` // EtcdPeerPrivateKeys is list of etcd peer private keys, and signed by the CA EtcdPeerPrivateKeys []string `json:"etcdPeerPrivateKeys,omitempty"` } // LinuxProfile represents the linux parameters passed to the cluster type LinuxProfile struct { AdminUsername string `json:"adminUsername" validate:"required"` SSH struct { PublicKeys []PublicKey `json:"publicKeys" validate:"required,min=1"` } `json:"ssh" validate:"required"` Secrets []KeyVaultSecrets `json:"secrets,omitempty"` ScriptRootURL string `json:"scriptroot,omitempty"` CustomSearchDomain *CustomSearchDomain `json:"customSearchDomain,omitempty"` CustomNodesDNS *CustomNodesDNS `json:"customNodesDNS,omitempty"` RunUnattendedUpgradesOnBootstrap *bool `json:"runUnattendedUpgradesOnBootstrap,omitempty"` EnableUnattendedUpgrades *bool `json:"enableUnattendedUpgrades,omitempty"` Eth0MTU int `json:"eth0MTU,omitempty"` } // PublicKey represents an SSH key for LinuxProfile type PublicKey struct { KeyData string `json:"keyData"` } // CustomSearchDomain represents the Search Domain when the custom vnet has a windows server DNS as a nameserver. type CustomSearchDomain struct { Name string `json:"name,omitempty"` RealmUser string `json:"realmUser,omitempty"` RealmPassword string `json:"realmPassword,omitempty"` } // CustomNodesDNS represents the Search Domain type CustomNodesDNS struct { DNSServer string `json:"dnsServer,omitempty"` } // WindowsLicenseType represents Windows license type type WindowsLicenseType string const ( // WindowsLicenseTypeServer specifies that the image or disk that is being used was licensed server on-premises. WindowsLicenseTypeServer WindowsLicenseType = "Windows_Server" ) // WindowsProfile represents the windows parameters passed to the cluster type WindowsProfile struct { AdminUsername string `json:"adminUsername,omitempty"` AdminPassword string `json:"adminPassword,omitempty"` CSIProxyURL string `json:"csiProxyURL,omitempty"` EnableCSIProxy *bool `json:"enableCSIProxy,omitempty"` ImageRef *ImageReference `json:"imageReference,omitempty"` ImageVersion string `json:"imageVersion,omitempty"` ProvisioningScriptsPackageURL string `json:"provisioningScriptsPackageURL,omitempty"` WindowsImageSourceURL string `json:"WindowsImageSourceUrl"` WindowsPublisher string `json:"WindowsPublisher"` WindowsOffer string `json:"WindowsOffer"` WindowsSku string `json:"WindowsSku"` WindowsDockerVersion string `json:"windowsDockerVersion"` Secrets []KeyVaultSecrets `json:"secrets,omitempty"` SSHEnabled *bool `json:"sshEnabled,omitempty"` EnableAutomaticUpdates *bool `json:"enableAutomaticUpdates,omitempty"` IsCredentialAutoGenerated *bool `json:"isCredentialAutoGenerated,omitempty"` EnableAHUB *bool `json:"enableAHUB,omitempty"` WindowsPauseImageURL string `json:"windowsPauseImageURL"` AlwaysPullWindowsPauseImage *bool `json:"alwaysPullWindowsPauseImage,omitempty"` WindowsRuntimes *WindowsRuntimes `json:"windowsRuntimes,omitempty"` WindowsSecureTLSEnabled *bool `json:"windowsSecureTLSEnabled,omitempty"` } // WindowsRuntimes configures containerd runtimes that are available on the windows nodes type WindowsRuntimes struct { Default string `json:"default,omitempty"` HypervRuntimes []RuntimeHandlers `json:"hypervRuntimes,omitempty"` } // RuntimeHandlers configures the runtime settings in containerd type RuntimeHandlers struct { BuildNumber string `json:"buildNumber,omitempty"` } // ProvisioningState represents the current state of container service resource. type ProvisioningState string const ( // Creating means ContainerService resource is being created. Creating ProvisioningState = "Creating" // Updating means an existing ContainerService resource is being updated Updating ProvisioningState = "Updating" // Failed means resource is in failed state Failed ProvisioningState = "Failed" // Succeeded means resource created succeeded during last create/update Succeeded ProvisioningState = "Succeeded" // Deleting means resource is in the process of being deleted Deleting ProvisioningState = "Deleting" // Migrating means resource is being migrated from one subscription or // resource group to another Migrating ProvisioningState = "Migrating" ) // OrchestratorProfile contains Orchestrator properties type OrchestratorProfile struct { // OrchestratorType is a legacy property, this should always be set to "Kubernetes" OrchestratorType string `json:"orchestratorType"` OrchestratorRelease string `json:"orchestratorRelease,omitempty"` OrchestratorVersion string `json:"orchestratorVersion,omitempty"` KubernetesConfig *KubernetesConfig `json:"kubernetesConfig,omitempty"` } // UnmarshalJSON unmarshal json using the default behavior // And do fields manipulation, such as populating default value func (o *OrchestratorProfile) UnmarshalJSON(b []byte) error { // Need to have a alias type to avoid circular unmarshal type aliasOrchestratorProfile OrchestratorProfile op := aliasOrchestratorProfile{} if e := json.Unmarshal(b, &op); e != nil { return e } *o = OrchestratorProfile(op) // Unmarshal OrchestratorType, format it as well orchestratorType := o.OrchestratorType switch { case strings.EqualFold(orchestratorType, Kubernetes), orchestratorType == "": o.OrchestratorType = Kubernetes default: return errors.Errorf("OrchestratorType has unknown orchestrator: %s", orchestratorType) } return nil } // KubernetesContainerSpec defines configuration for a container spec type KubernetesContainerSpec struct { Name string `json:"name,omitempty"` Image string `json:"image,omitempty"` CPURequests string `json:"cpuRequests,omitempty"` MemoryRequests string `json:"memoryRequests,omitempty"` CPULimits string `json:"cpuLimits,omitempty"` MemoryLimits string `json:"memoryLimits,omitempty"` } // AddonNodePoolsConfig defines configuration for pool-specific cluster-autoscaler configuration type AddonNodePoolsConfig struct { Name string `json:"name,omitempty"` Config map[string]string `json:"config,omitempty"` } // KubernetesAddon defines a list of addons w/ configuration to include with the cluster deployment type KubernetesAddon struct { Name string `json:"name,omitempty"` Enabled *bool `json:"enabled,omitempty"` Mode string `json:"mode,omitempty"` Containers []KubernetesContainerSpec `json:"containers,omitempty"` Config map[string]string `json:"config,omitempty"` Pools []AddonNodePoolsConfig `json:"pools,omitempty"` Data string `json:"data,omitempty"` } // IsEnabled returns true if the addon is enabled func (a *KubernetesAddon) IsEnabled() bool { if a.Enabled == nil { return false } return *a.Enabled } // KubernetesComponent defines a component w/ configuration to include with the cluster deployment type KubernetesComponent struct { Name string `json:"name,omitempty"` Enabled *bool `json:"enabled,omitempty"` Containers []KubernetesContainerSpec `json:"containers,omitempty"` Config map[string]string `json:"config,omitempty"` Data string `json:"data,omitempty"` } // PrivateCluster defines the configuration for a private cluster type PrivateCluster struct { Enabled *bool `json:"enabled,omitempty"` EnableHostsConfigAgent *bool `json:"enableHostsConfigAgent,omitempty"` JumpboxProfile *PrivateJumpboxProfile `json:"jumpboxProfile,omitempty"` } // PrivateJumpboxProfile represents a jumpbox definition type PrivateJumpboxProfile struct { Name string `json:"name" validate:"required"` VMSize string `json:"vmSize" validate:"required"` OSDiskSizeGB int `json:"osDiskSizeGB,omitempty" validate:"min=0,max=2048"` Username string `json:"username,omitempty"` PublicKey string `json:"publicKey" validate:"required"` StorageProfile string `json:"storageProfile,omitempty"` } // KubeProxyMode is for iptables and ipvs (and future others) type KubeProxyMode string // We currently support ipvs and iptables const ( KubeProxyModeIPTables KubeProxyMode = "iptables" KubeProxyModeIPVS KubeProxyMode = "ipvs" ) // KubernetesConfig contains the Kubernetes config structure, containing // Kubernetes specific configuration type KubernetesConfig struct { KubernetesImageBase string `json:"kubernetesImageBase,omitempty"` KubernetesImageBaseType string `json:"kubernetesImageBaseType,omitempty"` MCRKubernetesImageBase string `json:"mcrKubernetesImageBase,omitempty"` ClusterSubnet string `json:"clusterSubnet,omitempty"` DNSServiceIP string `json:"dnsServiceIP,omitempty"` ServiceCidr string `json:"serviceCidr,omitempty"` NetworkPolicy string `json:"networkPolicy,omitempty"` NetworkPlugin string `json:"networkPlugin,omitempty"` NetworkMode string `json:"networkMode,omitempty"` ContainerRuntime string `json:"containerRuntime,omitempty"` MaxPods int `json:"maxPods,omitempty"` DockerBridgeSubnet string `json:"dockerBridgeSubnet,omitempty"` UseManagedIdentity *bool `json:"useManagedIdentity,omitempty"` UserAssignedID string `json:"userAssignedID,omitempty"` UserAssignedClientID string `json:"userAssignedClientID,omitempty"` //Note: cannot be provided in config. Used *only* for transferring this to azure.json. CustomHyperkubeImage string `json:"customHyperkubeImage,omitempty"` CustomKubeAPIServerImage string `json:"customKubeAPIServerImage,omitempty"` CustomKubeControllerManagerImage string `json:"customKubeControllerManagerImage,omitempty"` CustomKubeProxyImage string `json:"customKubeProxyImage,omitempty"` CustomKubeSchedulerImage string `json:"customKubeSchedulerImage,omitempty"` CustomKubeBinaryURL string `json:"customKubeBinaryURL,omitempty"` DockerEngineVersion string `json:"dockerEngineVersion,omitempty"` // Deprecated MobyVersion string `json:"mobyVersion,omitempty"` LinuxMobyURL string `json:"linuxMobyURL,omitempty"` LinuxRuncURL string `json:"linuxRuncURL,omitempty"` ContainerdVersion string `json:"containerdVersion,omitempty"` LinuxContainerdURL string `json:"linuxContainerdURL,omitempty"` CustomCcmImage string `json:"customCcmImage,omitempty"` UseCloudControllerManager *bool `json:"useCloudControllerManager,omitempty"` CustomWindowsPackageURL string `json:"customWindowsPackageURL,omitempty"` WindowsNodeBinariesURL string `json:"windowsNodeBinariesURL,omitempty"` WindowsContainerdURL string `json:"windowsContainerdURL,omitempty"` WindowsSdnPluginURL string `json:"windowsSdnPluginURL,omitempty"` UseInstanceMetadata *bool `json:"useInstanceMetadata,omitempty"` EnableRbac *bool `json:"enableRbac,omitempty"` EnableSecureKubelet *bool `json:"enableSecureKubelet,omitempty"` EnableAggregatedAPIs bool `json:"enableAggregatedAPIs,omitempty"` PrivateCluster *PrivateCluster `json:"privateCluster,omitempty"` GCHighThreshold int `json:"gchighthreshold,omitempty"` GCLowThreshold int `json:"gclowthreshold,omitempty"` EtcdVersion string `json:"etcdVersion,omitempty"` EtcdDiskSizeGB string `json:"etcdDiskSizeGB,omitempty"` EtcdStorageLimitGB int `json:"etcdStorageLimitGB,omitempty"` EtcdEncryptionKey string `json:"etcdEncryptionKey,omitempty"` EnableDataEncryptionAtRest *bool `json:"enableDataEncryptionAtRest,omitempty"` EnableEncryptionWithExternalKms *bool `json:"enableEncryptionWithExternalKms,omitempty"` EnablePodSecurityPolicy *bool `json:"enablePodSecurityPolicy,omitempty"` Addons []KubernetesAddon `json:"addons,omitempty"` Components []KubernetesComponent `json:"components,omitempty"` ContainerRuntimeConfig map[string]string `json:"containerRuntimeConfig,omitempty"` KubeletConfig map[string]string `json:"kubeletConfig,omitempty"` ControllerManagerConfig map[string]string `json:"controllerManagerConfig,omitempty"` CloudControllerManagerConfig map[string]string `json:"cloudControllerManagerConfig,omitempty"` APIServerConfig map[string]string `json:"apiServerConfig,omitempty"` SchedulerConfig map[string]string `json:"schedulerConfig,omitempty"` PodSecurityPolicyConfig map[string]string `json:"podSecurityPolicyConfig,omitempty"` // Deprecated KubeReservedCgroup string `json:"kubeReservedCgroup,omitempty"` CloudProviderBackoffMode string `json:"cloudProviderBackoffMode"` CloudProviderBackoff *bool `json:"cloudProviderBackoff,omitempty"` CloudProviderBackoffRetries int `json:"cloudProviderBackoffRetries,omitempty"` CloudProviderBackoffJitter float64 `json:"cloudProviderBackoffJitter,omitempty"` CloudProviderBackoffDuration int `json:"cloudProviderBackoffDuration,omitempty"` CloudProviderBackoffExponent float64 `json:"cloudProviderBackoffExponent,omitempty"` CloudProviderRateLimit *bool `json:"cloudProviderRateLimit,omitempty"` CloudProviderRateLimitQPS float64 `json:"cloudProviderRateLimitQPS,omitempty"` CloudProviderRateLimitQPSWrite float64 `json:"cloudProviderRateLimitQPSWrite,omitempty"` CloudProviderRateLimitBucket int `json:"cloudProviderRateLimitBucket,omitempty"` CloudProviderRateLimitBucketWrite int `json:"cloudProviderRateLimitBucketWrite,omitempty"` CloudProviderDisableOutboundSNAT *bool `json:"cloudProviderDisableOutboundSNAT,omitempty"` LoadBalancerSku string `json:"loadBalancerSku,omitempty"` ExcludeMasterFromStandardLB *bool `json:"excludeMasterFromStandardLB,omitempty"` LoadBalancerOutboundIPs *int `json:"loadBalancerOutboundIPs,omitempty"` AzureCNIVersion string `json:"azureCNIVersion,omitempty"` AzureCNIURLLinux string `json:"azureCNIURLLinux,omitempty"` AzureCNIURLWindows string `json:"azureCNIURLWindows,omitempty"` KeyVaultSku string `json:"keyVaultSku,omitempty"` MaximumLoadBalancerRuleCount int `json:"maximumLoadBalancerRuleCount,omitempty"` ProxyMode KubeProxyMode `json:"kubeProxyMode,omitempty"` PrivateAzureRegistryServer string `json:"privateAzureRegistryServer,omitempty"` OutboundRuleIdleTimeoutInMinutes int32 `json:"outboundRuleIdleTimeoutInMinutes,omitempty"` MicrosoftAptRepositoryURL string `json:"microsoftAptRepositoryURL,omitempty"` EnableMultipleStandardLoadBalancers *bool `json:"enableMultipleStandardLoadBalancers,omitempty"` Tags string `json:"tags,omitempty"` } // CustomFile has source as the full absolute source path to a file and dest // is the full absolute desired destination path to put the file on a master node type CustomFile struct { Source string `json:"source,omitempty"` Dest string `json:"dest,omitempty"` } // MasterProfile represents the definition of the master cluster type MasterProfile struct { Count int `json:"count" validate:"required,eq=1|eq=3|eq=5"` DNSPrefix string `json:"dnsPrefix" validate:"required"` SubjectAltNames []string `json:"subjectAltNames"` VMSize string `json:"vmSize" validate:"required"` OSDiskSizeGB int `json:"osDiskSizeGB,omitempty" validate:"min=0,max=2048"` VnetSubnetID string `json:"vnetSubnetID,omitempty"` VnetCidr string `json:"vnetCidr,omitempty"` AgentVnetSubnetID string `json:"agentVnetSubnetID,omitempty"` FirstConsecutiveStaticIP string `json:"firstConsecutiveStaticIP,omitempty"` IPAddressCount int `json:"ipAddressCount,omitempty" validate:"min=0,max=256"` StorageProfile string `json:"storageProfile,omitempty" validate:"eq=StorageAccount|eq=ManagedDisks|len=0"` HTTPSourceAddressPrefix string `json:"HTTPSourceAddressPrefix,omitempty"` OAuthEnabled bool `json:"oauthEnabled"` PreProvisionExtension *Extension `json:"preProvisionExtension"` Extensions []Extension `json:"extensions"` Distro Distro `json:"distro,omitempty"` KubernetesConfig *KubernetesConfig `json:"kubernetesConfig,omitempty"` ImageRef *ImageReference `json:"imageReference,omitempty"` CustomFiles *[]CustomFile `json:"customFiles,omitempty"` AvailabilityProfile string `json:"availabilityProfile"` AgentSubnet string `json:"agentSubnet,omitempty"` AvailabilityZones []string `json:"availabilityZones,omitempty"` SinglePlacementGroup *bool `json:"singlePlacementGroup,omitempty"` PlatformFaultDomainCount *int `json:"platformFaultDomainCount,omitempty"` PlatformUpdateDomainCount *int `json:"platformUpdateDomainCount"` AuditDEnabled *bool `json:"auditDEnabled,omitempty"` CustomVMTags map[string]string `json:"customVMTags,omitempty"` SysctlDConfig map[string]string `json:"sysctldConfig,omitempty"` UltraSSDEnabled *bool `json:"ultraSSDEnabled,omitempty"` EncryptionAtHost *bool `json:"encryptionAtHost,omitempty"` // subnet is internal subnet string // subnetIPv6 is internal subnetIPv6 string // Master LB public endpoint/FQDN with port // The format will be FQDN:2376 // Not used during PUT, returned as part of GET FQDN string `json:"fqdn,omitempty"` // True: uses cosmos etcd endpoint instead of installing etcd on masters CosmosEtcd *bool `json:"cosmosEtcd,omitempty"` ProximityPlacementGroupID string `json:"proximityPlacementGroupID,omitempty"` OSDiskCachingType string `json:"osDiskCachingType,omitempty"` } // ImageReference represents a reference to an Image resource in Azure. type ImageReference struct { Name string `json:"name,omitempty"` ResourceGroup string `json:"resourceGroup,omitempty"` SubscriptionID string `json:"subscriptionId,omitempty"` Gallery string `json:"gallery,omitempty"` Version string `json:"version,omitempty"` } // ExtensionProfile represents an extension definition type ExtensionProfile struct { Name string `json:"name"` Version string `json:"version"` ExtensionParameters string `json:"extensionParameters,omitempty"` ExtensionParametersKeyVaultRef *KeyvaultSecretRef `json:"parametersKeyvaultSecretRef,omitempty"` RootURL string `json:"rootURL,omitempty"` // This is only needed for preprovision extensions and it needs to be a bash script Script string `json:"script,omitempty"` URLQuery string `json:"urlQuery,omitempty"` } // Extension represents an extension definition in the master or agentPoolProfile type Extension struct { Name string `json:"name"` SingleOrAll string `json:"singleOrAll"` Template string `json:"template"` } // AgentPoolProfile represents an agent pool definition type AgentPoolProfile struct { Name string `json:"name" validate:"required"` Count int `json:"count" validate:"required,min=1,max=1000"` VMSize string `json:"vmSize" validate:"required"` OSDiskSizeGB int `json:"osDiskSizeGB,omitempty" validate:"min=0,max=2048"` DNSPrefix string `json:"dnsPrefix,omitempty"` OSType OSType `json:"osType,omitempty"` Ports []int `json:"ports,omitempty" validate:"dive,min=1,max=65535"` AvailabilityProfile string `json:"availabilityProfile"` ScaleSetPriority string `json:"scaleSetPriority,omitempty" validate:"eq=Regular|eq=Low|eq=Spot|len=0"` ScaleSetEvictionPolicy string `json:"scaleSetEvictionPolicy,omitempty" validate:"eq=Delete|eq=Deallocate|len=0"` SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` StorageProfile string `json:"storageProfile" validate:"eq=StorageAccount|eq=ManagedDisks|eq=Ephemeral|len=0"` DiskSizesGB []int `json:"diskSizesGB,omitempty" validate:"max=4,dive,min=1,max=32767"` VnetSubnetID string `json:"vnetSubnetID,omitempty"` IPAddressCount int `json:"ipAddressCount,omitempty" validate:"min=0,max=256"` Distro Distro `json:"distro,omitempty"` KubernetesConfig *KubernetesConfig `json:"kubernetesConfig,omitempty"` ImageRef *ImageReference `json:"imageReference,omitempty"` Role AgentPoolProfileRole `json:"role,omitempty"` AcceleratedNetworkingEnabled *bool `json:"acceleratedNetworkingEnabled,omitempty"` AcceleratedNetworkingEnabledWindows *bool `json:"acceleratedNetworkingEnabledWindows,omitempty"` VMSSOverProvisioningEnabled *bool `json:"vmssOverProvisioningEnabled,omitempty"` AuditDEnabled *bool `json:"auditDEnabled,omitempty"` CustomVMTags map[string]string `json:"customVMTags,omitempty"` DiskEncryptionSetID string `json:"diskEncryptionSetID,omitempty"` UltraSSDEnabled *bool `json:"ultraSSDEnabled,omitempty"` EncryptionAtHost *bool `json:"encryptionAtHost,omitempty"` // subnet is internal subnet string FQDN string `json:"fqdn"` CustomNodeLabels map[string]string `json:"customNodeLabels,omitempty"` PreProvisionExtension *Extension `json:"preProvisionExtension"` Extensions []Extension `json:"extensions"` SinglePlacementGroup *bool `json:"singlePlacementGroup,omitempty"` PlatformFaultDomainCount *int `json:"platformFaultDomainCount,omitempty"` PlatformUpdateDomainCount *int `json:"platformUpdateDomainCount"` AvailabilityZones []string `json:"availabilityZones,omitempty"` EnableVMSSNodePublicIP *bool `json:"enableVMSSNodePublicIP,omitempty"` LoadBalancerBackendAddressPoolIDs []string `json:"loadBalancerBackendAddressPoolIDs,omitempty"` SysctlDConfig map[string]string `json:"sysctldConfig,omitempty"` ProximityPlacementGroupID string `json:"proximityPlacementGroupID,omitempty"` OSDiskCachingType string `json:"osDiskCachingType,omitempty"` DataDiskCachingType string `json:"dataDiskCachingType,omitempty"` // VMSSName is a read-only field; its value will be computed during template generation VMSSName string `json:"vmssName,omitempty"` } // AgentPoolProfileRole represents an agent role type AgentPoolProfileRole string // AADProfile specifies attributes for AAD integration type AADProfile struct { // The client AAD application ID. ClientAppID string `json:"clientAppID,omitempty"` // The server AAD application ID. ServerAppID string `json:"serverAppID,omitempty"` // The AAD tenant ID to use for authentication. // If not specified, will use the tenant of the deployment subscription. // Optional TenantID string `json:"tenantID,omitempty"` // The Azure Active Directory Group Object ID that will be assigned the // cluster-admin RBAC role. // Optional AdminGroupID string `json:"adminGroupID,omitempty"` } // KeyVaultSecrets specifies certificates to install on the pool // of machines from a given key vault // the key vault specified must have been granted read permissions to CRP type KeyVaultSecrets struct { SourceVault *KeyVaultID `json:"sourceVault,omitempty"` VaultCertificates []KeyVaultCertificate `json:"vaultCertificates,omitempty"` } // KeyVaultID specifies a key vault type KeyVaultID struct { ID string `json:"id,omitempty"` } // KeyVaultCertificate specifies a certificate to install // On Linux, the certificate file is placed under the /var/lib/waagent directory // with the file name <UppercaseThumbprint>.crt for the X509 certificate file // and <UppercaseThumbprint>.prv for the private key. Both of these files are .pem formatted. // On windows the certificate will be saved in the specified store. type KeyVaultCertificate struct { CertificateURL string `json:"certificateUrl,omitempty"` CertificateStore string `json:"certificateStore,omitempty"` } // OSType represents OS types of agents type OSType string // Distro represents Linux distro to use for Linux VMs type Distro string // DependenciesLocation represents location to retrieve the dependencies. type DependenciesLocation string // ResourceIdentifier contains a set of Azure resource IDs. type ResourceIdentifier struct { Graph string `json:"graph"` KeyVault string `json:"keyVault"` Datalake string `json:"datalake"` Batch string `json:"batch"` OperationalInsights string `json:"operationalInsights"` Storage string `json:"storage"` Synapse string `json:"synapse"` ServiceBus string `json:"serviceBus"` } // Environment represents a set of endpoints for each of Azure's Clouds. type Environment struct { Name string `json:"name"` ManagementPortalURL string `json:"managementPortalURL"` PublishSettingsURL string `json:"publishSettingsURL"` ServiceManagementEndpoint string `json:"serviceManagementEndpoint"` ResourceManagerEndpoint string `json:"resourceManagerEndpoint"` ActiveDirectoryEndpoint string `json:"activeDirectoryEndpoint"` GalleryEndpoint string `json:"galleryEndpoint"` KeyVaultEndpoint string `json:"keyVaultEndpoint"` GraphEndpoint string `json:"graphEndpoint"` ServiceBusEndpoint string `json:"serviceBusEndpoint"` BatchManagementEndpoint string `json:"batchManagementEndpoint"` StorageEndpointSuffix string `json:"storageEndpointSuffix"` SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"` TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"` KeyVaultDNSSuffix string `json:"keyVaultDNSSuffix"` ServiceBusEndpointSuffix string `json:"serviceBusEndpointSuffix"` ServiceManagementVMDNSSuffix string `json:"serviceManagementVMDNSSuffix"` ResourceManagerVMDNSSuffix string `json:"resourceManagerVMDNSSuffix"` ContainerRegistryDNSSuffix string `json:"containerRegistryDNSSuffix"` CosmosDBDNSSuffix string `json:"cosmosDBDNSSuffix"` TokenAudience string `json:"tokenAudience"` APIManagementHostNameSuffix string `json:"apiManagementHostNameSuffix"` SynapseEndpointSuffix string `json:"synapseEndpointSuffix"` ResourceIdentifiers ResourceIdentifier `json:"resourceIdentifiers"` } // CustomCloudProfile represents the custom cloud profile type CustomCloudProfile struct { Environment *Environment `json:"environment,omitempty"` AzureEnvironmentSpecConfig *AzureEnvironmentSpecConfig `json:"azureEnvironmentSpecConfig,omitempty"` IdentitySystem string `json:"identitySystem,omitempty"` AuthenticationMethod string `json:"authenticationMethod,omitempty"` DependenciesLocation DependenciesLocation `json:"dependenciesLocation,omitempty"` PortalURL string `json:"portalURL,omitempty"` CustomCloudRootCertificates string `json:"customCloudRootCertificates,omitempty"` CustomCloudSourcesList string `json:"customCloudSourcesList,omitempty"` } // TelemetryProfile contains settings for collecting telemtry. // Note telemtry is currently enabled/disabled with the 'EnableTelemetry' feature flag. type TelemetryProfile struct { ApplicationInsightsKey string `json:"applicationInsightsKey,omitempty"` } // HasFlatcar returns true if the cluster contains Flatcar nodes func (p *Properties) HasFlatcar() bool { for _, agentPoolProfile := range p.AgentPoolProfiles { if agentPoolProfile.Distro == Flatcar { return true } } return false } // HasWindows returns true if the cluster contains windows func (p *Properties) HasWindows() bool { for _, agentPoolProfile := range p.AgentPoolProfiles { if agentPoolProfile.OSType == Windows { return true } } return false } // HasAvailabilityZones returns true if the cluster contains any profile with zones func (p *Properties) HasAvailabilityZones() bool { hasZones := p.MasterProfile != nil && p.MasterProfile.HasAvailabilityZones() if !hasZones && p.AgentPoolProfiles != nil { for _, agentPoolProfile := range p.AgentPoolProfiles { if agentPoolProfile.HasAvailabilityZones() { hasZones = true break } } } return hasZones } // IsCustomCloudProfile return true if user has provided a custom cloud profile func (p *Properties) IsCustomCloudProfile() bool { return p.CustomCloudProfile != nil } // GetCustomCloudRootCertificates returns comma-separated list of base64-encoded custom root certificates func (p *Properties) GetCustomCloudRootCertificates() string { if p.IsCustomCloudProfile() { return p.CustomCloudProfile.CustomCloudRootCertificates } return "" } // GetCustomCloudSourcesList returns a base64-encoded custom sources.list file func (p *Properties) GetCustomCloudSourcesList() string { if p.IsCustomCloudProfile() { return p.CustomCloudProfile.CustomCloudSourcesList } return "" } // IsAzureStackCloud return true if the cloud is AzureStack func (p *Properties) IsAzureStackCloud() bool { // For backward compatibility, treat nil Environment and empty Environment name as AzureStackCloud as well return p.IsCustomCloudProfile() && (p.CustomCloudProfile.Environment == nil || p.CustomCloudProfile.Environment.Name == "" || strings.EqualFold(p.CustomCloudProfile.Environment.Name, "AzureStackCloud")) } // HasAADAdminGroupID returns true if the cluster has an AADProfile w/ a valid AdminGroupID func (p *Properties) HasAADAdminGroupID() bool { return p.AADProfile != nil && p.AADProfile.AdminGroupID != "" } // GetAADAdminGroupID returns AADProfile.AdminGroupID, or "" if no AADProfile func (p *Properties) GetAADAdminGroupID() string { if p.AADProfile != nil { return p.AADProfile.AdminGroupID } return "" } // IsCustomVNET returns true if the customer brought their own VNET func (m *MasterProfile) IsCustomVNET() bool { return len(m.VnetSubnetID) > 0 } // GetSubnet returns the read-only subnet for the master func (m *MasterProfile) GetSubnet() string { return m.subnet } // GetSubnetIPv6 returns the read-only ipv6 subnet for the master func (m *MasterProfile) GetSubnetIPv6() string { return m.subnetIPv6 } // SetSubnet sets the read-only subnet for the master func (m *MasterProfile) SetSubnet(subnet string) { m.subnet = subnet } // SetSubnetIPv6 sets the read-only ipv6 subnet for the master func (m *MasterProfile) SetSubnetIPv6(subnetIPv6 string) { m.subnetIPv6 = subnetIPv6 } // IsManagedDisks returns true if the master specified managed disks func (m *MasterProfile) IsManagedDisks() bool { return m.StorageProfile == ManagedDisks } // IsStorageAccount returns true if the master specified storage account func (m *MasterProfile) IsStorageAccount() bool { return m.StorageProfile == StorageAccount } // IsUbuntu1604 returns true if the master profile distro is based on Ubuntu 16.04 func (m *MasterProfile) IsUbuntu1604() bool { switch m.Distro { case AKSUbuntu1604, Ubuntu, ACC1604: return true default: return false } } // IsUbuntu1804 returns true if the master profile distro is based on Ubuntu 18.04 func (m *MasterProfile) IsUbuntu1804() bool { switch m.Distro { case AKSUbuntu1804, Ubuntu1804, Ubuntu1804Gen2: return true default: return false } } // IsUbuntu2004 returns true if the agent pool profile distro is based on Ubuntu 20.04 func (m *MasterProfile) IsUbuntu2004() bool { switch m.Distro { case AKSUbuntu2004, Ubuntu2004: return true default: return false } } // IsUbuntu2204 returns true if the agent pool profile distro is based on Ubuntu 22.04 func (m *MasterProfile) IsUbuntu2204() bool { switch m.Distro { case AKSUbuntu2204, Ubuntu2204: return true default: return false } } // IsUbuntu returns true if the master profile distro is any ubuntu distro func (m *MasterProfile) IsUbuntu() bool { return m.IsUbuntu1604() || m.IsUbuntu1804() || m.IsUbuntu2004() || m.IsUbuntu2204() } // IsVirtualMachineScaleSets returns true if the master availability profile is VMSS func (m *MasterProfile) IsVirtualMachineScaleSets() bool { return m.AvailabilityProfile == VirtualMachineScaleSets } // HasAvailabilityZones returns true if the master profile has availability zones func (m *MasterProfile) HasAvailabilityZones() bool { return len(m.AvailabilityZones) > 0 } // HasZonesForAllAgentPools returns true if all of the agent pools have zones func (p *Properties) HasZonesForAllAgentPools() bool { for _, ap := range p.AgentPoolProfiles { if !ap.HasAvailabilityZones() { return false } } return true } // MastersAndAgentsUseAvailabilityZones returns true if the cluster contains AZs for all agents and masters profiles func (p *Properties) MastersAndAgentsUseAvailabilityZones() bool { return (p.MasterProfile != nil && p.MasterProfile.HasAvailabilityZones()) && p.HasZonesForAllAgentPools() } // IsClusterAllVirtualMachineScaleSets returns true if the cluster contains only Virtual Machine Scale Sets func (p *Properties) IsClusterAllVirtualMachineScaleSets() bool { isAll := p.MasterProfile != nil && p.MasterProfile.IsVirtualMachineScaleSets() if isAll && p.AgentPoolProfiles != nil { for _, agentPoolProfile := range p.AgentPoolProfiles { if agentPoolProfile.AvailabilityProfile == AvailabilitySet { isAll = false break } } } return isAll } // GetAgentPoolByName returns the pool in the AgentPoolProfiles array that matches a name, nil if no match func (p *Properties) GetAgentPoolByName(name string) *AgentPoolProfile { for _, profile := range p.AgentPoolProfiles { if profile.Name == name { return profile } } return nil } // ShouldEnableAzureCloudAddon determines whether or not we should enable the following addons: // 1. cloud-node-manager, // 2. azuredisk-csi-driver, // 3. azurefile-csi-driver. // For Linux clusters, we should enable CSI Drivers when using K8s 1.13+ and cloud-node-manager when using K8s 1.16+. // For Windows clusters, we should enable them when using K8s 1.18+. func (p *Properties) ShouldEnableAzureCloudAddon(addonName string) bool { o := p.OrchestratorProfile if !to.Bool(o.KubernetesConfig.UseCloudControllerManager) { return false } if addonName == common.AzureDiskCSIDriverAddonName && p.IsAzureStackCloud() { return false } if !p.HasWindows() { switch addonName { case common.AzureDiskCSIDriverAddonName, common.AzureFileCSIDriverAddonName: return common.IsKubernetesVersionGe(o.OrchestratorVersion, "1.13.0") case common.CloudNodeManagerAddonName: return common.IsKubernetesVersionGe(o.OrchestratorVersion, "1.16.0") default: return false } } return common.IsKubernetesVersionGe(o.OrchestratorVersion, "1.18.0") } // IsCustomVNET returns true if the customer brought their own VNET func (a *AgentPoolProfile) IsCustomVNET() bool { return len(a.VnetSubnetID) > 0 } // IsWindows returns true if the agent pool is windows func (a *AgentPoolProfile) IsWindows() bool { return a.OSType == Windows } // IsLinux returns true if the agent pool is linux func (a *AgentPoolProfile) IsLinux() bool { return a.OSType == Linux } // IsFlatcar returns true if the agent specified a Flatcar distro func (a *AgentPoolProfile) IsFlatcar() bool { return a.Distro == Flatcar } // IsAvailabilitySets returns true if the customer specified disks func (a *AgentPoolProfile) IsAvailabilitySets() bool { return a.AvailabilityProfile == AvailabilitySet } // IsVirtualMachineScaleSets returns true if the agent pool availability profile is VMSS func (a *AgentPoolProfile) IsVirtualMachineScaleSets() bool { return a.AvailabilityProfile == VirtualMachineScaleSets } // IsNSeriesSKU returns true if the agent pool contains an N-series (NVIDIA GPU) VM func (a *AgentPoolProfile) IsNSeriesSKU() bool { return common.IsNvidiaEnabledSKU(a.VMSize) } // IsManagedDisks returns true if the customer specified managed disks func (a *AgentPoolProfile) IsManagedDisks() bool { return a.StorageProfile == ManagedDisks } // IsEphemeral returns true if the customer specified ephemeral disks func (a *AgentPoolProfile) IsEphemeral() bool { return a.StorageProfile == Ephemeral } // IsStorageAccount returns true if the customer specified storage account func (a *AgentPoolProfile) IsStorageAccount() bool { return a.StorageProfile == StorageAccount } // HasDisks returns true if the customer specified disks func (a *AgentPoolProfile) HasDisks() bool { return len(a.DiskSizesGB) > 0 } // GetSubnet returns the read-only subnet for the agent pool func (a *AgentPoolProfile) GetSubnet() string { return a.subnet } // SetSubnet sets the read-only subnet for the agent pool func (a *AgentPoolProfile) SetSubnet(subnet string) { a.subnet = subnet } // HasAvailabilityZones returns true if the agent pool has availability zones func (a *AgentPoolProfile) HasAvailabilityZones() bool { return len(a.AvailabilityZones) > 0 } // IsUbuntu1604 returns true if the agent pool profile distro is based on Ubuntu 16.04 func (a *AgentPoolProfile) IsUbuntu1604() bool { if a.OSType != Windows { switch a.Distro { case AKSUbuntu1604, Ubuntu, ACC1604: return true default: return false } } return false } // IsUbuntu1804 returns true if the agent pool profile distro is based on Ubuntu 18.04 func (a *AgentPoolProfile) IsUbuntu1804() bool { if a.OSType != Windows { switch a.Distro { case AKSUbuntu1804, Ubuntu1804, Ubuntu1804Gen2: return true default: return false } } return false } // IsUbuntu2004 returns true if the agent pool profile distro is based on Ubuntu 20.04 func (a *AgentPoolProfile) IsUbuntu2004() bool { if a.OSType != Windows { switch a.Distro { case AKSUbuntu2004, Ubuntu2004: return true default: return false } } return false } // IsUbuntu2204 returns true if the agent pool profile distro is based on Ubuntu 22.04 func (a *AgentPoolProfile) IsUbuntu2204() bool { if a.OSType != Windows { switch a.Distro { case AKSUbuntu2204, Ubuntu2204: return true default: return false } } return false } // IsUbuntu returns true if the master profile distro is any ubuntu distro func (a *AgentPoolProfile) IsUbuntu() bool { return a.IsUbuntu1604() || a.IsUbuntu1804() || a.IsUbuntu2004() || a.IsUbuntu2204() } // HasSearchDomain returns true if the customer specified secrets to install func (l *LinuxProfile) HasSearchDomain() bool { if l.CustomSearchDomain != nil { if l.CustomSearchDomain.Name != "" && l.CustomSearchDomain.RealmPassword != "" && l.CustomSearchDomain.RealmUser != "" { return true } } return false } // HasCustomNodesDNS returns true if the customer specified secrets to install func (l *LinuxProfile) HasCustomNodesDNS() bool { if l.CustomNodesDNS != nil { if l.CustomNodesDNS.DNSServer != "" { return true } } return false } // IsCSIProxyEnabled returns true if CSI proxy service should be enable for Windows nodes func (w *WindowsProfile) IsCSIProxyEnabled() bool { if w.EnableCSIProxy != nil { return *w.EnableCSIProxy } return common.DefaultEnableCSIProxyWindows } // RequiresDocker returns if the kubernetes settings require docker binary to be installed. func (k *KubernetesConfig) RequiresDocker() bool { runtime := strings.ToLower(k.ContainerRuntime) return runtime == Docker || runtime == "" } // IsRBACEnabled checks if RBAC is enabled func (k *KubernetesConfig) IsRBACEnabled() bool { if k.EnableRbac != nil { return to.Bool(k.EnableRbac) } return false } // GetAddonByName returns the KubernetesAddon instance with name `addonName` func (k *KubernetesConfig) GetAddonByName(addonName string) KubernetesAddon { var kubeAddon KubernetesAddon for _, addon := range k.Addons { if addon.Name == addonName { kubeAddon = addon break } } return kubeAddon } // IsAddonEnabled checks whether a k8s addon with name "addonName" is enabled or not based on the Enabled field of KubernetesAddon. // If the value of Enabled is nil, the "defaultValue" is returned. func (k *KubernetesConfig) IsAddonEnabled(addonName string) bool { if k != nil { kubeAddon := k.GetAddonByName(addonName) return kubeAddon.IsEnabled() } return false } // IsIPv6DualStackEnabled checks if IPv6DualStack feature is enabled func (f *FeatureFlags) IsIPv6DualStackEnabled() bool { return f != nil && f.EnableIPv6DualStack } // IsIPv6OnlyEnabled checks if IPv6Only feature is enabled func (f *FeatureFlags) IsIPv6OnlyEnabled() bool { return f != nil && f.EnableIPv6Only } // IsWinDSREnabled checks if WinDSR feature is enabled func (f *FeatureFlags) IsWinDSREnabled() bool { return f != nil && f.EnableWinDSR } // IsEnforceUbuntuDisaStigEnabled checks if EnforceUbuntuDisaStig feature is enabled func (f *FeatureFlags) IsEnforceUbuntuDisaStigEnabled() bool { return f != nil && (f.EnforceUbuntu2004DisaStig || f.EnforceUbuntu2204DisaStig) } // IsEnforceKubernetesDisaStigEnabled checks if EnforceKubernetesDisaStig feature is enabled func (f *FeatureFlags) IsEnforceKubernetesDisaStigEnabled() bool { return f != nil && f.EnforceKubernetesDisaStig }