pkg/engine/networkinterfaces.go (384 lines of code) (raw):

// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. package engine import ( "fmt" "github.com/Azure/aks-engine-azurestack/pkg/api" "github.com/Azure/aks-engine-azurestack/pkg/helpers/to" "github.com/Azure/azure-sdk-for-go/profiles/2020-09-01/network/mgmt/network" ) // CreateMasterVMNetworkInterfaces returns an ARM resource for the master VM NIC func CreateMasterVMNetworkInterfaces(cs *api.ContainerService) NetworkInterfaceARM { var dependencies []string if cs.Properties.MasterProfile != nil && cs.Properties.MasterProfile.IsCustomVNET() { dependencies = append(dependencies, "[variables('nsgID')]") } else { dependencies = append(dependencies, "[variables('vnetID')]") } if cs.Properties.MasterProfile != nil && cs.Properties.MasterProfile.HasMultipleNodes() { dependencies = append(dependencies, "[variables('masterInternalLbName')]") } if cs.Properties.MasterProfile != nil && cs.Properties.MasterProfile.HasCosmosEtcd() { dependencies = append(dependencies, "[resourceId('Microsoft.DocumentDB/databaseAccounts/', variables('cosmosAccountName'))]") } lbBackendAddressPools := []network.BackendAddressPool{} dependencies = append(dependencies, "[variables('masterLbName')]") publicLbPool := network.BackendAddressPool{ ID: to.StringPtr("[concat(variables('masterLbID'), '/backendAddressPools/', variables('masterLbBackendPoolName'))]"), } lbBackendAddressPools = append(lbBackendAddressPools, publicLbPool) armResource := ARMResource{ APIVersion: "[variables('apiVersionNetwork')]", Copy: map[string]string{ "count": "[sub(variables('masterCount'), variables('masterOffset'))]", "name": "nicLoopNode", }, DependsOn: dependencies, } if cs.Properties.MasterProfile != nil && cs.Properties.MasterProfile.HasMultipleNodes() { internalLbPool := network.BackendAddressPool{ ID: to.StringPtr("[concat(variables('masterInternalLbID'), '/backendAddressPools/', variables('masterLbBackendPoolName'))]"), } lbBackendAddressPools = append(lbBackendAddressPools, internalLbPool) } loadBalancerIPConfig := network.InterfaceIPConfiguration{ Name: to.StringPtr("ipconfig1"), InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{ LoadBalancerBackendAddressPools: &lbBackendAddressPools, PrivateIPAddress: to.StringPtr("[variables('masterPrivateIpAddrs')[copyIndex(variables('masterOffset'))]]"), Primary: to.BoolPtr(true), PrivateIPAllocationMethod: network.Static, Subnet: &network.Subnet{ ID: to.StringPtr("[variables('vnetSubnetID')]"), }, }, } publicNatRules := []network.InboundNatRule{ { ID: to.StringPtr("[concat(variables('masterLbID'),'/inboundNatRules/SSH-',variables('masterVMNamePrefix'),copyIndex(variables('masterOffset')))]"), }, } loadBalancerIPConfig.LoadBalancerInboundNatRules = &publicNatRules isAzureCNI := cs.Properties.OrchestratorProfile.IsAzureCNI() ipConfigurations := []network.InterfaceIPConfiguration{loadBalancerIPConfig} nicProperties := network.InterfacePropertiesFormat{ IPConfigurations: &ipConfigurations, } if isAzureCNI { ipConfigurations = append(ipConfigurations, getSecondaryNICIPConfigs(cs.Properties.MasterProfile.IPAddressCount)...) if cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack") { nicProperties.EnableIPForwarding = to.BoolPtr(true) } } else { if !cs.Properties.IsAzureStackCloud() { nicProperties.EnableIPForwarding = to.BoolPtr(true) } } // add ipv6 nic config for dual stack if cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack") || cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6Only") { ipv6Config := network.InterfaceIPConfiguration{ Name: to.StringPtr("ipconfigv6"), InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{ PrivateIPAddressVersion: "IPv6", Primary: to.BoolPtr(false), Subnet: &network.Subnet{ ID: to.StringPtr("[variables('vnetSubnetID')]"), }, }, } ipConfigurations = append(ipConfigurations, ipv6Config) } linuxProfile := cs.Properties.LinuxProfile if linuxProfile != nil && linuxProfile.HasCustomNodesDNS() { nicProperties.DNSSettings = &network.InterfaceDNSSettings{ DNSServers: &[]string{ "[parameters('dnsServer')]", }, } } if cs.Properties.MasterProfile != nil && cs.Properties.MasterProfile.IsCustomVNET() { nicProperties.NetworkSecurityGroup = &network.SecurityGroup{ ID: to.StringPtr("[variables('nsgID')]"), } } networkInterface := network.Interface{ Location: to.StringPtr("[variables('location')]"), Name: to.StringPtr("[concat(variables('masterVMNamePrefix'), 'nic-', copyIndex(variables('masterOffset')))]"), InterfacePropertiesFormat: &nicProperties, Type: to.StringPtr("Microsoft.Network/networkInterfaces"), } return NetworkInterfaceARM{ ARMResource: armResource, Interface: networkInterface, } } // createPrivateClusterMasterVMNetworkInterface returns an ARM resource for the master VM NIC in a private cluster configuration scenario func createPrivateClusterMasterVMNetworkInterface(cs *api.ContainerService) NetworkInterfaceARM { var dependencies []string if cs.Properties.MasterProfile.IsCustomVNET() { dependencies = append(dependencies, "[variables('nsgID')]") } else { dependencies = append(dependencies, "[variables('vnetID')]") } loadBalancerIPConfig := network.InterfaceIPConfiguration{ Name: to.StringPtr("ipconfig1"), InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{ PrivateIPAddress: to.StringPtr("[variables('masterPrivateIpAddrs')[copyIndex(variables('masterOffset'))]]"), Primary: to.BoolPtr(true), PrivateIPAllocationMethod: network.Static, Subnet: &network.Subnet{ ID: to.StringPtr("[variables('vnetSubnetID')]"), }, }, } if cs.Properties.MasterProfile.HasMultipleNodes() { dependencies = append(dependencies, "[variables('masterInternalLbName')]") var lbBackendAddressPools []network.BackendAddressPool internalLbPool := network.BackendAddressPool{ ID: to.StringPtr("[concat(variables('masterInternalLbID'), '/backendAddressPools/', variables('masterLbBackendPoolName'))]"), } lbBackendAddressPools = append(lbBackendAddressPools, internalLbPool) if cs.Properties.OrchestratorProfile.KubernetesConfig.LoadBalancerSku == api.StandardLoadBalancerSku { dependencies = append(dependencies, "[variables('masterLbName')]") publicLbPool := network.BackendAddressPool{ ID: to.StringPtr("[concat(variables('masterLbID'), '/backendAddressPools/', variables('masterLbBackendPoolName'))]"), } lbBackendAddressPools = append(lbBackendAddressPools, publicLbPool) } loadBalancerIPConfig.InterfaceIPConfigurationPropertiesFormat.LoadBalancerBackendAddressPools = &lbBackendAddressPools loadBalancerIPConfig.InterfaceIPConfigurationPropertiesFormat.LoadBalancerInboundNatRules = &[]network.InboundNatRule{} } ipConfigurations := []network.InterfaceIPConfiguration{loadBalancerIPConfig} isAzureCNI := cs.Properties.OrchestratorProfile.IsAzureCNI() if isAzureCNI { for i := 2; i <= cs.Properties.MasterProfile.IPAddressCount; i++ { ipConfig := network.InterfaceIPConfiguration{ Name: to.StringPtr(fmt.Sprintf("ipconfig%d", i)), InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{ Primary: to.BoolPtr(false), PrivateIPAllocationMethod: network.Dynamic, Subnet: &network.Subnet{ ID: to.StringPtr("[variables('vnetSubnetID')]"), }, }, } ipConfigurations = append(ipConfigurations, ipConfig) } } nicProperties := network.InterfacePropertiesFormat{ IPConfigurations: &ipConfigurations, } if !isAzureCNI && !cs.Properties.IsAzureStackCloud() { nicProperties.EnableIPForwarding = to.BoolPtr(true) } // Enable IPForwarding on NetworkInterface for azurecni dualstack if isAzureCNI { if cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack") { nicProperties.EnableIPForwarding = to.BoolPtr(true) } } linuxProfile := cs.Properties.LinuxProfile if linuxProfile != nil && linuxProfile.HasCustomNodesDNS() { nicProperties.DNSSettings = &network.InterfaceDNSSettings{ DNSServers: &[]string{ "[parameters('dnsServer')]", }, } } if cs.Properties.MasterProfile.IsCustomVNET() { nicProperties.NetworkSecurityGroup = &network.SecurityGroup{ ID: to.StringPtr("[variables('nsgID')]"), } } networkInterface := network.Interface{ Location: to.StringPtr("[variables('location')]"), Name: to.StringPtr("[concat(variables('masterVMNamePrefix'), 'nic-', copyIndex(variables('masterOffset')))]"), InterfacePropertiesFormat: &nicProperties, Type: to.StringPtr("Microsoft.Network/networkInterfaces"), } armResource := ARMResource{ APIVersion: "[variables('apiVersionNetwork')]", Copy: map[string]string{ "count": "[sub(variables('masterCount'), variables('masterOffset'))]", "name": "nicLoopNode", }, DependsOn: dependencies, } return NetworkInterfaceARM{ ARMResource: armResource, Interface: networkInterface, } } func createJumpboxNetworkInterface(cs *api.ContainerService) NetworkInterfaceARM { dependencies := []string{ "[concat('Microsoft.Network/publicIpAddresses/', variables('jumpboxPublicIpAddressName'))]", "[concat('Microsoft.Network/networkSecurityGroups/', variables('jumpboxNetworkSecurityGroupName'))]", } if !cs.Properties.MasterProfile.IsCustomVNET() { dependencies = append(dependencies, "[variables('vnetID')]") } armResource := ARMResource{ APIVersion: "[variables('apiVersionNetwork')]", DependsOn: dependencies, } nicProperties := network.InterfacePropertiesFormat{ IPConfigurations: &[]network.InterfaceIPConfiguration{ { Name: to.StringPtr("ipconfig1"), InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{ Subnet: &network.Subnet{ ID: to.StringPtr("[variables('vnetSubnetID')]"), }, Primary: to.BoolPtr(true), PrivateIPAllocationMethod: network.Dynamic, PublicIPAddress: &network.PublicIPAddress{ ID: to.StringPtr("[resourceId('Microsoft.Network/publicIpAddresses', variables('jumpboxPublicIpAddressName'))]"), }, }, }, }, NetworkSecurityGroup: &network.SecurityGroup{ ID: to.StringPtr("[resourceId('Microsoft.Network/networkSecurityGroups', variables('jumpboxNetworkSecurityGroupName'))]"), }, } networkInterface := network.Interface{ Location: to.StringPtr("[variables('location')]"), Name: to.StringPtr("[variables('jumpboxNetworkInterfaceName')]"), InterfacePropertiesFormat: &nicProperties, Type: to.StringPtr("Microsoft.Network/networkInterfaces"), } return NetworkInterfaceARM{ ARMResource: armResource, Interface: networkInterface, } } func createAgentVMASNetworkInterface(cs *api.ContainerService, profile *api.AgentPoolProfile) NetworkInterfaceARM { isWindows := profile.IsWindows() isCustomVNet := profile.IsCustomVNET() isAzureCNI := cs.Properties.OrchestratorProfile.IsAzureCNI() armResource := ARMResource{ APIVersion: "[variables('apiVersionNetwork')]", Copy: map[string]string{ "count": fmt.Sprintf("[sub(variables('%[1]sCount'), variables('%[1]sOffset'))]", profile.Name), "name": "loop", }, } var dependencies []string if isCustomVNet { dependencies = append(dependencies, "[variables('nsgID')]") } else { dependencies = append(dependencies, "[variables('vnetID')]") } if profile.LoadBalancerBackendAddressPoolIDs == nil && cs.Properties.OrchestratorProfile.KubernetesConfig.LoadBalancerSku == api.StandardLoadBalancerSku { dependencies = append(dependencies, "[variables('agentLbID')]") } armResource.DependsOn = dependencies networkInterface := network.Interface{ Type: to.StringPtr("Microsoft.Network/networkInterfaces"), Name: to.StringPtr("[concat(variables('" + profile.Name + "VMNamePrefix'), 'nic-', copyIndex(variables('" + profile.Name + "Offset')))]"), Location: to.StringPtr("[variables('location')]"), } networkInterface.InterfacePropertiesFormat = &network.InterfacePropertiesFormat{} if isCustomVNet { networkInterface.NetworkSecurityGroup = &network.SecurityGroup{ ID: to.StringPtr("[variables('nsgID')]"), } } if isWindows { networkInterface.EnableAcceleratedNetworking = profile.AcceleratedNetworkingEnabledWindows } else { networkInterface.EnableAcceleratedNetworking = profile.AcceleratedNetworkingEnabled } var ipConfigurations []network.InterfaceIPConfiguration for i := 1; i <= profile.IPAddressCount; i++ { ipConfig := network.InterfaceIPConfiguration{ Name: to.StringPtr(fmt.Sprintf("ipconfig%d", i)), InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{}, } if i == 1 { ipConfig.Primary = to.BoolPtr(true) backendPools := make([]network.BackendAddressPool, 0) if profile.LoadBalancerBackendAddressPoolIDs != nil { for _, lbBackendPoolID := range profile.LoadBalancerBackendAddressPoolIDs { backendPools = append(backendPools, network.BackendAddressPool{ ID: to.StringPtr(lbBackendPoolID), }, ) } } else { if cs.Properties.OrchestratorProfile.KubernetesConfig.LoadBalancerSku == api.StandardLoadBalancerSku { agentLbBackendAddressPools := network.BackendAddressPool{ ID: to.StringPtr("[concat(variables('agentLbID'), '/backendAddressPools/', variables('agentLbBackendPoolName'))]"), } backendPools = append(backendPools, agentLbBackendAddressPools) } } ipConfig.LoadBalancerBackendAddressPools = &backendPools } ipConfig.PrivateIPAllocationMethod = network.Dynamic ipConfig.Subnet = &network.Subnet{ ID: to.StringPtr(fmt.Sprintf("[variables('%sVnetSubnetID')]", profile.Name)), } if !isWindows { if profile.Role == "Infra" { ipConfig.LoadBalancerBackendAddressPools = &[]network.BackendAddressPool{ { ID: to.StringPtr("[concat(resourceId('Microsoft.Network/loadBalancers', variables('routerLBName')), '/backendAddressPools/backend')]"), }, } } } if cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack") || cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6Only") { if cs.Properties.OrchestratorProfile.KubernetesConfig.LoadBalancerSku != api.StandardLoadBalancerSku { var backendPools []network.BackendAddressPool if ipConfig.LoadBalancerBackendAddressPools != nil { backendPools = *ipConfig.LoadBalancerBackendAddressPools } backendPools = append(backendPools, network.BackendAddressPool{ ID: to.StringPtr("[concat(resourceId('Microsoft.Network/loadBalancers',parameters('masterEndpointDNSNamePrefix')), '/backendAddressPools/', parameters('masterEndpointDNSNamePrefix'))]"), }) ipConfig.LoadBalancerBackendAddressPools = &backendPools } } ipConfigurations = append(ipConfigurations, ipConfig) } // add ipv6 nic config for dual stack if cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack") || cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6Only") { ipv6Config := network.InterfaceIPConfiguration{ Name: to.StringPtr("ipconfigv6"), InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{ PrivateIPAddressVersion: "IPv6", Primary: to.BoolPtr(false), Subnet: &network.Subnet{ ID: to.StringPtr(fmt.Sprintf("[variables('%sVnetSubnetID')]", profile.Name)), }, }, } ipConfigurations = append(ipConfigurations, ipv6Config) } networkInterface.IPConfigurations = &ipConfigurations if !isAzureCNI && !cs.Properties.IsAzureStackCloud() { networkInterface.EnableIPForwarding = to.BoolPtr(true) } // Enable IPForwarding on NetworkInterface for azurecni dualstack if isAzureCNI { if cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack") { networkInterface.EnableIPForwarding = to.BoolPtr(true) } } return NetworkInterfaceARM{ ARMResource: armResource, Interface: networkInterface, } } func getSecondaryNICIPConfigs(n int) []network.InterfaceIPConfiguration { var ipConfigurations []network.InterfaceIPConfiguration for i := 2; i <= n; i++ { ipConfig := network.InterfaceIPConfiguration{ Name: to.StringPtr(fmt.Sprintf("ipconfig%d", i)), InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{ Primary: to.BoolPtr(false), PrivateIPAllocationMethod: network.Dynamic, Subnet: &network.Subnet{ ID: to.StringPtr("[variables('vnetSubnetID')]"), }, }, } ipConfigurations = append(ipConfigurations, ipConfig) } return ipConfigurations }