зеркало из https://github.com/Azure/aks-engine.git
2340 строки
99 KiB
Go
2340 строки
99 KiB
Go
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT license.
|
|
|
|
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"hash/fnv"
|
|
"math/rand"
|
|
"net"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/Azure/aks-engine/pkg/api/common"
|
|
"github.com/Azure/aks-engine/pkg/api/vlabs"
|
|
"github.com/Azure/aks-engine/pkg/helpers"
|
|
"github.com/Azure/go-autorest/autorest/azure"
|
|
"github.com/Azure/go-autorest/autorest/to"
|
|
"github.com/blang/semver"
|
|
)
|
|
|
|
// TypeMeta describes an individual API model object
|
|
type TypeMeta struct {
|
|
// APIVersion is on every object
|
|
APIVersion string `json:"apiVersion"`
|
|
}
|
|
|
|
// ResourcePurchasePlan defines resource plan as required by ARM
|
|
// for billing purposes.
|
|
type ResourcePurchasePlan struct {
|
|
Name string `json:"name"`
|
|
Product string `json:"product"`
|
|
PromotionCode string `json:"promotionCode"`
|
|
Publisher string `json:"publisher"`
|
|
}
|
|
|
|
// ContainerService complies with the ARM model of
|
|
// resource definition in a JSON template.
|
|
type ContainerService struct {
|
|
ID string `json:"id"`
|
|
Location string `json:"location"`
|
|
Name string `json:"name"`
|
|
Plan *ResourcePurchasePlan `json:"plan,omitempty"`
|
|
Tags map[string]string `json:"tags"`
|
|
Type string `json:"type"`
|
|
|
|
Properties *Properties `json:"properties,omitempty"`
|
|
}
|
|
|
|
// Properties represents the AKS cluster definition
|
|
type Properties struct {
|
|
ClusterID string
|
|
ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
|
|
OrchestratorProfile *OrchestratorProfile `json:"orchestratorProfile,omitempty"`
|
|
MasterProfile *MasterProfile `json:"masterProfile,omitempty"`
|
|
AgentPoolProfiles []*AgentPoolProfile `json:"agentPoolProfiles,omitempty"`
|
|
LinuxProfile *LinuxProfile `json:"linuxProfile,omitempty"`
|
|
WindowsProfile *WindowsProfile `json:"windowsProfile,omitempty"`
|
|
ExtensionProfiles []*ExtensionProfile `json:"extensionProfiles"`
|
|
JumpboxProfile *JumpboxProfile `json:"jumpboxProfile,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"`
|
|
}
|
|
|
|
// ServicePrincipalProfile contains the client and secret used by the cluster for Azure Resource CRUD
|
|
type ServicePrincipalProfile struct {
|
|
ClientID string `json:"clientId"`
|
|
Secret string `json:"secret,omitempty" conform:"redact"`
|
|
ObjectID string `json:"objectId,omitempty"`
|
|
KeyvaultSecretRef *KeyvaultSecretRef `json:"keyvaultSecretRef,omitempty"`
|
|
}
|
|
|
|
// KeyvaultSecretRef specifies path to the Azure keyvault along with secret name and (optionaly) version
|
|
// for Service Principal's secret
|
|
type KeyvaultSecretRef struct {
|
|
VaultID string `json:"vaultID"`
|
|
SecretName string `json:"secretName"`
|
|
SecretVersion string `json:"version,omitempty"`
|
|
}
|
|
|
|
// CertificateProfile represents the definition of the master cluster
|
|
type CertificateProfile struct {
|
|
// CaCertificate is the certificate authority certificate.
|
|
CaCertificate string `json:"caCertificate,omitempty" conform:"redact"`
|
|
// CaPrivateKey is the certificate authority key.
|
|
CaPrivateKey string `json:"caPrivateKey,omitempty" conform:"redact"`
|
|
// ApiServerCertificate is the rest api server certificate, and signed by the CA
|
|
APIServerCertificate string `json:"apiServerCertificate,omitempty" conform:"redact"`
|
|
// ApiServerPrivateKey is the rest api server private key, and signed by the CA
|
|
APIServerPrivateKey string `json:"apiServerPrivateKey,omitempty" conform:"redact"`
|
|
// ClientCertificate is the certificate used by the client kubelet services and signed by the CA
|
|
ClientCertificate string `json:"clientCertificate,omitempty" conform:"redact"`
|
|
// ClientPrivateKey is the private key used by the client kubelet services and signed by the CA
|
|
ClientPrivateKey string `json:"clientPrivateKey,omitempty" conform:"redact"`
|
|
// KubeConfigCertificate is the client certificate used for kubectl cli and signed by the CA
|
|
KubeConfigCertificate string `json:"kubeConfigCertificate,omitempty" conform:"redact"`
|
|
// KubeConfigPrivateKey is the client private key used for kubectl cli and signed by the CA
|
|
KubeConfigPrivateKey string `json:"kubeConfigPrivateKey,omitempty" conform:"redact"`
|
|
// EtcdServerCertificate is the server certificate for etcd, and signed by the CA
|
|
EtcdServerCertificate string `json:"etcdServerCertificate,omitempty" conform:"redact"`
|
|
// EtcdServerPrivateKey is the server private key for etcd, and signed by the CA
|
|
EtcdServerPrivateKey string `json:"etcdServerPrivateKey,omitempty" conform:"redact"`
|
|
// EtcdClientCertificate is etcd client certificate, and signed by the CA
|
|
EtcdClientCertificate string `json:"etcdClientCertificate,omitempty" conform:"redact"`
|
|
// EtcdClientPrivateKey is the etcd client private key, and signed by the CA
|
|
EtcdClientPrivateKey string `json:"etcdClientPrivateKey,omitempty" conform:"redact"`
|
|
// EtcdPeerCertificates is list of etcd peer certificates, and signed by the CA
|
|
EtcdPeerCertificates []string `json:"etcdPeerCertificates,omitempty" conform:"redact"`
|
|
// EtcdPeerPrivateKeys is list of etcd peer private keys, and signed by the CA
|
|
EtcdPeerPrivateKeys []string `json:"etcdPeerPrivateKeys,omitempty" conform:"redact"`
|
|
}
|
|
|
|
// LinuxProfile represents the linux parameters passed to the cluster
|
|
type LinuxProfile struct {
|
|
AdminUsername string `json:"adminUsername"`
|
|
SSH struct {
|
|
PublicKeys []PublicKey `json:"publicKeys"`
|
|
} `json:"ssh"`
|
|
Secrets []KeyVaultSecrets `json:"secrets,omitempty"`
|
|
Distro Distro `json:"distro,omitempty"`
|
|
ScriptRootURL string `json:"scriptroot,omitempty"`
|
|
CustomSearchDomain *CustomSearchDomain `json:"customSearchDomain,omitempty"`
|
|
CustomNodesDNS *CustomNodesDNS `json:"CustomNodesDNS,omitempty"`
|
|
IsSSHKeyAutoGenerated *bool `json:"isSSHKeyAutoGenerated,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 when the custom vnet for a custom DNS as a nameserver.
|
|
type CustomNodesDNS struct {
|
|
DNSServer string `json:"dnsServer,omitempty"`
|
|
}
|
|
|
|
const (
|
|
// WindowsLicenseTypeServer specifies that the image or disk that is being used was licensed server on-premises.
|
|
WindowsLicenseTypeServer string = "Windows_Server"
|
|
// WindowsLicenseTypeNone specifies that the image or disk that is being used was not licensed on-premises.
|
|
WindowsLicenseTypeNone string = "None"
|
|
)
|
|
|
|
// WindowsProfile represents the windows parameters passed to the cluster
|
|
type WindowsProfile struct {
|
|
AdminUsername string `json:"adminUsername"`
|
|
AdminPassword string `json:"adminPassword" conform:"redact"`
|
|
CSIProxyURL string `json:"csiProxyURL,omitempty"`
|
|
EnableCSIProxy *bool `json:"enableCSIProxy,omitempty"`
|
|
ImageRef *ImageReference `json:"imageReference,omitempty"`
|
|
ImageVersion string `json:"imageVersion"`
|
|
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"
|
|
// Scaling means an existing ContainerService resource is being scaled only
|
|
Scaling ProvisioningState = "Scaling"
|
|
// 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"
|
|
// Upgrading means an existing ContainerService resource is being upgraded
|
|
Upgrading ProvisioningState = "Upgrading"
|
|
)
|
|
|
|
// OrchestratorProfile contains Orchestrator properties
|
|
type OrchestratorProfile struct {
|
|
// OrchestratorType is a legacy property, this should always be set to "Kubernetes"
|
|
OrchestratorType string `json:"orchestratorType"`
|
|
OrchestratorVersion string `json:"orchestratorVersion"`
|
|
KubernetesConfig *KubernetesConfig `json:"kubernetesConfig,omitempty"`
|
|
}
|
|
|
|
// OrchestratorVersionProfile contains information of a supported orchestrator version:
|
|
type OrchestratorVersionProfile struct {
|
|
// Orchestrator type and version
|
|
OrchestratorProfile
|
|
// Whether this orchestrator version is deployed by default if orchestrator release is not specified
|
|
Default bool `json:"default,omitempty"`
|
|
// List of available upgrades for this orchestrator version
|
|
Upgrades []*OrchestratorProfile `json:"upgrades,omitempty"`
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// IsDisabled returns true if the addon is explicitly disabled
|
|
func (a *KubernetesAddon) IsDisabled() bool {
|
|
if a.Enabled == nil {
|
|
return false
|
|
}
|
|
return !*a.Enabled
|
|
}
|
|
|
|
// GetAddonContainersIndexByName returns the KubernetesAddon containers index with the name `containerName`
|
|
func (a KubernetesAddon) GetAddonContainersIndexByName(containerName string) int {
|
|
for i := range a.Containers {
|
|
if a.Containers[i].Name == containerName {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// GetAddonPoolIndexByName returns the KubernetesAddon pools index with the name `poolName`
|
|
func (a KubernetesAddon) GetAddonPoolIndexByName(poolName string) int {
|
|
for i := range a.Pools {
|
|
if a.Pools[i].Name == poolName {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// 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"`
|
|
}
|
|
|
|
// IsEnabled returns true if the component is enabled
|
|
func (c *KubernetesComponent) IsEnabled() bool {
|
|
if c.Enabled == nil {
|
|
return false
|
|
}
|
|
return *c.Enabled
|
|
}
|
|
|
|
// IsDisabled returns true if the component is explicitly disabled
|
|
func (c *KubernetesComponent) IsDisabled() bool {
|
|
if c.Enabled == nil {
|
|
return false
|
|
}
|
|
return !*c.Enabled
|
|
}
|
|
|
|
// GetContainersIndexByName returns the KubernetesAddon containers index with the name `containerName`
|
|
func (c KubernetesComponent) GetContainersIndexByName(containerName string) int {
|
|
for i := range c.Containers {
|
|
if c.Containers[i].Name == containerName {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// 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"`
|
|
}
|
|
|
|
// CloudProviderConfig contains the KubernetesConfig properties specific to the Cloud Provider
|
|
type CloudProviderConfig struct {
|
|
CloudProviderBackoffMode string `json:"cloudProviderBackoffMode,omitempty"`
|
|
CloudProviderBackoff *bool `json:"cloudProviderBackoff,omitempty"`
|
|
CloudProviderBackoffRetries int `json:"cloudProviderBackoffRetries,omitempty"`
|
|
CloudProviderBackoffJitter string `json:"cloudProviderBackoffJitter,omitempty"`
|
|
CloudProviderBackoffDuration int `json:"cloudProviderBackoffDuration,omitempty"`
|
|
CloudProviderBackoffExponent string `json:"cloudProviderBackoffExponent,omitempty"`
|
|
CloudProviderRateLimit *bool `json:"cloudProviderRateLimit,omitempty"`
|
|
CloudProviderRateLimitQPS string `json:"cloudProviderRateLimitQPS,omitempty"`
|
|
CloudProviderRateLimitQPSWrite string `json:"cloudProviderRateLimitQPSWrite,omitempty"`
|
|
CloudProviderRateLimitBucket int `json:"cloudProviderRateLimitBucket,omitempty"`
|
|
CloudProviderRateLimitBucketWrite int `json:"cloudProviderRateLimitBucketWrite,omitempty"`
|
|
CloudProviderDisableOutboundSNAT *bool `json:"cloudProviderDisableOutboundSNAT,omitempty"`
|
|
}
|
|
|
|
// KubeProxyMode is for iptables and ipvs (and future others)
|
|
type KubeProxyMode string
|
|
|
|
// We currently support ipvs and iptables
|
|
const (
|
|
// KubeProxyModeIPTables is used to set the kube-proxy to iptables mode
|
|
KubeProxyModeIPTables KubeProxyMode = "iptables"
|
|
// KubeProxyModeIPVS is used to set the kube-proxy to ipvs mode
|
|
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"`
|
|
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"`
|
|
DNSServiceIP string `json:"dnsServiceIP,omitempty"`
|
|
ServiceCIDR string `json:"serviceCidr,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"` // Image for cloud-controller-manager
|
|
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"`
|
|
KubeletConfig map[string]string `json:"kubeletConfig,omitempty"`
|
|
ContainerRuntimeConfig map[string]string `json:"containerRuntimeConfig"`
|
|
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"`
|
|
NonMasqueradeCidr string `json:"nonMasqueradeCidr,omitempty"`
|
|
NodeStatusUpdateFrequency string `json:"nodeStatusUpdateFrequency,omitempty"`
|
|
HardEvictionThreshold string `json:"hardEvictionThreshold,omitempty"`
|
|
CtrlMgrNodeMonitorGracePeriod string `json:"ctrlMgrNodeMonitorGracePeriod,omitempty"`
|
|
CtrlMgrPodEvictionTimeout string `json:"ctrlMgrPodEvictionTimeout,omitempty"`
|
|
CtrlMgrRouteReconciliationPeriod string `json:"ctrlMgrRouteReconciliationPeriod,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"`
|
|
DNSPrefix string `json:"dnsPrefix"`
|
|
SubjectAltNames []string `json:"subjectAltNames"`
|
|
VMSize string `json:"vmSize"`
|
|
OSDiskSizeGB int `json:"osDiskSizeGB,omitempty"`
|
|
VnetSubnetID string `json:"vnetSubnetID,omitempty"`
|
|
VnetCidr string `json:"vnetCidr,omitempty"`
|
|
AgentVnetSubnetID string `json:"agentVnetSubnetID,omitempty"`
|
|
FirstConsecutiveStaticIP string `json:"firstConsecutiveStaticIP,omitempty"`
|
|
Subnet string `json:"subnet"`
|
|
SubnetIPv6 string `json:"subnetIPv6"`
|
|
IPAddressCount int `json:"ipAddressCount,omitempty"`
|
|
StorageProfile string `json:"storageProfile,omitempty"`
|
|
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"`
|
|
PlatformFaultDomainCount *int `json:"platformFaultDomainCount"`
|
|
PlatformUpdateDomainCount *int `json:"platformUpdateDomainCount"`
|
|
AgentSubnet string `json:"agentSubnet,omitempty"`
|
|
AvailabilityZones []string `json:"availabilityZones,omitempty"`
|
|
SinglePlacementGroup *bool `json:"singlePlacementGroup,omitempty"`
|
|
AuditDEnabled *bool `json:"auditDEnabled,omitempty"`
|
|
UltraSSDEnabled *bool `json:"ultraSSDEnabled,omitempty"`
|
|
EncryptionAtHost *bool `json:"encryptionAtHost,omitempty"`
|
|
CustomVMTags map[string]string `json:"customVMTags,omitempty"`
|
|
// 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"`
|
|
SysctlDConfig map[string]string `json:"sysctldConfig,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"`
|
|
Count int `json:"count"`
|
|
VMSize string `json:"vmSize"`
|
|
OSDiskSizeGB int `json:"osDiskSizeGB,omitempty"`
|
|
DNSPrefix string `json:"dnsPrefix,omitempty"`
|
|
OSType OSType `json:"osType,omitempty"`
|
|
Ports []int `json:"ports,omitempty"`
|
|
ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
|
|
AvailabilityProfile string `json:"availabilityProfile"`
|
|
ScaleSetPriority string `json:"scaleSetPriority,omitempty"`
|
|
ScaleSetEvictionPolicy string `json:"scaleSetEvictionPolicy,omitempty"`
|
|
SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"`
|
|
StorageProfile string `json:"storageProfile,omitempty"`
|
|
DiskSizesGB []int `json:"diskSizesGB,omitempty"`
|
|
VnetSubnetID string `json:"vnetSubnetID,omitempty"`
|
|
Subnet string `json:"subnet"`
|
|
IPAddressCount int `json:"ipAddressCount,omitempty"`
|
|
Distro Distro `json:"distro,omitempty"`
|
|
Role AgentPoolProfileRole `json:"role,omitempty"`
|
|
AcceleratedNetworkingEnabled *bool `json:"acceleratedNetworkingEnabled,omitempty"`
|
|
AcceleratedNetworkingEnabledWindows *bool `json:"acceleratedNetworkingEnabledWindows,omitempty"`
|
|
VMSSOverProvisioningEnabled *bool `json:"vmssOverProvisioningEnabled,omitempty"`
|
|
FQDN string `json:"fqdn,omitempty"`
|
|
CustomNodeLabels map[string]string `json:"customNodeLabels,omitempty"`
|
|
PreprovisionExtension *Extension `json:"preProvisionExtension"`
|
|
Extensions []Extension `json:"extensions"`
|
|
KubernetesConfig *KubernetesConfig `json:"kubernetesConfig,omitempty"`
|
|
OrchestratorVersion string `json:"orchestratorVersion"`
|
|
ImageRef *ImageReference `json:"imageReference,omitempty"`
|
|
MaxCount *int `json:"maxCount,omitempty"`
|
|
MinCount *int `json:"minCount,omitempty"`
|
|
EnableAutoScaling *bool `json:"enableAutoScaling,omitempty"`
|
|
AvailabilityZones []string `json:"availabilityZones,omitempty"`
|
|
PlatformFaultDomainCount *int `json:"platformFaultDomainCount"`
|
|
PlatformUpdateDomainCount *int `json:"platformUpdateDomainCount"`
|
|
SinglePlacementGroup *bool `json:"singlePlacementGroup,omitempty"`
|
|
VnetCidrs []string `json:"vnetCidrs,omitempty"`
|
|
PreserveNodesProperties *bool `json:"preserveNodesProperties,omitempty"`
|
|
WindowsNameVersion string `json:"windowsNameVersion,omitempty"` // Deprecated
|
|
EnableVMSSNodePublicIP *bool `json:"enableVMSSNodePublicIP,omitempty"`
|
|
LoadBalancerBackendAddressPoolIDs []string `json:"loadBalancerBackendAddressPoolIDs,omitempty"`
|
|
AuditDEnabled *bool `json:"auditDEnabled,omitempty"`
|
|
CustomVMTags map[string]string `json:"customVMTags,omitempty"`
|
|
DiskEncryptionSetID string `json:"diskEncryptionSetID,omitempty"`
|
|
SysctlDConfig map[string]string `json:"sysctldConfig,omitempty"`
|
|
UltraSSDEnabled *bool `json:"ultraSSDEnabled,omitempty"`
|
|
EncryptionAtHost *bool `json:"encryptionAtHost,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
|
|
|
|
// JumpboxProfile describes properties of the jumpbox setup
|
|
// in the AKS container cluster.
|
|
type JumpboxProfile struct {
|
|
OSType OSType `json:"osType"`
|
|
DNSPrefix string `json:"dnsPrefix"`
|
|
|
|
// Jumpbox 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"`
|
|
}
|
|
|
|
// 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
|
|
|
|
// AuthenticatorType represents the authenticator type the cluster was
|
|
// set up with.
|
|
type AuthenticatorType string
|
|
|
|
const (
|
|
// OIDC represent cluster setup in OIDC auth mode
|
|
OIDC AuthenticatorType = "oidc"
|
|
// Webhook represent cluster setup in wehhook auth mode
|
|
Webhook AuthenticatorType = "webhook"
|
|
)
|
|
|
|
// 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 server AAD application secret
|
|
ServerAppSecret string `json:"serverAppSecret,omitempty" conform:"redact"`
|
|
// 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"`
|
|
// The authenticator to use, either "oidc" or "webhook".
|
|
Authenticator AuthenticatorType `json:"authenticator"`
|
|
}
|
|
|
|
// VlabsARMContainerService is the type we read and write from file
|
|
// needed because the json that is sent to ARM and aks-engine
|
|
// is different from the json that the ACS RP Api gets from ARM
|
|
type VlabsARMContainerService struct {
|
|
TypeMeta
|
|
*vlabs.ContainerService
|
|
}
|
|
|
|
// AzureStackMetadataEndpoints is the type for Azure Stack metadata endpoints
|
|
type AzureStackMetadataEndpoints struct {
|
|
GalleryEndpoint string `json:"galleryEndpoint,omitempty"`
|
|
GraphEndpoint string `json:"graphEndpoint,omitempty"`
|
|
PortalEndpoint string `json:"portalEndpoint,omitempty"`
|
|
Authentication *AzureStackMetadataAuthentication `json:"authentication,omitempty"`
|
|
}
|
|
|
|
// AzureStackMetadataAuthentication is the type for Azure Stack metadata authentication endpoints
|
|
type AzureStackMetadataAuthentication struct {
|
|
LoginEndpoint string `json:"loginEndpoint,omitempty"`
|
|
Audiences []string `json:"audiences,omitempty"`
|
|
}
|
|
|
|
// DependenciesLocation represents location to retrieve the dependencies.
|
|
type DependenciesLocation string
|
|
|
|
// CustomCloudProfile represents the custom cloud profile
|
|
type CustomCloudProfile struct {
|
|
Environment *azure.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
|
|
}
|
|
|
|
// HasManagedDisks returns true if the cluster contains Managed Disks
|
|
func (p *Properties) HasManagedDisks() bool {
|
|
if p.MasterProfile != nil && p.MasterProfile.StorageProfile == ManagedDisks {
|
|
return true
|
|
}
|
|
for _, agentPoolProfile := range p.AgentPoolProfiles {
|
|
if agentPoolProfile.StorageProfile == ManagedDisks {
|
|
return true
|
|
}
|
|
}
|
|
if p.OrchestratorProfile != nil && p.OrchestratorProfile.KubernetesConfig != nil && p.OrchestratorProfile.KubernetesConfig.PrivateJumpboxProvision() && p.OrchestratorProfile.KubernetesConfig.PrivateCluster.JumpboxProfile.StorageProfile == ManagedDisks {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// HasStorageAccountDisks returns true if the cluster contains Storage Account Disks
|
|
func (p *Properties) HasStorageAccountDisks() bool {
|
|
if p.MasterProfile != nil && p.MasterProfile.StorageProfile == StorageAccount {
|
|
return true
|
|
}
|
|
for _, agentPoolProfile := range p.AgentPoolProfiles {
|
|
if agentPoolProfile.StorageProfile == StorageAccount {
|
|
return true
|
|
}
|
|
}
|
|
if p.OrchestratorProfile != nil && p.OrchestratorProfile.KubernetesConfig != nil && p.OrchestratorProfile.KubernetesConfig.PrivateJumpboxProvision() && p.OrchestratorProfile.KubernetesConfig.PrivateCluster.JumpboxProfile.StorageProfile == StorageAccount {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// HasStorageAccountDisks returns true if the cluster contains agent pools with Ephemeral Disks
|
|
func (p *Properties) HasEphemeralDisks() bool {
|
|
for _, agentPoolProfile := range p.AgentPoolProfiles {
|
|
if agentPoolProfile.StorageProfile == Ephemeral {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// TotalNodes returns the total number of nodes in the cluster configuration
|
|
func (p *Properties) TotalNodes() int {
|
|
var totalNodes int
|
|
if p.MasterProfile != nil {
|
|
totalNodes = p.MasterProfile.Count
|
|
}
|
|
for _, pool := range p.AgentPoolProfiles {
|
|
totalNodes += pool.Count
|
|
}
|
|
return totalNodes
|
|
}
|
|
|
|
// HasVMSSAgentPool returns true if the cluster contains Virtual Machine Scale Sets agent pools
|
|
func (p *Properties) HasVMSSAgentPool() bool {
|
|
for _, agentPoolProfile := range p.AgentPoolProfiles {
|
|
if agentPoolProfile.AvailabilityProfile == VirtualMachineScaleSets {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// K8sOrchestratorName returns the 3 character orchestrator code for kubernetes-based clusters.
|
|
func (p *Properties) K8sOrchestratorName() string {
|
|
return DefaultOrchestratorName
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// GetAgentPoolIndexByName returns the index of the provided agentpool.
|
|
func (p *Properties) GetAgentPoolIndexByName(name string) int {
|
|
index := -1
|
|
for i, profile := range p.AgentPoolProfiles {
|
|
if profile.Name == name {
|
|
index = i
|
|
break
|
|
}
|
|
}
|
|
return index
|
|
}
|
|
|
|
// GetAgentVMPrefix returns the VM prefix for an agentpool.
|
|
func (p *Properties) GetAgentVMPrefix(a *AgentPoolProfile, index int) string {
|
|
if a.IsVirtualMachineScaleSets() && a.VMSSName != "" {
|
|
return a.VMSSName
|
|
}
|
|
nameSuffix := p.GetClusterID()
|
|
vmPrefix := ""
|
|
if a.IsLinux() || a.OSType == "" {
|
|
vmPrefix = p.K8sOrchestratorName() + "-" + a.Name + "-" + nameSuffix + "-"
|
|
if a.IsVirtualMachineScaleSets() {
|
|
vmPrefix += "vmss"
|
|
}
|
|
} else if a.IsWindows() && index != -1 {
|
|
vmPrefix = nameSuffix[:4] + p.K8sOrchestratorName() + fmt.Sprintf("%02d", index)
|
|
}
|
|
return vmPrefix
|
|
}
|
|
|
|
// IsAgentPoolMember returns true the VM is a pool member
|
|
func (p *Properties) IsAgentPoolMember(vmName string, a *AgentPoolProfile, index int) bool {
|
|
return strings.HasPrefix(vmName, p.GetAgentVMPrefix(a, index))
|
|
}
|
|
|
|
// GetVMType returns the type of VM "vmss" or "standard" to be passed to the cloud provider
|
|
func (p *Properties) GetVMType() string {
|
|
if p.HasVMSSAgentPool() {
|
|
return VMSSVMType
|
|
}
|
|
return StandardVMType
|
|
}
|
|
|
|
// HasVMASAgentPool checks whether any of the agents in the AgentPool use VMAS or not
|
|
func (p *Properties) HasVMASAgentPool() bool {
|
|
for _, agentProfile := range p.AgentPoolProfiles {
|
|
if agentProfile.IsAvailabilitySets() {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// AnyAgentIsLinux checks whether any of the agents in the AgentPools are linux
|
|
func (p *Properties) AnyAgentIsLinux() bool {
|
|
for _, agentProfile := range p.AgentPoolProfiles {
|
|
if agentProfile.IsLinux() {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GetMasterVMNameList returns the ordered control plane VM name list
|
|
func (p *Properties) GetMasterVMNameList() []string {
|
|
masters := []string{}
|
|
for i := 0; i < p.MasterProfile.Count; i++ {
|
|
if p.MasterProfile.IsAvailabilitySet() {
|
|
masters = append(masters, fmt.Sprintf("%s%d", p.GetMasterVMPrefix(), i))
|
|
} else {
|
|
masters = append(masters, fmt.Sprintf("%svmss00000%d", p.GetMasterVMPrefix(), i))
|
|
}
|
|
}
|
|
return masters
|
|
}
|
|
|
|
// GetMasterVMPrefix returns the prefix of master VMs
|
|
func (p *Properties) GetMasterVMPrefix() string {
|
|
return p.K8sOrchestratorName() + "-master-" + p.GetClusterID() + "-"
|
|
}
|
|
|
|
// GetRouteTableName returns the route table name of the cluster.
|
|
func (p *Properties) GetRouteTableName() string {
|
|
return p.GetMasterVMPrefix() + "routetable"
|
|
}
|
|
|
|
// GetNSGName returns the name of the network security group of the cluster.
|
|
func (p *Properties) GetNSGName() string {
|
|
return p.GetMasterVMPrefix() + "nsg"
|
|
}
|
|
|
|
// GetPrimaryAvailabilitySetName returns the name of the primary availability set of the cluster
|
|
func (p *Properties) GetPrimaryAvailabilitySetName() string {
|
|
if len(p.AgentPoolProfiles) > 0 {
|
|
if p.AgentPoolProfiles[0].AvailabilityProfile == AvailabilitySet {
|
|
return p.AgentPoolProfiles[0].Name + "-availabilitySet-" + p.GetClusterID()
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// GetPrimaryScaleSetName returns the name of the primary scale set node of the cluster
|
|
func (p *Properties) GetPrimaryScaleSetName() string {
|
|
if len(p.AgentPoolProfiles) > 0 {
|
|
if p.AgentPoolProfiles[0].AvailabilityProfile == VirtualMachineScaleSets {
|
|
return p.GetAgentVMPrefix(p.AgentPoolProfiles[0], 0)
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// IsIPMasqAgentEnabled returns true if ip-masq-agent is enabled
|
|
func (p *Properties) IsIPMasqAgentEnabled() bool {
|
|
return p.OrchestratorProfile != nil &&
|
|
p.OrchestratorProfile.KubernetesConfig != nil &&
|
|
p.OrchestratorProfile.KubernetesConfig.IsAddonEnabled(common.IPMASQAgentAddonName)
|
|
}
|
|
|
|
// IsIPMasqAgentDisabled returns true if the ip-masq-agent functionality is disabled
|
|
func (p *Properties) IsIPMasqAgentDisabled() bool {
|
|
return p.OrchestratorProfile != nil &&
|
|
p.OrchestratorProfile.KubernetesConfig != nil &&
|
|
p.OrchestratorProfile.KubernetesConfig.IsAddonDisabled(common.IPMASQAgentAddonName)
|
|
}
|
|
|
|
// GetVNetResourceGroupName returns the virtual network resource group name of the cluster
|
|
func (p *Properties) GetVNetResourceGroupName() string {
|
|
var vnetResourceGroupName string
|
|
if p.MasterProfile != nil && p.MasterProfile.IsCustomVNET() {
|
|
vnetResourceGroupName = strings.Split(p.MasterProfile.VnetSubnetID, "/")[DefaultVnetResourceGroupSegmentIndex]
|
|
}
|
|
return vnetResourceGroupName
|
|
}
|
|
|
|
// GetVirtualNetworkName returns the virtual network name of the cluster
|
|
func (p *Properties) GetVirtualNetworkName() string {
|
|
var vnetName string
|
|
if p.MasterProfile != nil && p.MasterProfile.IsCustomVNET() {
|
|
vnetName = strings.Split(p.MasterProfile.VnetSubnetID, "/")[DefaultVnetNameResourceSegmentIndex]
|
|
} else {
|
|
vnetName = p.K8sOrchestratorName() + "-vnet-" + p.GetClusterID()
|
|
}
|
|
return vnetName
|
|
}
|
|
|
|
// GetSubnetName returns the subnet name of the cluster based on its current configuration.
|
|
func (p *Properties) GetSubnetName() string {
|
|
var subnetName string
|
|
if p.MasterProfile.IsCustomVNET() {
|
|
subnetName = strings.Split(p.MasterProfile.VnetSubnetID, "/")[DefaultSubnetNameResourceSegmentIndex]
|
|
} else if p.MasterProfile.IsVirtualMachineScaleSets() {
|
|
subnetName = "subnetmaster"
|
|
} else {
|
|
subnetName = p.K8sOrchestratorName() + "-subnet"
|
|
}
|
|
return subnetName
|
|
}
|
|
|
|
// GetDNSPrefix returns the the string used as master FQDN prefix
|
|
func (p *Properties) GetDNSPrefix() string {
|
|
if p.MasterProfile != nil {
|
|
// MasterProfile exists, uses master DNS prefix
|
|
return strings.ToLower(p.MasterProfile.DNSPrefix)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// AreAgentProfilesCustomVNET returns true if all of the agent profiles in the clusters are configured with VNET.
|
|
func (p *Properties) AreAgentProfilesCustomVNET() bool {
|
|
if p.AgentPoolProfiles != nil {
|
|
for _, agentPoolProfile := range p.AgentPoolProfiles {
|
|
if !agentPoolProfile.IsCustomVNET() {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GetClusterID creates a unique 8 string cluster ID.
|
|
func (p *Properties) GetClusterID() string {
|
|
if p.ClusterID == "" {
|
|
uniqueNameSuffixSize := 8
|
|
// the name suffix uniquely identifies the cluster and is generated off a hash
|
|
// from the master dns name
|
|
h := fnv.New64a()
|
|
if p.MasterProfile != nil {
|
|
_, _ = h.Write([]byte(p.MasterProfile.DNSPrefix))
|
|
} else if len(p.AgentPoolProfiles) > 0 {
|
|
_, _ = h.Write([]byte(p.AgentPoolProfiles[0].Name))
|
|
}
|
|
r := rand.New(rand.NewSource(int64(h.Sum64())))
|
|
p.ClusterID = fmt.Sprintf("%08d", r.Uint32())[:uniqueNameSuffixSize]
|
|
}
|
|
return p.ClusterID
|
|
}
|
|
|
|
// HasZonesForAllAgentPools returns true if all of the agent pools have zones
|
|
func (p *Properties) HasZonesForAllAgentPools() bool {
|
|
if len(p.AgentPoolProfiles) > 0 {
|
|
for _, ap := range p.AgentPoolProfiles {
|
|
if !ap.HasAvailabilityZones() {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsVHDDistroForAllNodes returns true if all of the agent pools plus masters are running the VHD image
|
|
func (p *Properties) IsVHDDistroForAllNodes() bool {
|
|
if len(p.AgentPoolProfiles) > 0 {
|
|
for _, ap := range p.AgentPoolProfiles {
|
|
if !ap.IsVHDDistro() {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
if p.MasterProfile != nil {
|
|
return p.MasterProfile.IsVHDDistro()
|
|
}
|
|
return true
|
|
}
|
|
|
|
// HasVHDDistroNodes returns true if any one Linux node pool, including masters, are running a VHD image
|
|
func (p *Properties) HasVHDDistroNodes() bool {
|
|
if len(p.AgentPoolProfiles) > 0 {
|
|
for _, ap := range p.AgentPoolProfiles {
|
|
if ap.IsVHDDistro() {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
if p.MasterProfile != nil {
|
|
return p.MasterProfile.IsVHDDistro()
|
|
}
|
|
return false
|
|
}
|
|
|
|
// HasAvailabilityZones returns true if the cluster contains a 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
|
|
}
|
|
|
|
func (p *Properties) HasAgentPoolAvailabilityZones() bool {
|
|
for _, pool := range p.AgentPoolProfiles {
|
|
if pool.AvailabilityZones != nil {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// HasNonRegularPriorityScaleset returns true if any one node pool has a low or spot priority scaleset configuration
|
|
func (p *Properties) HasNonRegularPriorityScaleset() bool {
|
|
for _, agentPoolProfile := range p.AgentPoolProfiles {
|
|
if agentPoolProfile.IsLowPriorityScaleSet() || agentPoolProfile.IsSpotScaleSet() {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GetNonMasqueradeCIDR returns the non-masquerade CIDR for the ip-masq-agent.
|
|
func (p *Properties) GetNonMasqueradeCIDR() string {
|
|
var nonMasqCidr string
|
|
if p.OrchestratorProfile.IsAzureCNI() {
|
|
if p.MasterProfile != nil && p.MasterProfile.IsCustomVNET() {
|
|
nonMasqCidr = p.MasterProfile.VnetCidr
|
|
} else {
|
|
nonMasqCidr = DefaultVNETCIDR
|
|
}
|
|
} else {
|
|
if p.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack") {
|
|
cidr := strings.Split(p.OrchestratorProfile.KubernetesConfig.ClusterSubnet, ",")[0]
|
|
_, ipnet, _ := net.ParseCIDR(cidr)
|
|
nonMasqCidr = ipnet.String()
|
|
} else {
|
|
nonMasqCidr = p.OrchestratorProfile.KubernetesConfig.ClusterSubnet
|
|
}
|
|
}
|
|
return nonMasqCidr
|
|
}
|
|
|
|
// GetSecondaryNonMasqueradeCIDR returns second cidr in case of dualstack clusters
|
|
func (p *Properties) GetSecondaryNonMasqueradeCIDR() string {
|
|
var nonMasqCidr string
|
|
if p.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack") {
|
|
cidr := strings.Split(p.OrchestratorProfile.KubernetesConfig.ClusterSubnet, ",")[1]
|
|
_, ipnet, _ := net.ParseCIDR(cidr)
|
|
nonMasqCidr = ipnet.String()
|
|
}
|
|
return nonMasqCidr
|
|
}
|
|
|
|
// GetAzureCNICidr returns the default CNI Cidr if Azure CNI is enabled.
|
|
func (p *Properties) GetAzureCNICidr() string {
|
|
var masqCNIIP string
|
|
if p.OrchestratorProfile != nil && p.OrchestratorProfile.IsAzureCNI() {
|
|
masqCNIIP = DefaultCNICIDR
|
|
}
|
|
return masqCNIIP
|
|
}
|
|
|
|
// GetMasterFQDN returns the master FQDN.
|
|
func (p *Properties) GetMasterFQDN() string {
|
|
return p.MasterProfile.FQDN
|
|
}
|
|
|
|
// AnyAgentHasLoadBalancerBackendAddressPoolIDs returns true if any of the agent profiles contains LoadBalancerBackendAddressPoolIDs
|
|
func (p *Properties) AnyAgentHasLoadBalancerBackendAddressPoolIDs() bool {
|
|
for _, agentPoolProfile := range p.AgentPoolProfiles {
|
|
if agentPoolProfile.LoadBalancerBackendAddressPoolIDs != nil {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GetKubeProxyFeatureGates returns the feature gates string for the kube-proxy yaml manifest
|
|
func (p *Properties) GetKubeProxyFeatureGates() string {
|
|
if p.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack") {
|
|
return "IPv6DualStack: true"
|
|
}
|
|
return "{}"
|
|
}
|
|
|
|
// GetKubeProxyFeatureGatesWindowsArguments returns the feature gates string for the kube-proxy arguments in Windows nodes
|
|
func (p *Properties) GetKubeProxyFeatureGatesWindowsArguments() string {
|
|
featureGates := map[string]bool{}
|
|
|
|
if p.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack") {
|
|
featureGates["IPv6DualStack"] = true
|
|
}
|
|
if p.FeatureFlags.IsFeatureEnabled("EnableWinDSR") {
|
|
// WinOverlay must be set to false
|
|
featureGates["WinDSR"] = true
|
|
featureGates["WinOverlay"] = false
|
|
}
|
|
|
|
keys := []string{}
|
|
for key := range featureGates {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
var buf bytes.Buffer
|
|
for _, key := range keys {
|
|
buf.WriteString(fmt.Sprintf("\"%s=%t\", ", key, featureGates[key]))
|
|
}
|
|
return strings.TrimSuffix(buf.String(), ", ")
|
|
}
|
|
|
|
// 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 ""
|
|
}
|
|
|
|
func (p *Properties) NeedsAuditdRules() bool {
|
|
if p.MasterProfile != nil && p.MasterProfile.IsAuditDEnabled() {
|
|
return true
|
|
}
|
|
for _, pool := range p.AgentPoolProfiles {
|
|
if pool.IsAuditDEnabled() {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 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
|
|
}
|
|
// For Azure Stack Hub clusters, azuredisk-csi driver will not be enabled by default when cloud-controller-manager is enabled due to custom data oversize
|
|
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")
|
|
}
|
|
|
|
// IsValid returns true if ImageRefernce contains at least Name and ResourceGroup
|
|
func (i *ImageReference) IsValid() bool {
|
|
return len(i.Name) > 0 && len(i.ResourceGroup) > 0
|
|
}
|
|
|
|
// IsGalleryImage returns true if ImageRefernce contains Gallry, Name, ResourceGroup, SubscriptionID, and Version
|
|
func (i *ImageReference) IsGalleryImage() bool {
|
|
return len(i.Gallery) > 0 && len(i.Name) > 0 && len(i.ResourceGroup) > 0 && len(i.SubscriptionID) > 0 && len(i.Version) > 0
|
|
}
|
|
|
|
// HasImageRef returns true if the customer brought os image
|
|
func (m *MasterProfile) HasImageRef() bool {
|
|
return m.ImageRef != nil && m.ImageRef.IsValid()
|
|
}
|
|
|
|
// HasImageGallery returns true if the customer brought os image from Shared Image Gallery
|
|
func (m *MasterProfile) HasImageGallery() bool {
|
|
return m.ImageRef != nil && m.ImageRef.IsGalleryImage()
|
|
}
|
|
|
|
// IsCustomVNET returns true if the customer brought their own VNET
|
|
func (m *MasterProfile) IsCustomVNET() bool {
|
|
return len(m.VnetSubnetID) > 0
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// IsVHDDistro returns true if the distro uses VHD SKUs
|
|
func (m *MasterProfile) IsVHDDistro() bool {
|
|
return m.Distro == AKSUbuntu1604 || m.Distro == AKSUbuntu1804 || m.Distro == AKSUbuntu2004
|
|
}
|
|
|
|
// IsAuditDEnabled returns true if the master profile is configured for auditd
|
|
func (m *MasterProfile) IsAuditDEnabled() bool {
|
|
return to.Bool(m.AuditDEnabled)
|
|
}
|
|
|
|
// IsVirtualMachineScaleSets returns true if the master availability profile is VMSS
|
|
func (m *MasterProfile) IsVirtualMachineScaleSets() bool {
|
|
return m.AvailabilityProfile == VirtualMachineScaleSets
|
|
}
|
|
|
|
// IsAvailabilitySet returns true if the master availability profile is availability set
|
|
func (m *MasterProfile) IsAvailabilitySet() bool {
|
|
return m.AvailabilityProfile == AvailabilitySet
|
|
}
|
|
|
|
// GetFirstConsecutiveStaticIPAddress returns the first static IP address of the given subnet.
|
|
func (m *MasterProfile) GetFirstConsecutiveStaticIPAddress(subnetStr string) string {
|
|
_, subnet, err := net.ParseCIDR(subnetStr)
|
|
if err != nil {
|
|
return DefaultFirstConsecutiveKubernetesStaticIP
|
|
}
|
|
|
|
// Find the first and last octet of the host bits.
|
|
ones, bits := subnet.Mask.Size()
|
|
firstOctet := ones / 8
|
|
lastOctet := bits/8 - 1
|
|
|
|
if m.IsVirtualMachineScaleSets() {
|
|
subnet.IP[lastOctet] = DefaultKubernetesFirstConsecutiveStaticIPOffsetVMSS
|
|
} else {
|
|
// Set the remaining host bits in the first octet.
|
|
subnet.IP[firstOctet] |= (1 << byte((8 - (ones % 8)))) - 1
|
|
|
|
// Fill the intermediate octets with 1s and last octet with offset. This is done so to match
|
|
// the existing behavior of allocating static IP addresses from the last /24 of the subnet.
|
|
for i := firstOctet + 1; i < lastOctet; i++ {
|
|
subnet.IP[i] = 255
|
|
}
|
|
subnet.IP[lastOctet] = DefaultKubernetesFirstConsecutiveStaticIPOffset
|
|
}
|
|
|
|
return subnet.IP.String()
|
|
}
|
|
|
|
// HasAvailabilityZones returns true if the master profile has availability zones
|
|
func (m *MasterProfile) HasAvailabilityZones() bool {
|
|
return m.AvailabilityZones != nil && len(m.AvailabilityZones) > 0
|
|
}
|
|
|
|
// 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 master profile distro is based on Ubuntu 20.04
|
|
func (m *MasterProfile) IsUbuntu2004() bool {
|
|
switch m.Distro {
|
|
case AKSUbuntu2004, Ubuntu2004, Ubuntu2004Gen2:
|
|
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()
|
|
}
|
|
|
|
// IsUbuntuNonVHD returns true if the distro uses a base Ubuntu image
|
|
func (m *MasterProfile) IsUbuntuNonVHD() bool {
|
|
return m.IsUbuntu() && !m.IsVHDDistro()
|
|
}
|
|
|
|
// HasMultipleNodes returns true if there are more than one master nodes
|
|
func (m *MasterProfile) HasMultipleNodes() bool {
|
|
return m.Count > 1
|
|
}
|
|
|
|
// HasCosmosEtcd returns true if cosmos etcd configuration is enabled
|
|
func (m *MasterProfile) HasCosmosEtcd() bool {
|
|
return to.Bool(m.CosmosEtcd)
|
|
}
|
|
|
|
// GetCosmosEndPointURI returns the URI string for the cosmos etcd endpoint
|
|
func (m *MasterProfile) GetCosmosEndPointURI() string {
|
|
if m.HasCosmosEtcd() {
|
|
return fmt.Sprintf(etcdEndpointURIFmt, m.DNSPrefix)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// HasImageRef returns true if the customer brought os image
|
|
func (a *AgentPoolProfile) HasImageRef() bool {
|
|
imageRef := a.ImageRef
|
|
return imageRef != nil && imageRef.IsValid()
|
|
}
|
|
|
|
// HasImageGallery returns true if the customer brought os image from Shared Image Gallery
|
|
func (a *AgentPoolProfile) HasImageGallery() bool {
|
|
imageRef := a.ImageRef
|
|
return imageRef != nil && imageRef.IsGalleryImage()
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// IsVHDDistro returns true if the distro uses VHD SKUs
|
|
func (a *AgentPoolProfile) IsVHDDistro() bool {
|
|
return a.Distro == AKSUbuntu1604 || a.Distro == AKSUbuntu1804 || a.Distro == AKSUbuntu2004
|
|
}
|
|
|
|
// IsAuditDEnabled returns true if the master profile is configured for auditd
|
|
func (a *AgentPoolProfile) IsAuditDEnabled() bool {
|
|
return to.Bool(a.AuditDEnabled)
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// IsLowPriorityScaleSet returns true if the VMSS is Low Priority
|
|
func (a *AgentPoolProfile) IsLowPriorityScaleSet() bool {
|
|
return a.AvailabilityProfile == VirtualMachineScaleSets && a.ScaleSetPriority == ScaleSetPriorityLow
|
|
}
|
|
|
|
// IsSpotScaleSet returns true if the VMSS is Spot Scale Set
|
|
func (a *AgentPoolProfile) IsSpotScaleSet() bool {
|
|
return a.AvailabilityProfile == VirtualMachineScaleSets && a.ScaleSetPriority == ScaleSetPrioritySpot
|
|
}
|
|
|
|
// IsManagedDisks returns true if the customer specified disks
|
|
func (a *AgentPoolProfile) IsManagedDisks() bool {
|
|
return a.StorageProfile == ManagedDisks
|
|
}
|
|
|
|
// IsStorageAccount returns true if the customer specified storage account
|
|
func (a *AgentPoolProfile) IsStorageAccount() bool {
|
|
return a.StorageProfile == StorageAccount
|
|
}
|
|
|
|
// IsStorageAccount returns true if the customer specified ephemeral disks
|
|
func (a *AgentPoolProfile) IsEphemeral() bool {
|
|
return a.StorageProfile == Ephemeral
|
|
}
|
|
|
|
// HasDisks returns true if the customer specified disks
|
|
func (a *AgentPoolProfile) HasDisks() bool {
|
|
return len(a.DiskSizesGB) > 0
|
|
}
|
|
|
|
// HasAvailabilityZones returns true if the agent pool has availability zones
|
|
func (a *AgentPoolProfile) HasAvailabilityZones() bool {
|
|
return a.AvailabilityZones != nil && 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, Ubuntu2004Gen2:
|
|
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()
|
|
}
|
|
|
|
// IsUbuntuNonVHD returns true if the distro uses a base Ubuntu image
|
|
func (a *AgentPoolProfile) IsUbuntuNonVHD() bool {
|
|
return a.IsUbuntu() && !a.IsVHDDistro()
|
|
}
|
|
|
|
// RequiresCloudproviderConfig returns true if the azure.json cloudprovider config should be delivered to the nodes in this pool
|
|
func (a *AgentPoolProfile) RequiresCloudproviderConfig() bool {
|
|
if a.KubernetesConfig != nil && a.KubernetesConfig.KubeletConfig != nil {
|
|
if v, ok := a.KubernetesConfig.KubeletConfig["--cloud-provider"]; ok {
|
|
if v != "" {
|
|
return true
|
|
}
|
|
} else {
|
|
return true
|
|
}
|
|
if v, ok := a.KubernetesConfig.KubeletConfig["--cloud-config"]; ok {
|
|
if v != "" {
|
|
return true
|
|
}
|
|
} else {
|
|
return true
|
|
}
|
|
if v, ok := a.KubernetesConfig.KubeletConfig["--azure-container-registry-config"]; ok {
|
|
if v != "" {
|
|
return true
|
|
}
|
|
} else {
|
|
return true
|
|
}
|
|
} else {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GetKubernetesLabels returns a k8s API-compliant labels string for nodes in this profile
|
|
func (a *AgentPoolProfile) GetKubernetesLabels(rg string, deprecated bool) string {
|
|
var buf bytes.Buffer
|
|
buf.WriteString("kubernetes.azure.com/role=agent")
|
|
if deprecated {
|
|
buf.WriteString(",node-role.kubernetes.io/agent=")
|
|
buf.WriteString(",kubernetes.io/role=agent")
|
|
}
|
|
buf.WriteString(fmt.Sprintf(",agentpool=%s", a.Name))
|
|
if a.StorageProfile == ManagedDisks {
|
|
storagetier, _ := common.GetStorageAccountType(a.VMSize)
|
|
buf.WriteString(fmt.Sprintf(",storageprofile=managed,storagetier=%s", storagetier))
|
|
}
|
|
if common.IsNvidiaEnabledSKU(a.VMSize) {
|
|
accelerator := "nvidia"
|
|
buf.WriteString(fmt.Sprintf(",accelerator=%s", accelerator))
|
|
}
|
|
buf.WriteString(fmt.Sprintf(",kubernetes.azure.com/cluster=%s", rg))
|
|
keys := []string{}
|
|
for key := range a.CustomNodeLabels {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
for _, key := range keys {
|
|
buf.WriteString(fmt.Sprintf(",%s=%s", key, a.CustomNodeLabels[key]))
|
|
}
|
|
return buf.String()
|
|
}
|
|
|
|
// IsVHDDistro returns true if the distro uses VHD SKUs
|
|
func (w *WindowsProfile) IsVHDDistro() bool {
|
|
return w.WindowsPublisher == AKSWindowsServer2019OSImageConfig.ImagePublisher && w.WindowsOffer == AKSWindowsServer2019OSImageConfig.ImageOffer
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// HasSecrets returns true if the customer specified secrets to install
|
|
func (w *WindowsProfile) HasSecrets() bool {
|
|
return len(w.Secrets) > 0
|
|
}
|
|
|
|
// HasCustomImage returns true if there is a custom windows os image url specified
|
|
func (w *WindowsProfile) HasCustomImage() bool {
|
|
return len(w.WindowsImageSourceURL) > 0
|
|
}
|
|
|
|
// HasImageRef returns true if the customer brought os image
|
|
func (w *WindowsProfile) HasImageRef() bool {
|
|
return w.ImageRef != nil && w.ImageRef.IsValid()
|
|
}
|
|
|
|
// HasImageGallery returns true if the customer brought os image from Shared Image Gallery
|
|
func (w *WindowsProfile) HasImageGallery() bool {
|
|
return w.ImageRef != nil && w.ImageRef.IsGalleryImage()
|
|
}
|
|
|
|
// GetWindowsDockerVersion gets the docker version specified or returns default value
|
|
func (w *WindowsProfile) GetWindowsDockerVersion() string {
|
|
if w.WindowsDockerVersion != "" {
|
|
return w.WindowsDockerVersion
|
|
}
|
|
return KubernetesWindowsDockerVersion
|
|
}
|
|
|
|
// GetWindowsDefaultRuntimeHandler get the default containerd runtime handler or return default value
|
|
func (w *WindowsProfile) GetWindowsDefaultRuntimeHandler() string {
|
|
if w.WindowsRuntimes != nil && w.WindowsRuntimes.Default != "" {
|
|
return w.WindowsRuntimes.Default
|
|
}
|
|
|
|
return KubernetesDefaultWindowsRuntimeHandler
|
|
}
|
|
|
|
// GetWindowsHypervRuntimeHandlers gets comma separated list of runtimehandler names
|
|
func (w *WindowsProfile) GetWindowsHypervRuntimeHandlers() string {
|
|
if w.WindowsRuntimes != nil && len(w.WindowsRuntimes.HypervRuntimes) > 0 {
|
|
handlernames := []string{}
|
|
for _, h := range w.WindowsRuntimes.HypervRuntimes {
|
|
handlernames = append(handlernames, h.BuildNumber)
|
|
}
|
|
return strings.Join(handlernames, ",")
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// GetWindowsSku gets the marketplace sku specified (such as Datacenter-Core-1809-with-Containers-smalldisk) or returns default value
|
|
func (w *WindowsProfile) GetWindowsSku() string {
|
|
if w.WindowsSku != "" {
|
|
return w.WindowsSku
|
|
}
|
|
return KubernetesDefaultWindowsSku
|
|
}
|
|
|
|
// GetSSHEnabled gets it ssh should be enabled for Windows nodes
|
|
func (w *WindowsProfile) GetSSHEnabled() bool {
|
|
if w.SSHEnabled != nil {
|
|
return *w.SSHEnabled
|
|
}
|
|
return DefaultWindowsSSHEnabled
|
|
}
|
|
|
|
// GetEnableWindowsUpdate gets the flag for enable windows update or returns the default value
|
|
func (w *WindowsProfile) GetEnableWindowsUpdate() bool {
|
|
if w.EnableAutomaticUpdates != nil {
|
|
return *w.EnableAutomaticUpdates
|
|
}
|
|
return DefaultEnableAutomaticUpdates
|
|
}
|
|
|
|
// GetIsCredentialAutoGenerated gets the flag to indicate whether the WindowsProfile is auto generated or returns the default value
|
|
func (w *WindowsProfile) GetIsCredentialAutoGenerated() bool {
|
|
if w.IsCredentialAutoGenerated != nil {
|
|
return *w.IsCredentialAutoGenerated
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GetEnableAHUB returns true if AHUB should be enabled for Windows nodes
|
|
func (w *WindowsProfile) GetEnableAHUB() bool {
|
|
if w.EnableAHUB != nil {
|
|
return *w.EnableAHUB
|
|
}
|
|
return false
|
|
}
|
|
|
|
// HasEnableAHUB returns true if EnableAHUB is not nil
|
|
func (w *WindowsProfile) HasEnableAHUB() bool {
|
|
return w.EnableAHUB != nil
|
|
}
|
|
|
|
// HasSecrets returns true if the customer specified secrets to install
|
|
func (l *LinuxProfile) HasSecrets() bool {
|
|
return len(l.Secrets) > 0
|
|
}
|
|
|
|
// 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 a dns server
|
|
func (l *LinuxProfile) HasCustomNodesDNS() bool {
|
|
if l.CustomNodesDNS != nil {
|
|
if l.CustomNodesDNS.DNSServer != "" {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsAzureCNI returns true if Azure CNI network plugin is enabled
|
|
func (o *OrchestratorProfile) IsAzureCNI() bool {
|
|
if o.KubernetesConfig != nil {
|
|
return o.KubernetesConfig.NetworkPlugin == NetworkPluginAzure
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsPrivateCluster returns true if this deployment is a private cluster
|
|
func (o *OrchestratorProfile) IsPrivateCluster() bool {
|
|
return o.KubernetesConfig != nil && o.KubernetesConfig.PrivateCluster != nil && to.Bool(o.KubernetesConfig.PrivateCluster.Enabled)
|
|
}
|
|
|
|
// IsHostsConfigAgentEnabled returns true if hosts config agent is enabled
|
|
func (o *OrchestratorProfile) IsHostsConfigAgentEnabled() bool {
|
|
return o.KubernetesConfig != nil && o.KubernetesConfig.PrivateCluster != nil && to.Bool(o.KubernetesConfig.PrivateCluster.EnableHostsConfigAgent)
|
|
}
|
|
|
|
// GetPodInfraContainerSpec returns the sandbox image as a string (ex: registry.k8s.io/pause-amd64:3.1)
|
|
func (o *OrchestratorProfile) GetPodInfraContainerSpec() string {
|
|
return o.KubernetesConfig.MCRKubernetesImageBase + GetK8sComponentsByVersionMap(o.KubernetesConfig)[o.OrchestratorVersion][common.PauseComponentName]
|
|
}
|
|
|
|
// HasAadProfile returns true if the has aad profile
|
|
func (p *Properties) HasAadProfile() bool {
|
|
return p.AADProfile != nil
|
|
}
|
|
|
|
// GetAPIServerEtcdAPIVersion Used to set apiserver's etcdapi version
|
|
func (o *OrchestratorProfile) GetAPIServerEtcdAPIVersion() string {
|
|
if o.KubernetesConfig != nil {
|
|
// if we are here, version has already been validated..
|
|
etcdVersion, _ := semver.Make(o.KubernetesConfig.EtcdVersion)
|
|
return "etcd" + strconv.FormatUint(etcdVersion.Major, 10)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// GetAddonScript retrieves the raw script data specified as input for the k8s addon with name "addonName".
|
|
func (k *KubernetesConfig) GetAddonScript(addonName string) string {
|
|
kubeAddon := k.GetAddonByName(addonName)
|
|
return kubeAddon.Data
|
|
}
|
|
|
|
// 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 {
|
|
kubeAddon := k.GetAddonByName(addonName)
|
|
return kubeAddon.IsEnabled()
|
|
}
|
|
|
|
// IsAddonDisabled checks whether a k8s addon with name "addonName" is explicitly disabled based on the Enabled field of KubernetesAddon.
|
|
// If the value of Enabled is nil, we return false (not explicitly disabled)
|
|
func (k *KubernetesConfig) IsAddonDisabled(addonName string) bool {
|
|
kubeAddon := k.GetAddonByName(addonName)
|
|
return kubeAddon.IsDisabled()
|
|
}
|
|
|
|
// IsAADPodIdentityEnabled checks if the AAD pod identity addon is enabled
|
|
func (k *KubernetesConfig) IsAADPodIdentityEnabled() bool {
|
|
return k.IsAddonEnabled(common.AADPodIdentityAddonName)
|
|
}
|
|
|
|
// IsContainerMonitoringAddonEnabled checks if the container monitoring addon is enabled
|
|
func (k *KubernetesConfig) IsContainerMonitoringAddonEnabled() bool {
|
|
return k.IsAddonEnabled(common.ContainerMonitoringAddonName)
|
|
}
|
|
|
|
// IsClusterAutoscalerEnabled checks if the cluster autoscaler addon is enabled
|
|
func (k *KubernetesConfig) IsClusterAutoscalerEnabled() bool {
|
|
return k.IsAddonEnabled(common.ClusterAutoscalerAddonName)
|
|
}
|
|
|
|
// IsAzurePolicyEnabled checks if the azure policy addon is enabled
|
|
func (k *KubernetesConfig) IsAzurePolicyEnabled() bool {
|
|
return k.IsAddonEnabled(common.AzurePolicyAddonName)
|
|
}
|
|
|
|
// IsAppGWIngressEnabled checks if the appgw ingress addon is enabled
|
|
func (k *KubernetesConfig) IsAppGWIngressEnabled() bool {
|
|
return k.IsAddonEnabled(common.AppGwIngressAddonName)
|
|
}
|
|
|
|
// GetComponentByName returns the KubernetesComponent object with name `componentName`
|
|
func (k *KubernetesConfig) GetComponentByName(componentName string) KubernetesComponent {
|
|
var component KubernetesComponent
|
|
for _, c := range k.Components {
|
|
if c.Name == componentName {
|
|
component = c
|
|
break
|
|
}
|
|
}
|
|
return component
|
|
}
|
|
|
|
// GetComponentData retrieves the raw data specified as input for a component with name "componentName".
|
|
func (k *KubernetesConfig) GetComponentData(componentName string) string {
|
|
component := k.GetComponentByName(componentName)
|
|
return component.Data
|
|
}
|
|
|
|
// IsComponentEnabled checks whether a component with name "componentName" is enabled or not based on the Enabled field of KubernetesComponent.
|
|
// If the value of Enabled is nil, the "defaultValue" is returned.
|
|
func (k *KubernetesConfig) IsComponentEnabled(componentName string) (KubernetesComponent, bool) {
|
|
component := k.GetComponentByName(componentName)
|
|
return component, component.IsEnabled()
|
|
}
|
|
|
|
// IsRBACEnabled checks if RBAC is enabled
|
|
func (k *KubernetesConfig) IsRBACEnabled() bool {
|
|
if k.EnableRbac != nil {
|
|
return to.Bool(k.EnableRbac)
|
|
}
|
|
return false
|
|
}
|
|
|
|
// UserAssignedIDEnabled checks if the user assigned ID is enabled or not.
|
|
func (k *KubernetesConfig) UserAssignedIDEnabled() bool {
|
|
return to.Bool(k.UseManagedIdentity) && k.UserAssignedID != ""
|
|
}
|
|
|
|
// SystemAssignedIDEnabled checks if system assigned IDs should be used.
|
|
func (k *KubernetesConfig) SystemAssignedIDEnabled() bool {
|
|
return to.Bool(k.UseManagedIdentity) && k.UserAssignedID == ""
|
|
}
|
|
|
|
func (k *KubernetesConfig) ShouldCreateNewUserAssignedIdentity() bool {
|
|
return !(k.UserAssignedIDEnabled() && strings.Contains(k.UserAssignedID, "/"))
|
|
}
|
|
|
|
// GetOrderedKubeletConfigString returns an ordered string of key/val pairs
|
|
func (k *KubernetesConfig) GetOrderedKubeletConfigString() string {
|
|
keys := []string{}
|
|
for key := range k.KubeletConfig {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
var buf bytes.Buffer
|
|
for _, key := range keys {
|
|
buf.WriteString(fmt.Sprintf("%s=%s ", key, k.KubeletConfig[key]))
|
|
}
|
|
return buf.String()
|
|
}
|
|
|
|
// GetOrderedKubeletConfigStringForPowershell returns an ordered string of key/val pairs for Powershell script consumption
|
|
func (k *KubernetesConfig) GetOrderedKubeletConfigStringForPowershell() string {
|
|
keys := []string{}
|
|
for key := range k.KubeletConfig {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
var buf bytes.Buffer
|
|
for _, key := range keys {
|
|
buf.WriteString(fmt.Sprintf("\"%s=%s\", ", key, k.KubeletConfig[key]))
|
|
}
|
|
return strings.TrimSuffix(buf.String(), ", ")
|
|
}
|
|
|
|
// NeedsContainerd returns whether or not we need the containerd runtime configuration
|
|
func (k *KubernetesConfig) NeedsContainerd() bool {
|
|
return k.ContainerRuntime == Containerd
|
|
}
|
|
|
|
// IsNSeriesSKU returns true if the agent pool contains an N-series (NVIDIA GPU) VM
|
|
func (a *AgentPoolProfile) IsNSeriesSKU() bool {
|
|
return common.IsNvidiaEnabledSKU(a.VMSize)
|
|
}
|
|
|
|
// HasNSeriesSKU returns whether or not there is an N series SKU agent pool
|
|
func (p *Properties) HasNSeriesSKU() bool {
|
|
for _, profile := range p.AgentPoolProfiles {
|
|
if strings.Contains(profile.VMSize, "Standard_N") {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// HasDCSeriesSKU returns whether or not there is an DC series SKU agent pool
|
|
func (p *Properties) HasDCSeriesSKU() bool {
|
|
for _, profile := range p.AgentPoolProfiles {
|
|
if strings.Contains(profile.VMSize, "Standard_DC") {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsNVIDIADevicePluginEnabled checks if the NVIDIA Device Plugin addon is enabled
|
|
// It is enabled by default if agents contain a GPU and Kubernetes version is >= 1.10.0
|
|
func (p *Properties) IsNVIDIADevicePluginEnabled() bool {
|
|
if p.OrchestratorProfile == nil || p.OrchestratorProfile.KubernetesConfig == nil {
|
|
return false
|
|
}
|
|
return p.OrchestratorProfile.KubernetesConfig.IsAddonEnabled(common.NVIDIADevicePluginAddonName)
|
|
}
|
|
|
|
// IsCustomCloudProfile returns 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 ""
|
|
}
|
|
|
|
// GetKubernetesVersion returns the cluster Kubernetes version, with the Azure Stack suffix if Azure Stack Cloud.
|
|
func (p *Properties) GetKubernetesVersion() string {
|
|
if p.IsAzureStackCloud() && !common.IsKubernetesVersionGe(p.OrchestratorProfile.OrchestratorVersion, "1.21.0") {
|
|
return p.OrchestratorProfile.OrchestratorVersion + AzureStackSuffix
|
|
}
|
|
return p.OrchestratorProfile.OrchestratorVersion
|
|
}
|
|
|
|
// GetKubernetesHyperkubeSpec returns the string to use for the Kubernetes hyperkube image.
|
|
func (p *Properties) GetKubernetesHyperkubeSpec() string {
|
|
var kubernetesHyperkubeSpec string
|
|
k8sComponents := GetK8sComponentsByVersionMap(p.OrchestratorProfile.KubernetesConfig)[p.OrchestratorProfile.OrchestratorVersion]
|
|
kubernetesHyperkubeSpec = p.OrchestratorProfile.KubernetesConfig.KubernetesImageBase + k8sComponents["hyperkube"]
|
|
if p.IsAzureStackCloud() && !common.IsKubernetesVersionGe(p.OrchestratorProfile.OrchestratorVersion, "1.21.0") {
|
|
kubernetesHyperkubeSpec = kubernetesHyperkubeSpec + AzureStackSuffix
|
|
}
|
|
if p.OrchestratorProfile.KubernetesConfig.CustomHyperkubeImage != "" {
|
|
kubernetesHyperkubeSpec = p.OrchestratorProfile.KubernetesConfig.CustomHyperkubeImage
|
|
}
|
|
return kubernetesHyperkubeSpec
|
|
}
|
|
|
|
// 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"))
|
|
}
|
|
|
|
// GetCustomEnvironmentJSON return the JSON format string for custom environment
|
|
func (p *Properties) GetCustomEnvironmentJSON(escape bool) (string, error) {
|
|
var environmentJSON string
|
|
if p.IsCustomCloudProfile() {
|
|
bytes, err := json.Marshal(p.CustomCloudProfile.Environment)
|
|
if err != nil {
|
|
return "", fmt.Errorf("Could not serialize Environment object - %s", err.Error())
|
|
}
|
|
environmentJSON = string(bytes)
|
|
if escape {
|
|
environmentJSON = strings.Replace(environmentJSON, "\"", "\\\"", -1)
|
|
}
|
|
}
|
|
return environmentJSON, nil
|
|
}
|
|
|
|
// GetCustomCloudName returns name of environment if customCloudProfile is provided, returns empty string if customCloudProfile is empty.
|
|
// Because customCloudProfile is empty for deployment is AzurePublicCloud, AzureChinaCloud,AzureGermanCloud,AzureUSGovernmentCloud,
|
|
// the return value will be empty string for those clouds
|
|
func (p *Properties) GetCustomCloudName() string {
|
|
var cloudProfileName string
|
|
if p.IsCustomCloudProfile() {
|
|
cloudProfileName = p.CustomCloudProfile.Environment.Name
|
|
}
|
|
return cloudProfileName
|
|
}
|
|
|
|
// GetLocations returns all supported regions.
|
|
// If AzureStackCloud, GetLocations provides the location of container service
|
|
// If AzurePublicCloud, AzureChinaCloud,AzureGermanCloud or AzureUSGovernmentCloud, GetLocations provides all azure regions in prod.
|
|
func (cs *ContainerService) GetLocations() []string {
|
|
var allLocations []string
|
|
if cs.Properties.IsCustomCloudProfile() {
|
|
allLocations = []string{cs.Location}
|
|
} else {
|
|
allLocations = helpers.GetAzureLocations()
|
|
}
|
|
return allLocations
|
|
}
|
|
|
|
// GetCustomCloudAuthenticationMethod returns authentication method which k8s azure cloud provider will use
|
|
// For AzurePublicCloud,AzureChinaCloud,azureGermanCloud,AzureUSGovernmentCloud, it will be always be client_secret
|
|
// For AzureStackCloud, if it is specified in configuration, the value will be used, if not ,the default value is client_secret.
|
|
func (p *Properties) GetCustomCloudAuthenticationMethod() string {
|
|
if p.IsCustomCloudProfile() {
|
|
return p.CustomCloudProfile.AuthenticationMethod
|
|
}
|
|
return ClientSecretAuthMethod
|
|
}
|
|
|
|
// GetCustomCloudIdentitySystem returns identity system method for azure stack.
|
|
// For AzurePublicCloud,AzureChinaCloud,azureGermanCloud,AzureUSGovernmentCloud, it will be always be AzureAD
|
|
// For AzureStackCloud, if it is specified in configuration, the value will be used, if not ,the default value is AzureAD.
|
|
func (p *Properties) GetCustomCloudIdentitySystem() string {
|
|
if p.IsCustomCloudProfile() {
|
|
return p.CustomCloudProfile.IdentitySystem
|
|
}
|
|
return AzureADIdentitySystem
|
|
}
|
|
|
|
// IsNvidiaDevicePluginCapable determines if the cluster definition is compatible with the nvidia-device-plugin daemonset
|
|
func (p *Properties) IsNvidiaDevicePluginCapable() bool {
|
|
return p.HasNSeriesSKU()
|
|
}
|
|
|
|
// IsAzureCNIDualStack determines if azure cni dual stack is enabled
|
|
func (p *Properties) IsAzureCNIDualStack() bool {
|
|
o := p.OrchestratorProfile
|
|
f := p.FeatureFlags
|
|
return o.IsAzureCNI() && f.IsFeatureEnabled("EnableIPv6DualStack")
|
|
}
|
|
|
|
// RequireRouteTable returns true if this deployment requires routing table
|
|
func (p *Properties) RequireRouteTable() bool {
|
|
o := p.OrchestratorProfile
|
|
f := p.FeatureFlags
|
|
switch o.OrchestratorType {
|
|
case Kubernetes:
|
|
if o.IsAzureCNI() && !f.IsFeatureEnabled("EnableIPv6DualStack") ||
|
|
NetworkPolicyCilium == o.KubernetesConfig.NetworkPolicy ||
|
|
"flannel" == o.KubernetesConfig.NetworkPlugin ||
|
|
NetworkPluginAntrea == o.KubernetesConfig.NetworkPlugin {
|
|
return false
|
|
}
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// SetCloudProviderRateLimitDefaults sets default cloudprovider rate limiter config
|
|
func (p *Properties) SetCloudProviderRateLimitDefaults() {
|
|
if p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucket == 0 {
|
|
var agentPoolProfilesCount = len(p.AgentPoolProfiles)
|
|
if agentPoolProfilesCount == 0 {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucket = DefaultKubernetesCloudProviderRateLimitBucket
|
|
} else {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucket = agentPoolProfilesCount * common.MaxAgentCount
|
|
}
|
|
if p.IsAzureStackCloud() {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucket = DefaultAzureStackKubernetesCloudProviderRateLimitBucket
|
|
}
|
|
}
|
|
if p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitQPS == 0 {
|
|
if (DefaultKubernetesCloudProviderRateLimitQPS / float64(p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucket)) < common.MinCloudProviderQPSToBucketFactor {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitQPS = float64(p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucket) * common.MinCloudProviderQPSToBucketFactor
|
|
} else {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitQPS = DefaultKubernetesCloudProviderRateLimitQPS
|
|
}
|
|
if p.IsAzureStackCloud() {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitQPS = DefaultAzureStackKubernetesCloudProviderRateLimitQPS
|
|
}
|
|
}
|
|
if p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucketWrite == 0 {
|
|
var agentPoolProfilesCount = len(p.AgentPoolProfiles)
|
|
if agentPoolProfilesCount == 0 {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucketWrite = DefaultKubernetesCloudProviderRateLimitBucketWrite
|
|
} else {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucketWrite = agentPoolProfilesCount * common.MaxAgentCount
|
|
}
|
|
if p.IsAzureStackCloud() {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucketWrite = DefaultAzureStackKubernetesCloudProviderRateLimitBucketWrite
|
|
}
|
|
}
|
|
if p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitQPSWrite == 0 {
|
|
if (DefaultKubernetesCloudProviderRateLimitQPSWrite / float64(p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucketWrite)) < common.MinCloudProviderQPSToBucketFactor {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitQPSWrite = float64(p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitBucketWrite) * common.MinCloudProviderQPSToBucketFactor
|
|
} else {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitQPSWrite = DefaultKubernetesCloudProviderRateLimitQPSWrite
|
|
}
|
|
if p.IsAzureStackCloud() {
|
|
p.OrchestratorProfile.KubernetesConfig.CloudProviderRateLimitQPSWrite = DefaultAzureStackKubernetesCloudProviderRateLimitQPSWrite
|
|
}
|
|
}
|
|
}
|
|
|
|
// PrivateJumpboxProvision checks if a private cluster has jumpbox auto-provisioning
|
|
func (k *KubernetesConfig) PrivateJumpboxProvision() bool {
|
|
if k != nil && k.PrivateCluster != nil && *k.PrivateCluster.Enabled && k.PrivateCluster.JumpboxProfile != nil {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// RequiresDocker returns if the kubernetes settings require docker binary to be installed.
|
|
func (k *KubernetesConfig) RequiresDocker() bool {
|
|
if k == nil {
|
|
return false
|
|
}
|
|
|
|
runtime := strings.ToLower(k.ContainerRuntime)
|
|
return runtime == Docker || runtime == ""
|
|
}
|
|
|
|
// SetCloudProviderBackoffDefaults sets default cloudprovider backoff config
|
|
func (p *Properties) SetCloudProviderBackoffDefaults() {
|
|
k := p.OrchestratorProfile.KubernetesConfig
|
|
if k.CloudProviderBackoffDuration == 0 {
|
|
k.CloudProviderBackoffDuration = DefaultKubernetesCloudProviderBackoffDuration
|
|
if p.IsAzureStackCloud() {
|
|
k.CloudProviderBackoffDuration = DefaultAzureStackKubernetesCloudProviderBackoffDuration
|
|
}
|
|
}
|
|
if k.CloudProviderBackoffRetries == 0 {
|
|
k.CloudProviderBackoffRetries = DefaultKubernetesCloudProviderBackoffRetries
|
|
if p.IsAzureStackCloud() {
|
|
k.CloudProviderBackoffRetries = DefaultAzureStackKubernetesCloudProviderBackoffRetries
|
|
}
|
|
}
|
|
if k.CloudProviderBackoffMode != CloudProviderBackoffModeV2 {
|
|
if k.CloudProviderBackoffExponent == 0 {
|
|
k.CloudProviderBackoffExponent = DefaultKubernetesCloudProviderBackoffExponent
|
|
if p.IsAzureStackCloud() {
|
|
k.CloudProviderBackoffExponent = DefaultAzureStackKubernetesCloudProviderBackoffExponent
|
|
}
|
|
}
|
|
if k.CloudProviderBackoffJitter == 0 {
|
|
k.CloudProviderBackoffJitter = DefaultKubernetesCloudProviderBackoffJitter
|
|
if p.IsAzureStackCloud() {
|
|
k.CloudProviderBackoffJitter = DefaultAzureStackKubernetesCloudProviderBackoffJitter
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetAzureCNIURLLinux returns the full URL to source Azure CNI binaries from
|
|
func (k *KubernetesConfig) GetAzureCNIURLLinux(cloudSpecConfig AzureEnvironmentSpecConfig) string {
|
|
if k.AzureCNIURLLinux != "" {
|
|
return k.AzureCNIURLLinux
|
|
}
|
|
return cloudSpecConfig.KubernetesSpecConfig.VnetCNILinuxPluginsDownloadURL
|
|
}
|
|
|
|
// GetAzureCNIURLWindows returns the full URL to source Azure CNI binaries from
|
|
func (k *KubernetesConfig) GetAzureCNIURLWindows(cloudSpecConfig AzureEnvironmentSpecConfig) string {
|
|
if k.AzureCNIURLWindows != "" {
|
|
return k.AzureCNIURLWindows
|
|
}
|
|
return cloudSpecConfig.KubernetesSpecConfig.VnetCNIWindowsPluginsDownloadURL
|
|
}
|
|
|
|
// IsFeatureEnabled returns true if a feature flag is on for the provided feature
|
|
func (f *FeatureFlags) IsFeatureEnabled(feature string) bool {
|
|
if f != nil {
|
|
switch feature {
|
|
case "CSERunInBackground":
|
|
return f.EnableCSERunInBackground
|
|
case "BlockOutboundInternet":
|
|
return f.BlockOutboundInternet
|
|
case "EnableIPv6DualStack":
|
|
return f.EnableIPv6DualStack
|
|
case "EnableTelemetry":
|
|
return f.EnableTelemetry
|
|
case "EnableIPv6Only":
|
|
return f.EnableIPv6Only
|
|
case "EnableWinDSR":
|
|
return f.EnableWinDSR
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GetCloudSpecConfig returns the Kubernetes container images URL configurations based on the deploy target environment.
|
|
// for example: if the target is the public azure, then the default container image url should be registry.k8s.io/...
|
|
// if the target is azure china, then the default container image should be mirror.azure.cn:5000/google_container/...
|
|
func (cs *ContainerService) GetCloudSpecConfig() AzureEnvironmentSpecConfig {
|
|
targetEnv := helpers.GetTargetEnv(cs.Location, cs.Properties.GetCustomCloudName())
|
|
return AzureCloudSpecEnvMap[targetEnv]
|
|
}
|
|
|
|
// IsAKSBillingEnabled checks if the AKS Billing Extension should be enabled for a cloud environment.
|
|
func (cs *ContainerService) IsAKSBillingEnabled() bool {
|
|
cloudSpecConfig := cs.GetCloudSpecConfig()
|
|
return cloudSpecConfig.CloudName == AzurePublicCloud || cloudSpecConfig.CloudName == AzureChinaCloud || cloudSpecConfig.CloudName == AzureUSGovernmentCloud
|
|
}
|
|
|
|
// GetAzureProdFQDN returns the formatted FQDN string for a given apimodel.
|
|
func (cs *ContainerService) GetAzureProdFQDN() string {
|
|
return FormatProdFQDNByLocation(cs.Properties.MasterProfile.DNSPrefix, cs.Location, cs.Properties.GetCustomCloudName())
|
|
}
|
|
|
|
// ProvisionScriptParametersInput is the struct used to pass in Azure environment variables and secrets
|
|
// as either values or ARM template variables when generating provision script parameters.
|
|
type ProvisionScriptParametersInput struct {
|
|
Location string
|
|
ResourceGroup string
|
|
TenantID string
|
|
SubscriptionID string
|
|
ClientID string
|
|
ClientSecret string
|
|
APIServerCertificate string
|
|
KubeletPrivateKey string
|
|
ClusterKeyVaultName string
|
|
}
|
|
|
|
// GetProvisionScriptParametersCommon returns the environment variables needed to run the Linux bootstrap scripts
|
|
// Ensure that the clientSecret parameter is surrounded by single quotes to protect against special characters
|
|
func (cs *ContainerService) GetProvisionScriptParametersCommon(input ProvisionScriptParametersInput) string {
|
|
cloudSpecConfig := cs.GetCloudSpecConfig()
|
|
kubernetesConfig := cs.Properties.OrchestratorProfile.KubernetesConfig
|
|
parameters := map[string]string{
|
|
"ADMINUSER": cs.Properties.LinuxProfile.AdminUsername,
|
|
"ETCD_DOWNLOAD_URL": cloudSpecConfig.KubernetesSpecConfig.EtcdDownloadURLBase,
|
|
"ETCD_VERSION": kubernetesConfig.EtcdVersion,
|
|
"CONTAINERD_VERSION": kubernetesConfig.ContainerdVersion,
|
|
"MOBY_VERSION": kubernetesConfig.MobyVersion,
|
|
"TENANT_ID": input.TenantID,
|
|
"KUBERNETES_VERSION": cs.Properties.GetKubernetesVersion(),
|
|
"HYPERKUBE_URL": cs.Properties.GetKubernetesHyperkubeSpec(),
|
|
"APISERVER_PUBLIC_KEY": input.APIServerCertificate,
|
|
"SUBSCRIPTION_ID": input.SubscriptionID,
|
|
"RESOURCE_GROUP": input.ResourceGroup,
|
|
"LOCATION": input.Location,
|
|
"VM_TYPE": cs.Properties.GetVMType(),
|
|
"SUBNET": cs.Properties.GetSubnetName(),
|
|
"NETWORK_SECURITY_GROUP": cs.Properties.GetNSGName(),
|
|
"VIRTUAL_NETWORK": cs.Properties.GetVirtualNetworkName(),
|
|
"VIRTUAL_NETWORK_RESOURCE_GROUP": cs.Properties.GetVNetResourceGroupName(),
|
|
"ROUTE_TABLE": cs.Properties.GetRouteTableName(),
|
|
"PRIMARY_AVAILABILITY_SET": cs.Properties.GetPrimaryAvailabilitySetName(),
|
|
"PRIMARY_SCALE_SET": cs.Properties.GetPrimaryScaleSetName(),
|
|
"SERVICE_PRINCIPAL_CLIENT_ID": input.ClientID,
|
|
"SERVICE_PRINCIPAL_CLIENT_SECRET": input.ClientSecret,
|
|
"KUBELET_PRIVATE_KEY": input.KubeletPrivateKey,
|
|
"NETWORK_PLUGIN": kubernetesConfig.NetworkPlugin,
|
|
"NETWORK_POLICY": kubernetesConfig.NetworkPolicy,
|
|
"VNET_CNI_PLUGINS_URL": kubernetesConfig.GetAzureCNIURLLinux(cloudSpecConfig),
|
|
"CNI_PLUGINS_URL": cloudSpecConfig.KubernetesSpecConfig.CNIPluginsDownloadURL,
|
|
"CLOUDPROVIDER_BACKOFF": strconv.FormatBool(to.Bool(kubernetesConfig.CloudProviderBackoff)),
|
|
"CLOUDPROVIDER_BACKOFF_MODE": kubernetesConfig.CloudProviderBackoffMode,
|
|
"CLOUDPROVIDER_BACKOFF_RETRIES": strconv.Itoa(kubernetesConfig.CloudProviderBackoffRetries),
|
|
"CLOUDPROVIDER_BACKOFF_EXPONENT": strconv.FormatFloat(kubernetesConfig.CloudProviderBackoffExponent, 'f', -1, 64),
|
|
"CLOUDPROVIDER_BACKOFF_DURATION": strconv.Itoa(kubernetesConfig.CloudProviderBackoffDuration),
|
|
"CLOUDPROVIDER_BACKOFF_JITTER": strconv.FormatFloat(kubernetesConfig.CloudProviderBackoffJitter, 'f', -1, 64),
|
|
"CLOUDPROVIDER_RATELIMIT": strconv.FormatBool(to.Bool(kubernetesConfig.CloudProviderRateLimit)),
|
|
"CLOUDPROVIDER_RATELIMIT_QPS": strconv.FormatFloat(kubernetesConfig.CloudProviderRateLimitQPS, 'f', -1, 64),
|
|
"CLOUDPROVIDER_RATELIMIT_QPS_WRITE": strconv.FormatFloat(kubernetesConfig.CloudProviderRateLimitQPSWrite, 'f', -1, 64),
|
|
"CLOUDPROVIDER_RATELIMIT_BUCKET": strconv.Itoa(kubernetesConfig.CloudProviderRateLimitBucket),
|
|
"CLOUDPROVIDER_RATELIMIT_BUCKET_WRITE": strconv.Itoa(kubernetesConfig.CloudProviderRateLimitBucketWrite),
|
|
"LOAD_BALANCER_DISABLE_OUTBOUND_SNAT": strconv.FormatBool(to.Bool(kubernetesConfig.CloudProviderDisableOutboundSNAT)),
|
|
"USE_MANAGED_IDENTITY_EXTENSION": strconv.FormatBool(to.Bool(kubernetesConfig.UseManagedIdentity)),
|
|
"USE_INSTANCE_METADATA": strconv.FormatBool(to.Bool(kubernetesConfig.UseInstanceMetadata)),
|
|
"LOAD_BALANCER_SKU": kubernetesConfig.LoadBalancerSku,
|
|
"EXCLUDE_MASTER_FROM_STANDARD_LB": strconv.FormatBool(to.Bool(kubernetesConfig.ExcludeMasterFromStandardLB)),
|
|
"MAXIMUM_LOADBALANCER_RULE_COUNT": strconv.Itoa(kubernetesConfig.MaximumLoadBalancerRuleCount),
|
|
"CONTAINER_RUNTIME": kubernetesConfig.ContainerRuntime,
|
|
"CONTAINERD_DOWNLOAD_URL_BASE": cloudSpecConfig.KubernetesSpecConfig.ContainerdDownloadURLBase,
|
|
"KMS_PROVIDER_VAULT_NAME": input.ClusterKeyVaultName,
|
|
"IS_IPV6_ENABLED": strconv.FormatBool(cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6Only") || cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack")),
|
|
"AUTHENTICATION_METHOD": cs.Properties.GetCustomCloudAuthenticationMethod(),
|
|
"IDENTITY_SYSTEM": cs.Properties.GetCustomCloudIdentitySystem(),
|
|
"NETWORK_API_VERSION": APIVersionNetwork,
|
|
"NETWORK_MODE": kubernetesConfig.NetworkMode,
|
|
"KUBE_BINARY_URL": kubernetesConfig.CustomKubeBinaryURL,
|
|
"CUSTOM_HYPERKUBE_IMAGE": kubernetesConfig.CustomHyperkubeImage,
|
|
"MS_APT_REPO": kubernetesConfig.MicrosoftAptRepositoryURL,
|
|
"TAGS": kubernetesConfig.Tags,
|
|
"ENABLE_MULTIPLE_STANDARD_LOAD_BALANCERS": strconv.FormatBool(to.Bool(kubernetesConfig.EnableMultipleStandardLoadBalancers)),
|
|
}
|
|
|
|
keys := make([]string, 0)
|
|
for k := range parameters {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
var provisionScriptParametersCommon strings.Builder
|
|
for _, name := range keys {
|
|
provisionScriptParametersCommon.WriteString(name)
|
|
provisionScriptParametersCommon.WriteString("=")
|
|
provisionScriptParametersCommon.WriteString(parameters[name])
|
|
provisionScriptParametersCommon.WriteString(" ")
|
|
}
|
|
|
|
return provisionScriptParametersCommon.String()
|
|
}
|
|
|
|
// FormatAzureProdFQDNByLocation constructs an Azure prod fqdn
|
|
func FormatAzureProdFQDNByLocation(fqdnPrefix string, location string) string {
|
|
targetEnv := helpers.GetCloudTargetEnv(location)
|
|
FQDNFormat := AzureCloudSpecEnvMap[targetEnv].EndpointConfig.ResourceManagerVMDNSSuffix
|
|
return fmt.Sprintf("%s.%s."+FQDNFormat, fqdnPrefix, location)
|
|
}
|
|
|
|
// FormatProdFQDNByLocation constructs an Azure prod fqdn with custom cloud profile
|
|
// CustomCloudName is name of environment if customCloudProfile is provided, it will be empty string if customCloudProfile is empty.
|
|
// Because customCloudProfile is empty for deployment for AzurePublicCloud, AzureChinaCloud,AzureGermanCloud,AzureUSGovernmentCloud,
|
|
// The customCloudName value will be empty string for those clouds
|
|
func FormatProdFQDNByLocation(fqdnPrefix string, location string, cloudName string) string {
|
|
targetEnv := helpers.GetTargetEnv(location, cloudName)
|
|
FQDNFormat := AzureCloudSpecEnvMap[targetEnv].EndpointConfig.ResourceManagerVMDNSSuffix
|
|
return fmt.Sprintf("%s.%s."+FQDNFormat, fqdnPrefix, location)
|
|
}
|