staging/cse/windows/azurecnifunc.ps1 (498 lines of code) (raw):
function Install-VnetPlugins
{
Param(
[Parameter(Mandatory=$true)][string]
$AzureCNIConfDir,
[Parameter(Mandatory=$true)][string]
$AzureCNIBinDir,
[Parameter(Mandatory=$true)][string]
$VNetCNIPluginsURL
)
Logs-To-Event -TaskName "AKS.WindowsCSE.InstallVnetPlugins" -TaskMessage "Start to install Azure VNet plugins. VnetCNIPluginsURL: $global:VNetCNIPluginsURL"
# Create CNI directories.
Create-Directory -FullPath $AzureCNIBinDir -DirectoryUsage "storing Azure CNI binaries"
Create-Directory -FullPath $AzureCNIConfDir -DirectoryUsage "storing Azure CNI configuration"
# Download Azure VNET CNI plugins.
# Mirror from https://github.com/Azure/azure-container-networking/releases
$zipfile = [Io.path]::Combine("$AzureCNIDir", "azure-vnet.zip")
DownloadFileOverHttp -Url $VNetCNIPluginsURL -DestinationPath $zipfile -ExitCode $global:WINDOWS_CSE_ERROR_DOWNLOAD_CNI_PACKAGE
Expand-Archive -path $zipfile -DestinationPath $AzureCNIBinDir
del $zipfile
# Windows does not need a separate CNI loopback plugin because the Windows
# kernel automatically creates a loopback interface for each network namespace.
# Copy CNI network config file and set bridge mode.
move $AzureCNIBinDir/*.conflist $AzureCNIConfDir
}
function Set-AzureCNIConfig
{
Param(
[Parameter(Mandatory=$true)][string]
$AzureCNIConfDir,
[Parameter(Mandatory=$true)][string]
$KubeDnsSearchPath,
[Parameter(Mandatory=$true)][string]
$KubeClusterCIDR,
[Parameter(Mandatory=$true)][string]
$KubeServiceCIDR,
[Parameter(Mandatory=$true)][string]
$VNetCIDR,
[Parameter(Mandatory=$true)][bool]
$IsDualStackEnabled,
[Parameter(Mandatory=$false)][bool]
$IsAzureCNIOverlayEnabled
)
Logs-To-Event -TaskName "AKS.WindowsCSE.SetAzureCNIConfig" -TaskMessage "Start to set Azure CNI config. IsDualStackEnabled: $global:IsDualStackEnabled, IsAzureCNIOverlayEnabled: $global:IsAzureCNIOverlayEnabled, IsDisableWindowsOutboundNat: $global:IsDisableWindowsOutboundNat, CiliumDataplaneEnabled: $global:CiliumDataplaneEnabled"
$fileName = [Io.path]::Combine("$AzureCNIConfDir", "10-azure.conflist")
$configJson = Get-Content $fileName | ConvertFrom-Json
$configJson.plugins.dns.Nameservers[0] = $KubeDnsServiceIp
$configJson.plugins.dns.Search[0] = $KubeDnsSearchPath
if (Test-Path variable:global:CiliumDataplaneEnabled) {
if($global:CiliumDataplaneEnabled) {
$configJson.plugins.ipam.type = "azure-cns"
}
}
if ($global:IsDisableWindowsOutboundNat) {
# Replace OutBoundNAT with LoopbackDSR for IMDS acess if AKS cluster disabled Windows OutBoundNAT.
# The Azure Instance Metadata Service (IMDS) provides information about currently running virtual machine instances.
# IMDS is a REST API that's available at a well-known, non-routable IP address (169.254.169.254)
# Details: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=windows#known-issues-and-faq
$valueObj = [PSCustomObject]@{
Type = 'LoopbackDSR'
IPAddress = '169.254.169.254'
}
$jsonContent = [PSCustomObject]@{
Name = 'EndpointPolicy'
Value = $valueObj
}
# $configJson.plugins[0].AdditionalArgs[0] is OutboundNAT.
Write-Log "Replace OutBoundNAT with LoopbackDSR for IMDS acess."
$configJson.plugins[0].AdditionalArgs[0] = $jsonContent
# Update the corresponding system regkey for DisableWindowsOutboundNat feature.
$osVersion = Get-WindowsVersion
if ($osVersion -eq "1809"){
Write-Log "Update RegKey to disable the incompatible HNSControlFlag (0x10) for feature DisableWindowsOutboundNat"
$hnsControlFlag=0x10
$currentValue=(Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\hns\State" -Name HNSControlFlag -ErrorAction Ignore)
if (![string]::IsNullOrEmpty($currentValue)) {
Write-Log "The current value of HNSControlFlag is $currentValue"
# Set the bit to 0 if the bit is 1
if ([int]$currentValue.HNSControlFlag -band $hnsControlFlag) {
$hnsControlFlag=([int]$currentValue.HNSControlFlag -bxor $hnsControlFlag)
Write-Log "HNSControlFlag is updated to $hnsControlFlag to clear the bit 0x10"
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\hns\State" -Name HNSControlFlag -Type DWORD -Value $hnsControlFlag
}
} else {
# Set 0 to disable all features under HNSControlFlag (0x10 defaults enable)
Write-Log "HNSControlFlag is set to 0 to clear the bit 0x10"
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\hns\State" -Name HNSControlFlag -Type DWORD -Value 0
}
} elseif ($osVersion -eq "ltsc2022") {
Write-Log "SourcePortPreservationForHostPort is set to 0"
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\hns\State" -Name SourcePortPreservationForHostPort -Type DWORD -Value 0
}
} else {
# Fill in DNS information for kubernetes.
$exceptionAddresses = @()
if ($IsDualStackEnabled) {
$subnetsToPass = $KubeClusterCIDR -split ","
foreach ($subnet in $subnetsToPass) {
$exceptionAddresses += $subnet
}
} else {
$exceptionAddresses += $KubeClusterCIDR
}
if (!$IsAzureCNIOverlayEnabled) {
$vnetCIDRs = $VNetCIDR -split ","
foreach ($cidr in $vnetCIDRs) {
$exceptionAddresses += $cidr
}
}
$osVersion = Get-WindowsVersion
if ($osVersion -eq "1809"){
# In WS2019 and below rules in the exception list are generated by dropping the prefix lenght and removing duplicate rules.
# If multiple execptions are specified with different ranges we should only include the broadest range for each address.
# This issue has been addressed in 19h1+ builds
$processedExceptions = GetBroadestRangesForEachAddress $exceptionAddresses
Write-Log "Filtering CNI config exception list values to work around WS2019 issue processing rules. Original exception list: $exceptionAddresses, processed exception list: $processedExceptions"
$configJson.plugins.AdditionalArgs[0].Value.ExceptionList = $processedExceptions
} else {
if ($IsDualStackEnabled) {
$ipv4Cidrs = @()
$ipv6Cidrs = @()
foreach ($cidr in $exceptionAddresses) {
# this is the pwsh way of strings.Count(s, ":") >= 2
if (($cidr -split ":").Count -ge 3) {
$ipv6Cidrs += $cidr
} else {
$ipv4Cidrs += $cidr
}
}
# we just assume the first entry in additional Args is the exception
# list for IPv4 and then append a new EnpointPolicy for IPv6. We
# probably shouldn't hard code the first one like this and just build
# 2 EndpointPolicies and append to the AdditionalArgs.
$configJson.plugins.AdditionalArgs[0].Value.ExceptionList = $ipv4Cidrs
$outboundException = [PSCustomObject]@{
Name = 'EndpointPolicy'
Value = [PSCustomObject]@{
Type = 'OutBoundNAT'
ExceptionList = $ipv6Cidrs
}
}
$configJson.plugins[0].AdditionalArgs += $outboundException
} else {
$configJson.plugins.AdditionalArgs[0].Value.ExceptionList = $exceptionAddresses
}
}
}
# Set the SDNRemoteArpMacAddress RegKey for HNS when AzureCNI is enabled
Write-Log "Setting SDNRemoteArpMacAddress to 12-34-56-78-9a-bc for HNS"
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\hns\State" -Name SDNRemoteArpMacAddress -Value "12-34-56-78-9a-bc"
# Restart hns service if it is exsting and running, to make the system regkey changes effective.
$hnsServiceName = 'hns'
$hnsService = Get-Service -Name $hnsServiceName -ErrorAction SilentlyContinue
if ($hnsService -and $hnsService.Status -eq 'Running') {
Write-Log "HNS service is already running. Restart HNS."
Restart-Service -Name $hnsServiceName
}
Write-Log "Done configuring HNS"
if ($global:KubeproxyFeatureGates.Contains("WinDSR=true")) {
Write-Log "Setting enableLoopbackDSR in Azure CNI conflist for WinDSR"
# Add {enableLoopbackDSR:true} if windowsSettings exists, otherwise, add {windowsSettings:{enableLoopbackDSR:true}}
if (Get-Member -InputObject $configJson.plugins[0] -name "windowsSettings" -Membertype Properties) {
$configJson.plugins[0].windowsSettings | Add-Member -Name "enableLoopbackDSR" -Value $True -MemberType NoteProperty
} else {
$jsonContent = [PSCustomObject]@{
'enableLoopbackDSR' = $True
}
$configJson.plugins[0] | Add-Member -Name "windowsSettings" -Value $jsonContent -MemberType NoteProperty
}
# $configJson.plugins[0].AdditionalArgs[1] is ROUTE. Remove ROUTE if WinDSR is enabled.
$configJson.plugins[0].AdditionalArgs = @($configJson.plugins[0].AdditionalArgs | Where-Object { $_ -ne $configJson.plugins[0].AdditionalArgs[1] })
} else {
if ($IsDualStackEnabled){
$configJson.plugins[0]|Add-Member -Name "ipv6Mode" -Value "ipv6nat" -MemberType NoteProperty
$serviceCidr = $KubeServiceCIDR -split ","
$configJson.plugins[0].AdditionalArgs[1].Value.DestinationPrefix = $serviceCidr[0]
$valueObj = [PSCustomObject]@{
Type = 'ROUTE'
DestinationPrefix = $serviceCidr[1]
NeedEncap = $True
}
$jsonContent = [PSCustomObject]@{
Name = 'EndpointPolicy'
Value = $valueObj
}
$configJson.plugins[0].AdditionalArgs += $jsonContent
}
else {
$configJson.plugins[0].AdditionalArgs[1].Value.DestinationPrefix = $KubeServiceCIDR
}
}
$aclRule1 = [PSCustomObject]@{
Type = 'ACL'
Protocols = '6'
Action = 'Block'
Direction = 'Out'
RemoteAddresses = '168.63.129.16/32'
RemotePorts = '80'
Priority = 200
RuleType = 'Switch'
}
$aclRule2 = [PSCustomObject]@{
Type = 'ACL'
Protocols = '6'
Action = 'Block'
Direction = 'Out'
RemoteAddresses = '168.63.129.16/32'
RemotePorts = '32526'
Priority = 200
RuleType = 'Switch'
}
$aclRule3 = [PSCustomObject]@{
Type = 'ACL'
Action = 'Allow'
Direction = 'In'
Priority = 65500
}
$aclRule4 = [PSCustomObject]@{
Type = 'ACL'
Action = 'Allow'
Direction = 'Out'
Priority = 65500
}
$jsonContent = [PSCustomObject]@{
Name = 'EndpointPolicy'
Value = $aclRule1
}
$configJson.plugins[0].AdditionalArgs += $jsonContent
$jsonContent = [PSCustomObject]@{
Name = 'EndpointPolicy'
Value = $aclRule2
}
$configJson.plugins[0].AdditionalArgs += $jsonContent
$jsonContent = [PSCustomObject]@{
Name = 'EndpointPolicy'
Value = $aclRule3
}
$configJson.plugins[0].AdditionalArgs += $jsonContent
$jsonContent = [PSCustomObject]@{
Name = 'EndpointPolicy'
Value = $aclRule4
}
$configJson.plugins[0].AdditionalArgs += $jsonContent
$configJson | ConvertTo-Json -depth 20 | Out-File -encoding ASCII -filepath $fileName
}
function GetBroadestRangesForEachAddress{
param([string[]] $values)
# Create a map of range values to IP addresses
$map = @{}
foreach ($value in $Values) {
if ($value -match '([0-9\.]+)\/([0-9]+)') {
if (!$map.contains($matches[1])) {
$map.Add($matches[1], @())
}
$map[$matches[1]] += [int]$matches[2]
}
}
# For each IP address select the range with the lagest scope (smallest value)
$returnValues = @()
foreach ($ip in $map.Keys) {
$range = $map[$ip] | Sort-Object | Select-Object -First 1
$returnValues += $ip + "/" + $range
}
# prefix $returnValues with common to ensure single values get returned as an array otherwise invalid json may be generated
return ,$returnValues
}
function GetSubnetPrefix
{
Param(
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $Token,
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $SubnetId,
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $ResourceManagerEndpoint,
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $NetworkAPIVersion
)
$uri = "$($ResourceManagerEndpoint)$($SubnetId)?api-version=$NetworkAPIVersion"
$headers = @{Authorization="Bearer $Token"}
try {
$response = Retry-Command -Command "Invoke-RestMethod" -Args @{Uri=$uri; Method="Get"; ContentType="application/json"; Headers=$headers} -Retries 5 -RetryDelaySeconds 10
} catch {
Set-ExitCode -ExitCode $global:WINDOWS_CSE_ERROR_GET_SUBNET_PREFIX -ErrorMessage "Error getting subnet prefix. Error: $_"
}
$response.properties.addressPrefix
}
function GenerateAzureStackCNIConfig
{
Param(
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $TenantId,
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $SubscriptionId,
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $AADClientId,
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $AADClientSecret,
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $ResourceGroup,
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $NetworkAPIVersion,
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $AzureEnvironmentFilePath,
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $IdentitySystem,
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $KubeDir
)
Logs-To-Event -TaskName "AKS.WindowsCSE.GenerateAzureStackCNIConfig" -TaskMessage "Start to generate Azure Stack CNI config"
$networkInterfacesFile = "$KubeDir\network-interfaces.json"
$azureCNIConfigFile = "$KubeDir\interfaces.json"
$azureEnvironment = Get-Content $AzureEnvironmentFilePath | ConvertFrom-Json
Write-Log "------------------------------------------------------------------------"
Write-Log "Parameters"
Write-Log "------------------------------------------------------------------------"
Write-Log "TenantId: $TenantId"
Write-Log "SubscriptionId: $SubscriptionId"
Write-Log "AADClientId: ..."
Write-Log "AADClientSecret: ..."
Write-Log "ResourceGroup: $ResourceGroup"
Write-Log "NetworkAPIVersion: $NetworkAPIVersion"
Write-Log "ServiceManagementEndpoint: $($azureEnvironment.serviceManagementEndpoint)"
Write-Log "ActiveDirectoryEndpoint: $($azureEnvironment.activeDirectoryEndpoint)"
Write-Log "ResourceManagerEndpoint: $($azureEnvironment.resourceManagerEndpoint)"
Write-Log "------------------------------------------------------------------------"
Write-Log "Variables"
Write-Log "------------------------------------------------------------------------"
Write-Log "azureCNIConfigFile: $azureCNIConfigFile"
Write-Log "networkInterfacesFile: $networkInterfacesFile"
Write-Log "------------------------------------------------------------------------"
Write-Log "Generating token for Azure Resource Manager"
$tokenURL = ""
if($IdentitySystem -ieq "adfs") {
$tokenURL = "$($azureEnvironment.activeDirectoryEndpoint)adfs/oauth2/token"
} else {
$tokenURL = "$($azureEnvironment.activeDirectoryEndpoint)$TenantId/oauth2/token"
}
Add-Type -AssemblyName System.Web
$encodedSecret = [System.Web.HttpUtility]::UrlEncode($AADClientSecret)
$body = "grant_type=client_credentials&client_id=$AADClientId&client_secret=$encodedSecret&resource=$($azureEnvironment.serviceManagementEndpoint)"
$args = @{Uri=$tokenURL; Method="Post"; Body=$body; ContentType='application/x-www-form-urlencoded'}
try {
$tokenResponse = Retry-Command -Command "Invoke-RestMethod" -Args $args -Retries 5 -RetryDelaySeconds 10
} catch {
Set-ExitCode -ExitCode $global:WINDOWS_CSE_ERROR_GENERATE_TOKEN_FOR_ARM -ErrorMessage "Error generating token for Azure Resource Manager. Error: $_"
}
$token = $tokenResponse | Select-Object -ExpandProperty access_token
Write-Log "Fetching network interface configuration for node"
$interfacesUri = "$($azureEnvironment.resourceManagerEndpoint)subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.Network/networkInterfaces?api-version=$NetworkAPIVersion"
$headers = @{Authorization="Bearer $token"}
$args = @{Uri=$interfacesUri; Method="Get"; ContentType="application/json"; Headers=$headers; OutFile=$networkInterfacesFile}
try {
Retry-Command -Command "Invoke-RestMethod" -Args $args -Retries 5 -RetryDelaySeconds 10
} catch {
Set-ExitCode -ExitCode $global:WINDOWS_CSE_ERROR_NETWORK_INTERFACES_NOT_EXIST -ErrorMessage "Error fetching network interface configuration for node. Error: $_"
}
Write-Log "Generating Azure CNI interface file"
$localNics = Get-NetAdapter | Select-Object -ExpandProperty MacAddress | ForEach-Object {$_ -replace "-",""}
$sdnNics = Get-Content $networkInterfacesFile `
| ConvertFrom-Json `
| Select-Object -ExpandProperty value `
| Where-Object { $localNics.Contains($_.properties.macAddress) } `
| Where-Object { $_.properties.ipConfigurations.Count -gt 0}
$interfaces = @{
Interfaces = @( $sdnNics | ForEach-Object { @{
MacAddress = $_.properties.macAddress
IsPrimary = $_.properties.primary
IPSubnets = @(@{
Prefix = GetSubnetPrefix `
-Token $token `
-SubnetId $_.properties.ipConfigurations[0].properties.subnet.id `
-NetworkAPIVersion $NetworkAPIVersion `
-ResourceManagerEndpoint $($azureEnvironment.resourceManagerEndpoint)
IPAddresses = $_.properties.ipConfigurations | ForEach-Object { @{
Address = $_.properties.privateIPAddress
IsPrimary = $_.properties.primary
}}
})
}})
}
ConvertTo-Json $interfaces -Depth 6 | Out-File -FilePath $azureCNIConfigFile -Encoding ascii
Set-ItemProperty -Path $azureCNIConfigFile -Name IsReadOnly -Value $true
}
function New-ExternalHnsNetwork
{
param (
[Parameter(Mandatory=$true)][bool]
$IsDualStackEnabled
)
Logs-To-Event -TaskName "AKS.WindowsCSE.NewExternalHnsNetwork" -TaskMessage "Start to create new external hns network"
Write-Log "Creating new HNS network `"ext`""
$externalNetwork = "ext"
$nas = @(Get-NetAdapter -Physical)
$nodeIPs = @()
if ($nas.Count -eq 0) {
Set-ExitCode -ExitCode $global:WINDOWS_CSE_ERROR_NETWORK_ADAPTER_NOT_EXIST -ErrorMessage "Failed to find any physical network adapters"
}
# If there is more than one adapter, use the first adapter that is assigned an ipaddress.
foreach($na in $nas)
{
$netIP = Get-NetIPAddress -ifIndex $na.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue -ErrorVariable netIPErr
if ($netIP)
{
$managementIP = $netIP.IPAddress
$adapterName = $na.Name
Write-Log "Get node IPv4 address assigned to the adapter $($na.Name): $($managementIP)"
$nodeIPs += $managementIP
if ($IsDualStackEnabled) {
$netIPv6s = Get-NetIPAddress -ifIndex $na.ifIndex -AddressFamily IPv6 -ErrorAction SilentlyContinue -ErrorVariable netIPErr
foreach($ipv6 in $netIPv6s)
{
# On an Azure Windows VM, there are two IPv6 IP addresses. Below is an example. It is same in an Azure Linux VM.
# ifIndex IPAddress PrefixLength PrefixOrigin SuffixOrigin AddressState PolicyStore
# ------- --------- ------------ ------------ ------------ ------------ -----------
# 6 fe80::97bd:baf7:2853:f73d%6 64 WellKnown Link Preferred ActiveStore
# 6 2404:f800:8000:122::4 128 Dhcp Dhcp Preferred ActiveStore
#
# From the found docuements. fe80: with WellKnown is the link-local address so we should ignore it.
# IPv6 link-local is a special type of unicast address that is auto-configured on any interface using a combination of
# the link-local prefix FE80::/10 (first 10 bits equal to 1111 1110 10) and the MAC address of the interface.
#
# https://learn.microsoft.com/en-us/dotnet/api/system.net.networkinformation.prefixorigin?view=net-8.0
# WellKnown | 2 | The prefix is a well-known prefix. Well-known prefixes are specified in standard-track Request for
# Comments (RFC) documents and assigned by the Internet Assigned Numbers Authority (Iana) or an address registry. Such
# prefixes are reserved for special purposes. -- | -- | --
if ($ipv6.PrefixOrigin -ne "WellKnown")
{
Write-Log "Get node IPv6 address assigned to the adapter $($na.Name): $($ipv6.IPAddress)"
$nodeIPs += $ipv6.IPAddress
}
}
}
break
}
else {
Write-Log "No IPv4 found on the network adapter $($na.Name); trying the next adapter ..."
if ($netIPErr) {
Write-Log "error when retrieving IPAddress: $netIPErr"
$netIPErr.Clear()
}
}
}
if(-Not $managementIP)
{
Set-ExitCode -ExitCode $global:WINDOWS_CSE_ERROR_NOT_FOUND_MANAGEMENT_IP -ErrorMessage "None of the physical network adapters has an IP address"
}
# https://github.com/kubernetes/kubernetes/pull/121028
if (([version]$global:KubeBinariesVersion).CompareTo([version]("1.29.0")) -ge 0) {
Logs-To-Event -TaskName "AKS.WindowsCSE.UpdateKubeClusterConfig" -TaskMessage "Start to update KubeCluster Config. NodeIPs: $nodeIPs"
# It should always get ipv4 address. Otherwise, it will throw WINDOWS_CSE_ERROR_NOT_FOUND_MANAGEMENT_IP
if ($IsDualStackEnabled -and $nodeIPs.Count -eq 1) {
Set-ExitCode -ExitCode $global:WINDOWS_CSE_ERROR_GET_NODE_IPV6_IP -ErrorMessage "Failed to get node IPv6 IP address"
}
try {
$clusterConfiguration = ConvertFrom-Json ((Get-Content $global:KubeClusterConfigPath -ErrorAction Stop) | Out-String)
$clusterConfiguration.Kubernetes.Kubelet.ConfigArgs += "--node-ip=$($nodeIPs -join ',')"
$clusterConfiguration | ConvertTo-Json -Depth 10 | Out-File -FilePath $global:KubeClusterConfigPath
} catch {
Set-ExitCode -ExitCode $global:WINDOWS_CSE_ERROR_UPDATING_KUBE_CLUSTER_CONFIG -ErrorMessage "Failed in updating kube cluster config. Error: $_"
}
}
Write-Log "Using adapter $adapterName with IP address $managementIP"
$mgmtIPAfterNetworkCreate
$stopWatch = New-Object System.Diagnostics.Stopwatch
$stopWatch.Start()
# Fixme : use a smallest range possible, that will not collide with any pod space
if ($IsDualStackEnabled) {
New-HNSNetwork -Type $global:NetworkMode -AddressPrefix @("192.168.255.0/30","192:168:255::0/127") -Gateway @("192.168.255.1","192:168:255::1") -AdapterName $adapterName -Name $externalNetwork -Verbose
}
else {
New-HNSNetwork -Type $global:NetworkMode -AddressPrefix "192.168.255.0/30" -Gateway "192.168.255.1" -AdapterName $adapterName -Name $externalNetwork -Verbose
}
# Wait for the switch to be created and the ip address to be assigned.
for ($i = 0; $i -lt 60; $i++) {
$mgmtIPAfterNetworkCreate = Get-NetIPAddress $managementIP -ErrorAction SilentlyContinue
if ($mgmtIPAfterNetworkCreate) {
break
}
Start-Sleep -Milliseconds 500
}
$stopWatch.Stop()
if (-not $mgmtIPAfterNetworkCreate) {
Set-ExitCode -ExitCode $global:WINDOWS_CSE_ERROR_MANAGEMENT_IP_NOT_EXIST -ErrorMessage "Failed to find $managementIP after creating $externalNetwork network"
}
Write-Log "It took $($StopWatch.Elapsed.Seconds) seconds to create the $externalNetwork network."
Write-Log "Log network adapter info after creating $externalNetwork network"
Get-NetIPConfiguration -AllCompartments -ErrorAction Ignore
$dnsServers=Get-DnsClientServerAddress -ErrorAction Ignore
if ($dnsServers) {
Write-Log "DNS Servers are: $($dnsServers.ServerAddresses)"
}
}
function Get-HnsPsm1
{
Param(
[Parameter(Mandatory=$true)][string]
$HNSModule
)
Logs-To-Event "ASK.WindowsCSE.GetAndImportHNSModule" -TaskMessage "Start to get and import hns module. NetworkPlugin: $global:NetworkPlugin"
# HNSModule is C:\k\hns.v2.psm1 when container runtime is Containerd
$fileName = [IO.Path]::GetFileName($HNSModule)
# Get-LogCollectionScripts will copy hns module file to C:\k\debug
$sourceFile = [IO.Path]::Combine('C:\k\debug\', $fileName)
try {
Write-Log "Copying $sourceFile to $HNSModule."
Copy-Item -Path $sourceFile -Destination "$HNSModule"
} catch {
Set-ExitCode -ExitCode $global:WINDOWS_CSE_ERROR_DOWNLOAD_HNS_MODULE -ErrorMessage "Failed to copy $sourceFile to $HNSModule. Error: $_"
}
}