acs-engine/pkg/api/types.go

1437 строки
60 KiB
Go

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
package api
import (
"fmt"
"hash/fnv"
"math/rand"
"net"
neturl "net/url"
"strconv"
"strings"
"sync"
"github.com/Azure/acs-engine/pkg/api/agentPoolOnlyApi/v20170831"
"github.com/Azure/acs-engine/pkg/api/agentPoolOnlyApi/v20180331"
"github.com/Azure/acs-engine/pkg/api/common"
"github.com/Azure/acs-engine/pkg/api/v20160330"
"github.com/Azure/acs-engine/pkg/api/v20160930"
"github.com/Azure/acs-engine/pkg/api/v20170131"
"github.com/Azure/acs-engine/pkg/api/v20170701"
"github.com/Azure/acs-engine/pkg/api/vlabs"
"github.com/Azure/acs-engine/pkg/helpers"
"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 ACS 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"`
DiagnosticsProfile *DiagnosticsProfile `json:"diagnosticsProfile,omitempty"`
JumpboxProfile *JumpboxProfile `json:"jumpboxProfile,omitempty"`
ServicePrincipalProfile *ServicePrincipalProfile `json:"servicePrincipalProfile,omitempty"`
CertificateProfile *CertificateProfile `json:"certificateProfile,omitempty"`
AADProfile *AADProfile `json:"aadProfile,omitempty"`
CustomProfile *CustomProfile `json:"customProfile,omitempty"`
HostedMasterProfile *HostedMasterProfile `json:"hostedMasterProfile,omitempty"`
AddonProfiles map[string]AddonProfile `json:"addonProfiles,omitempty"`
AzProfile *AzProfile `json:"azProfile,omitempty"`
FeatureFlags *FeatureFlags `json:"featureFlags,omitempty"`
}
// ClusterMetadata represents the metadata of the ACS cluster.
type ClusterMetadata struct {
SubnetName string `json:"subnetName,omitempty"`
VNetResourceGroupName string `json:"vnetResourceGroupName,omitempty"`
VirtualNetworkName string `json:"virtualNetworkName,omitempty"`
SecurityGroupName string `json:"securityGroupName,omitempty"`
RouteTableName string `json:"routeTableName,omitempty"`
PrimaryAvailabilitySetName string `json:"primaryAvailabilitySetName,omitempty"`
PrimaryScaleSetName string `json:"primaryScaleSetName,omitempty"`
ResourcePrefix string `json:"resourcePrefix,omitempty"`
}
// AddonProfile represents an addon for managed cluster
type AddonProfile struct {
Enabled bool `json:"enabled"`
Config map[string]string `json:"config"`
}
// AzProfile holds the azure context for where the cluster resides
type AzProfile struct {
TenantID string `json:"tenantId,omitempty"`
SubscriptionID string `json:"subscriptionId,omitempty"`
ResourceGroup string `json:"resourceGroup,omitempty"`
Location string `json:"location,omitempty"`
}
// FeatureFlags defines feature-flag restricted functionality
type FeatureFlags struct {
EnableCSERunInBackground bool `json:"enableCSERunInBackground,omitempty"`
BlockOutboundInternet bool `json:"blockOutboundInternet,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"`
}
// 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"`
}
// WindowsProfile represents the windows parameters passed to the cluster
type WindowsProfile struct {
AdminUsername string `json:"adminUsername"`
AdminPassword string `json:"adminPassword" conform:"redact"`
ImageVersion string `json:"imageVersion"`
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"`
}
// ProvisioningState represents the current state of container service resource.
type ProvisioningState string
const (
// Creating means ContainerService resource is being created.
Creating ProvisioningState = "Creating"
// Updating means an existing ContainerService resource is being updated
Updating ProvisioningState = "Updating"
// Failed means resource is in failed state
Failed ProvisioningState = "Failed"
// Succeeded means resource created succeeded during last create/update
Succeeded ProvisioningState = "Succeeded"
// Deleting means resource is in the process of being deleted
Deleting ProvisioningState = "Deleting"
// Migrating means resource is being migrated from one subscription or
// resource group to another
Migrating ProvisioningState = "Migrating"
// Upgrading means an existing ContainerService resource is being upgraded
Upgrading ProvisioningState = "Upgrading"
)
// OrchestratorProfile contains Orchestrator properties
type OrchestratorProfile struct {
OrchestratorType string `json:"orchestratorType"`
OrchestratorVersion string `json:"orchestratorVersion"`
KubernetesConfig *KubernetesConfig `json:"kubernetesConfig,omitempty"`
OpenShiftConfig *OpenShiftConfig `json:"openshiftConfig,omitempty"`
DcosConfig *DcosConfig `json:"dcosConfig,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"`
}
// 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"`
Containers []KubernetesContainerSpec `json:"containers,omitempty"`
Config map[string]string `json:"config,omitempty"`
Data string `json:"data,omitempty"`
}
// IsEnabled returns if the addon is explicitly enabled, or the user-provided default if non explicitly enabled
func (a *KubernetesAddon) IsEnabled(ifNil bool) bool {
if a.Enabled == nil {
return ifNil
}
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
}
// PrivateCluster defines the configuration for a private cluster
type PrivateCluster struct {
Enabled *bool `json:"enabled,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=1023"`
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 {
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"`
CloudProviderRateLimitBucket int `json:"cloudProviderRateLimitBucket,omitempty"`
}
// KubernetesConfigDeprecated are properties that are no longer operable and will be ignored
// TODO use this when strict JSON checking accommodates struct embedding
type KubernetesConfigDeprecated struct {
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"`
}
// KubernetesConfig contains the Kubernetes config structure, containing
// Kubernetes specific configuration
type KubernetesConfig struct {
KubernetesImageBase string `json:"kubernetesImageBase,omitempty"`
ClusterSubnet string `json:"clusterSubnet,omitempty"`
NetworkPolicy string `json:"networkPolicy,omitempty"`
NetworkPlugin string `json:"networkPlugin,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"`
DockerEngineVersion string `json:"dockerEngineVersion,omitempty"` // Deprecated
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"`
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"`
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"`
KubeletConfig map[string]string `json:"kubeletConfig,omitempty"`
ControllerManagerConfig map[string]string `json:"controllerManagerConfig,omitempty"`
CloudControllerManagerConfig map[string]string `json:"cloudControllerManagerConfig,omitempty"`
APIServerConfig map[string]string `json:"apiServerConfig,omitempty"`
SchedulerConfig map[string]string `json:"schedulerConfig,omitempty"`
PodSecurityPolicyConfig map[string]string `json:"podSecurityPolicyConfig,omitempty"`
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"`
CloudProviderRateLimitBucket int `json:"cloudProviderRateLimitBucket,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"`
AzureCNIVersion string `json:"azureCNIVersion,omitempty"`
AzureCNIURLLinux string `json:"azureCNIURLLinux,omitempty"`
AzureCNIURLWindows string `json:"azureCNIURLWindows,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"`
}
// BootstrapProfile represents the definition of the DCOS bootstrap node used to deploy the cluster
type BootstrapProfile struct {
VMSize string `json:"vmSize,omitempty"`
OSDiskSizeGB int `json:"osDiskSizeGB,omitempty"`
OAuthEnabled bool `json:"oauthEnabled,omitempty"`
StaticIP string `json:"staticIP,omitempty"`
Subnet string `json:"subnet,omitempty"`
}
// DcosConfig Configuration for DC/OS
type DcosConfig struct {
DcosBootstrapURL string `json:"dcosBootstrapURL,omitempty"`
DcosWindowsBootstrapURL string `json:"dcosWindowsBootstrapURL,omitempty"`
Registry string `json:"registry,omitempty"`
RegistryUser string `json:"registryUser,omitempty"`
RegistryPass string `json:"registryPassword,omitempty"`
DcosRepositoryURL string `json:"dcosRepositoryURL,omitempty"` // For CI use, you need to specify
DcosClusterPackageListID string `json:"dcosClusterPackageListID,omitempty"` // all three of these items
DcosProviderPackageID string `json:"dcosProviderPackageID,omitempty"` // repo url is the location of the build,
BootstrapProfile *BootstrapProfile `json:"bootstrapProfile,omitempty"`
}
// OpenShiftConfig holds configuration for OpenShift
type OpenShiftConfig struct {
KubernetesConfig *KubernetesConfig `json:"kubernetesConfig,omitempty"`
// ClusterUsername and ClusterPassword are temporary, do not rely on them.
ClusterUsername string `json:"clusterUsername,omitempty"`
ClusterPassword string `json:"clusterPassword,omitempty"`
// EnableAADAuthentication is temporary, do not rely on it.
EnableAADAuthentication bool `json:"enableAADAuthentication,omitempty"`
ConfigBundles map[string][]byte `json:"configBundles,omitempty"`
PublicHostname string
RouterProfiles []OpenShiftRouterProfile
}
// OpenShiftRouterProfile represents an OpenShift router.
type OpenShiftRouterProfile struct {
Name string
PublicSubdomain string
FQDN string
}
// 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"`
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"`
AgentSubnet string `json:"agentSubnet,omitempty"`
AvailabilityZones []string `json:"availabilityZones,omitempty"`
SinglePlacementGroup *bool `json:"singlePlacementGroup,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"`
}
// ImageReference represents a reference to an Image resource in Azure.
type ImageReference struct {
Name string `json:"name,omitempty"`
ResourceGroup string `json:"resourceGroup,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"`
AvailabilityProfile string `json:"availabilityProfile"`
ScaleSetPriority string `json:"scaleSetPriority,omitempty"`
ScaleSetEvictionPolicy string `json:"scaleSetEvictionPolicy,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"`
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"`
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"`
SinglePlacementGroup *bool `json:"singlePlacementGroup,omitempty"`
}
// AgentPoolProfileRole represents an agent role
type AgentPoolProfileRole string
// DiagnosticsProfile setting to enable/disable capturing
// diagnostics for VMs hosting container cluster.
type DiagnosticsProfile struct {
VMDiagnostics *VMDiagnostics `json:"vmDiagnostics"`
}
// VMDiagnostics contains settings to on/off boot diagnostics collection
// in RD Host
type VMDiagnostics struct {
Enabled bool `json:"enabled"`
// Specifies storage account Uri where Boot Diagnostics (CRP &
// VMSS BootDiagostics) and VM Diagnostics logs (using Linux
// Diagnostics Extension) will be stored. Uri will be of standard
// blob domain. i.e. https://storageaccount.blob.core.windows.net/
// This field is readonly as ACS RP will create a storage account
// for the customer.
StorageURL *neturl.URL `json:"storageUrl"`
}
// JumpboxProfile describes properties of the jumpbox setup
// in the ACS 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
// HostedMasterProfile defines properties for a hosted master
type HostedMasterProfile struct {
// Master public endpoint/FQDN with port
// The format will be FQDN:2376
// Not used during PUT, returned as part of GETFQDN
FQDN string `json:"fqdn,omitempty"`
DNSPrefix string `json:"dnsPrefix"`
// Subnet holds the CIDR which defines the Azure Subnet in which
// Agents will be provisioned. This is stored on the HostedMasterProfile
// and will become `masterSubnet` in the compiled template.
Subnet string `json:"subnet"`
// ApiServerWhiteListRange is a comma delimited CIDR which is whitelisted to AKS
APIServerWhiteListRange *string `json:"apiServerWhiteListRange"`
}
// 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"`
}
// CustomProfile specifies custom properties that are used for
// cluster instantiation. Should not be used by most users.
type CustomProfile struct {
Orchestrator string `json:"orchestrator,omitempty"`
}
// VlabsARMContainerService is the type we read and write from file
// needed because the json that is sent to ARM and acs-engine
// is different from the json that the ACS RP Api gets from ARM
type VlabsARMContainerService struct {
TypeMeta
*vlabs.ContainerService
}
// V20160330ARMContainerService is the type we read and write from file
// needed because the json that is sent to ARM and acs-engine
// is different from the json that the ACS RP Api gets from ARM
type V20160330ARMContainerService struct {
TypeMeta
*v20160330.ContainerService
}
// V20160930ARMContainerService is the type we read and write from file
// needed because the json that is sent to ARM and acs-engine
// is different from the json that the ACS RP Api gets from ARM
type V20160930ARMContainerService struct {
TypeMeta
*v20160930.ContainerService
}
// V20170131ARMContainerService is the type we read and write from file
// needed because the json that is sent to ARM and acs-engine
// is different from the json that the ACS RP Api gets from ARM
type V20170131ARMContainerService struct {
TypeMeta
*v20170131.ContainerService
}
// V20170701ARMContainerService is the type we read and write from file
// needed because the json that is sent to ARM and acs-engine
// is different from the json that the ACS RP Api gets from ARM
type V20170701ARMContainerService struct {
TypeMeta
*v20170701.ContainerService
}
// V20170831ARMManagedContainerService is the type we read and write from file
// needed because the json that is sent to ARM and acs-engine
// is different from the json that the ACS RP Api gets from ARM
type V20170831ARMManagedContainerService struct {
TypeMeta
*v20170831.ManagedCluster
}
// V20180331ARMManagedContainerService is the type we read and write from file
// needed because the json that is sent to ARM and acs-engine
// is different from the json that the ACS RP Api gets from ARM
type V20180331ARMManagedContainerService struct {
TypeMeta
*v20180331.ManagedCluster
}
// 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.OrchestratorProfile != nil && p.OrchestratorProfile.OrchestratorType == OpenShift {
return true
}
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
}
// 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 = 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 {
if p.OrchestratorProfile.IsKubernetes() ||
p.OrchestratorProfile.IsOpenShift() {
if p.HostedMasterProfile != nil {
return DefaultHostedProfileMasterName
} else if p.OrchestratorProfile.IsOpenShift() {
return DefaultOpenshiftOrchestratorName
} else {
return DefaultOrchestratorName
}
}
return ""
}
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) string {
index := p.getAgentPoolIndexByName(a.Name)
nameSuffix := p.GetClusterID()
vmPrefix := ""
if index != -1 {
if a.IsWindows() {
vmPrefix = nameSuffix[:4] + p.K8sOrchestratorName() + fmt.Sprintf("%02d", index)
} else {
vmPrefix = p.K8sOrchestratorName() + "-" + a.Name + "-" + nameSuffix + "-"
if a.IsVirtualMachineScaleSets() {
vmPrefix += "vmss"
}
}
}
return vmPrefix
}
// GetMasterVMPrefix returns the prefix of master VMs
func (p *Properties) GetMasterVMPrefix() string {
return p.K8sOrchestratorName() + "-master-" + p.GetClusterID() + "-"
}
// GetResourcePrefix returns the prefix to use for naming cluster resources
func (p *Properties) GetResourcePrefix() string {
if p.IsHostedMasterProfile() {
return p.K8sOrchestratorName() + "-agentpool-" + p.GetClusterID() + "-"
}
return p.K8sOrchestratorName() + "-master-" + p.GetClusterID() + "-"
}
// GetRouteTableName returns the route table name of the cluster.
func (p *Properties) GetRouteTableName() string {
return p.GetResourcePrefix() + "routetable"
}
// GetNSGName returns the name of the network security group of the cluster.
func (p *Properties) GetNSGName() string {
return p.GetResourcePrefix() + "nsg"
}
// GetPrimaryAvailabilitySetName returns the name of the primary availability set of the cluster
func (p *Properties) GetPrimaryAvailabilitySetName() string {
return p.AgentPoolProfiles[0].Name + "-availabilitySet-" + p.GetClusterID()
}
// GetPrimaryScaleSetName returns the name of the primary scale set node of the cluster
func (p *Properties) GetPrimaryScaleSetName() string {
return p.K8sOrchestratorName() + "-" + p.AgentPoolProfiles[0].Name + "-" + p.GetClusterID() + "-vmss"
}
// IsHostedMasterProfile returns true if the cluster has a hosted master
func (p *Properties) IsHostedMasterProfile() bool {
return p.HostedMasterProfile != nil
}
// GetVNetResourceGroupName returns the virtual network resource group name of the cluster
func (p *Properties) GetVNetResourceGroupName() string {
var vnetResourceGroupName string
if p.IsHostedMasterProfile() && p.AreAgentProfilesCustomVNET() {
vnetResourceGroupName = strings.Split(p.AgentPoolProfiles[0].VnetSubnetID, "/")[DefaultVnetResourceGroupSegmentIndex]
} else if !p.IsHostedMasterProfile() && 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.IsHostedMasterProfile() && p.AreAgentProfilesCustomVNET() {
vnetName = strings.Split(p.AgentPoolProfiles[0].VnetSubnetID, "/")[DefaultVnetNameResourceSegmentIndex]
} else if !p.IsHostedMasterProfile() && 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.IsHostedMasterProfile() {
if p.AreAgentProfilesCustomVNET() {
subnetName = strings.Split(p.AgentPoolProfiles[0].VnetSubnetID, "/")[DefaultSubnetNameResourceSegmentIndex]
} else {
subnetName = p.K8sOrchestratorName() + "-subnet"
}
} else {
if p.MasterProfile.IsCustomVNET() {
subnetName = strings.Split(p.MasterProfile.VnetSubnetID, "/")[DefaultSubnetNameResourceSegmentIndex]
} else {
subnetName = p.K8sOrchestratorName() + "-subnet"
}
}
return subnetName
}
// 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 {
var mutex = &sync.Mutex{}
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 p.HostedMasterProfile != nil {
h.Write([]byte(p.HostedMasterProfile.DNSPrefix))
} else {
h.Write([]byte(p.AgentPoolProfiles[0].Name))
}
r := rand.New(rand.NewSource(int64(h.Sum64())))
mutex.Lock()
p.ClusterID = fmt.Sprintf("%08d", r.Uint32())[:uniqueNameSuffixSize]
mutex.Unlock()
}
return p.ClusterID
}
// GetClusterMetadata returns a instance of the struct type api.ClusterMetadata.
func (p *Properties) GetClusterMetadata() *ClusterMetadata {
return &ClusterMetadata{
SubnetName: p.GetSubnetName(),
VNetResourceGroupName: p.GetVNetResourceGroupName(),
VirtualNetworkName: p.GetVirtualNetworkName(),
SecurityGroupName: p.GetNSGName(),
RouteTableName: p.GetRouteTableName(),
PrimaryAvailabilitySetName: p.GetPrimaryAvailabilitySetName(),
PrimaryScaleSetName: p.GetPrimaryScaleSetName(),
ResourcePrefix: p.GetResourcePrefix(),
}
}
// HasZonesForAllAgentPools returns true if all of the agent pools have zones
func (p *Properties) HasZonesForAllAgentPools() bool {
for _, ap := range p.AgentPoolProfiles {
if !ap.HasAvailabilityZones() {
return false
}
}
return true
}
// 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
}
// GetNonMasqueradeCIDR returns the non-masquerade CIDR for the ip-masq-agent.
func (p *Properties) GetNonMasqueradeCIDR() string {
var nonMasqCidr string
if !p.IsHostedMasterProfile() {
if p.OrchestratorProfile.IsAzureCNI() {
if p.MasterProfile != nil && p.MasterProfile.IsCustomVNET() {
nonMasqCidr = p.MasterProfile.VnetCidr
} else {
nonMasqCidr = DefaultVNETCIDR
}
} else {
nonMasqCidr = p.OrchestratorProfile.KubernetesConfig.ClusterSubnet
}
}
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
}
// 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
}
// IsRHEL returns true if the master specified a RHEL distro
func (m *MasterProfile) IsRHEL() bool {
return m.Distro == RHEL
}
// IsCoreOS returns true if the master specified a CoreOS distro
func (m *MasterProfile) IsCoreOS() bool {
return m.Distro == CoreOS
}
// IsVirtualMachineScaleSets returns true if the master availability profile is VMSS
func (m *MasterProfile) IsVirtualMachineScaleSets() bool {
return m.AvailabilityProfile == VirtualMachineScaleSets
}
// 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
}
// 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
}
// IsRHEL returns true if the agent pool specified a RHEL distro
func (a *AgentPoolProfile) IsRHEL() bool {
return a.OSType == Linux && a.Distro == RHEL
}
// IsCoreOS returns true if the agent specified a CoreOS distro
func (a *AgentPoolProfile) IsCoreOS() bool {
return a.OSType == Linux && a.Distro == CoreOS
}
// 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
}
// 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
}
// 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
}
// 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
}
// GetWindowsDockerVersion gets the docker version specified or returns default value
func (w *WindowsProfile) GetWindowsDockerVersion() string {
if w.WindowsDockerVersion != "" {
return w.WindowsDockerVersion
}
return KubernetesWindowsDockerVersion
}
// 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
}
// 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
}
// IsSwarmMode returns true if this template is for Swarm Mode orchestrator
func (o *OrchestratorProfile) IsSwarmMode() bool {
return o.OrchestratorType == SwarmMode
}
// IsKubernetes returns true if this template is for Kubernetes orchestrator
func (o *OrchestratorProfile) IsKubernetes() bool {
return o.OrchestratorType == Kubernetes
}
// IsOpenShift returns true if this template is for OpenShift orchestrator
func (o *OrchestratorProfile) IsOpenShift() bool {
return o.OrchestratorType == OpenShift
}
// IsDCOS returns true if this template is for DCOS orchestrator
func (o *OrchestratorProfile) IsDCOS() bool {
return o.OrchestratorType == DCOS
}
// IsAzureCNI returns true if Azure CNI network plugin is enabled
func (o *OrchestratorProfile) IsAzureCNI() bool {
if o.KubernetesConfig != nil {
return o.KubernetesConfig.NetworkPlugin == "azure"
}
return false
}
// RequireRouteTable returns true if this deployment requires routing table
func (o *OrchestratorProfile) RequireRouteTable() bool {
switch o.OrchestratorType {
case Kubernetes:
if o.IsAzureCNI() || "cilium" == o.KubernetesConfig.NetworkPolicy {
return false
}
return true
default:
return false
}
}
// NeedsExecHealthz returns whether or not we have a configuration that requires exechealthz pod anywhere
func (o *OrchestratorProfile) NeedsExecHealthz() bool {
return o.IsKubernetes() &&
common.IsKubernetesVersionGe(o.OrchestratorVersion, "1.7.0") &&
!common.IsKubernetesVersionGe(o.OrchestratorVersion, "1.9.0")
}
// 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 in nil, the "defaultValue" is returned.
func (k *KubernetesConfig) isAddonEnabled(addonName string, defaultValue bool) bool {
kubeAddon := k.GetAddonByName(addonName)
return kubeAddon.IsEnabled(defaultValue)
}
// IsMetricsServerEnabled checks if the metrics server addon is enabled
func (o *OrchestratorProfile) IsMetricsServerEnabled() bool {
return o.KubernetesConfig.isAddonEnabled(DefaultMetricsServerAddonName,
common.IsKubernetesVersionGe(o.OrchestratorVersion, "1.9.0"))
}
// IsContainerMonitoringEnabled checks if the container monitoring addon is enabled
func (k *KubernetesConfig) IsContainerMonitoringEnabled() bool {
return k.isAddonEnabled(ContainerMonitoringAddonName, DefaultContainerMonitoringAddonEnabled)
}
// IsTillerEnabled checks if the tiller addon is enabled
func (k *KubernetesConfig) IsTillerEnabled() bool {
return k.isAddonEnabled(DefaultTillerAddonName, DefaultTillerAddonEnabled)
}
// IsAADPodIdentityEnabled checks if the tiller addon is enabled
func (k *KubernetesConfig) IsAADPodIdentityEnabled() bool {
return k.isAddonEnabled(DefaultAADPodIdentityAddonName, DefaultAADPodIdentityAddonEnabled)
}
// IsACIConnectorEnabled checks if the ACI Connector addon is enabled
func (k *KubernetesConfig) IsACIConnectorEnabled() bool {
return k.isAddonEnabled(DefaultACIConnectorAddonName, DefaultACIConnectorAddonEnabled)
}
// IsClusterAutoscalerEnabled checks if the cluster autoscaler addon is enabled
func (k *KubernetesConfig) IsClusterAutoscalerEnabled() bool {
return k.isAddonEnabled(DefaultClusterAutoscalerAddonName, DefaultClusterAutoscalerAddonEnabled)
}
// IsBlobfuseFlexVolumeEnabled checks if the Blobfuse FlexVolume addon is enabled
func (k *KubernetesConfig) IsBlobfuseFlexVolumeEnabled() bool {
return k.isAddonEnabled(DefaultBlobfuseFlexVolumeAddonName, DefaultBlobfuseFlexVolumeAddonEnabled)
}
// IsSMBFlexVolumeEnabled checks if the SMB FlexVolume addon is enabled
func (k *KubernetesConfig) IsSMBFlexVolumeEnabled() bool {
return k.isAddonEnabled(DefaultSMBFlexVolumeAddonName, DefaultSMBFlexVolumeAddonEnabled)
}
// IsKeyVaultFlexVolumeEnabled checks if the Key Vault FlexVolume addon is enabled
func (k *KubernetesConfig) IsKeyVaultFlexVolumeEnabled() bool {
return k.isAddonEnabled(DefaultKeyVaultFlexVolumeAddonName, DefaultKeyVaultFlexVolumeAddonEnabled)
}
// IsDashboardEnabled checks if the kubernetes-dashboard addon is enabled
func (k *KubernetesConfig) IsDashboardEnabled() bool {
return k.isAddonEnabled(DefaultDashboardAddonName, DefaultDashboardAddonEnabled)
}
// IsIPMasqAgentEnabled checks if the ip-masq-agent addon is enabled
func (k *KubernetesConfig) IsIPMasqAgentEnabled() bool {
return k.isAddonEnabled(IPMASQAgentAddonName, IPMasqAgentAddonEnabled)
}
// 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
}
// 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 {
k := p.OrchestratorProfile.KubernetesConfig
return k.isAddonEnabled(NVIDIADevicePluginAddonName, getDefaultNVIDIADevicePluginEnabled(p))
}
func getDefaultNVIDIADevicePluginEnabled(p *Properties) bool {
o := p.OrchestratorProfile
var addonEnabled bool
if p.HasNSeriesSKU() && common.IsKubernetesVersionGe(o.OrchestratorVersion, "1.10.0") {
addonEnabled = true
} else {
addonEnabled = false
}
return addonEnabled
}
// IsReschedulerEnabled checks if the rescheduler addon is enabled
func (k *KubernetesConfig) IsReschedulerEnabled() bool {
return k.isAddonEnabled(DefaultReschedulerAddonName, DefaultReschedulerAddonEnabled)
}
// 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 {
runtime := strings.ToLower(k.ContainerRuntime)
return runtime == "docker" || runtime == ""
}
// SetCloudProviderBackoffDefaults sets default cloudprovider backoff config
func (k *KubernetesConfig) SetCloudProviderBackoffDefaults() {
if k.CloudProviderBackoffDuration == 0 {
k.CloudProviderBackoffDuration = DefaultKubernetesCloudProviderBackoffDuration
}
if k.CloudProviderBackoffExponent == 0 {
k.CloudProviderBackoffExponent = DefaultKubernetesCloudProviderBackoffExponent
}
if k.CloudProviderBackoffJitter == 0 {
k.CloudProviderBackoffJitter = DefaultKubernetesCloudProviderBackoffJitter
}
if k.CloudProviderBackoffRetries == 0 {
k.CloudProviderBackoffRetries = DefaultKubernetesCloudProviderBackoffRetries
}
}
// SetCloudProviderRateLimitDefaults sets default cloudprovider rate limiter config
func (k *KubernetesConfig) SetCloudProviderRateLimitDefaults() {
if k.CloudProviderRateLimitQPS == 0 {
k.CloudProviderRateLimitQPS = DefaultKubernetesCloudProviderRateLimitQPS
}
if k.CloudProviderRateLimitBucket == 0 {
k.CloudProviderRateLimitBucket = DefaultKubernetesCloudProviderRateLimitBucket
}
}
// 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
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 k8s.gcr.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.GetCloudTargetEnv(cs.Location)
return AzureCloudSpecEnvMap[targetEnv]
}
// GetAzureProdFQDN returns the formatted FQDN string for a given apimodel.
func (cs *ContainerService) GetAzureProdFQDN() string {
return FormatAzureProdFQDNByLocation(cs.Properties.MasterProfile.DNSPrefix, cs.Location)
}
// 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)
}