diff --git a/Makefile b/Makefile index 4e5db3a47..617cb471e 100644 --- a/Makefile +++ b/Makefile @@ -84,6 +84,16 @@ NODE_CONTAINER_BIN_DIR=./dist/bin/ NODE_CONTAINER_BINARY = $(NODE_CONTAINER_BIN_DIR)/calico-node-$(ARCH) WINDOWS_BINARY = $(NODE_CONTAINER_BIN_DIR)/calico-node.exe +WINDOWS_GEN_INSTALL_SCRIPT_BIN := hack/bin/gen-install-calico-windows-script + +# Base URL of the Calico for Windows installation zip archive. +# This can be overridden for dev releases. +WINDOWS_ARCHIVE_BASE_URL ?= https://docs.projectcalico.org + +# This is either "Calico" or "Calico Enterprise" +WINDOWS_INSTALL_SCRIPT_PRODUCT ?= Calico +WINDOWS_INSTALL_SCRIPT := dist/install-calico-windows.ps1 + # Variables for the Windows packaging. # Name of the Windows release ZIP archive. WINDOWS_ARCHIVE_ROOT := windows-packaging/CalicoWindows @@ -159,6 +169,8 @@ clean: rm -f $(WINDOWS_ARCHIVE_ROOT)/libs/hns/hns.psm1 rm -f $(WINDOWS_ARCHIVE_ROOT)/libs/hns/License.txt rm -f $(WINDOWS_ARCHIVE_ROOT)/cni/*.exe + rm -f $(WINDOWS_GEN_INSTALL_SCRIPT_BIN) + rm -f $(WINDOWS_INSTALL_SCRIPT) rm -rf filesystem/included-source rm -rf dist rm -rf filesystem/etc/calico/confd/conf.d filesystem/etc/calico/confd/config filesystem/etc/calico/confd/templates @@ -520,6 +532,9 @@ endif $(MAKE) retag-build-images-with-registries RELEASE=true IMAGETAG=$(VERSION) # Generate the `latest` images. $(MAKE) retag-build-images-with-registries RELEASE=true IMAGETAG=latest + # Generate the install-calico-windows.ps1 script + $(MAKE) install-calico-windows-script + # Generate the Windows zip archives. $(MAKE) release-windows-archive ## Produces the Windows ZIP archive for the release. @@ -556,6 +571,11 @@ endif -n $(VERSION) \ $(VERSION) $(WINDOWS_ARCHIVE) + # Update the release with the install-calico-windows.ps1 file too. + ghr -u projectcalico -r node \ + -n $(VERSION) \ + $(VERSION) $(WINDOWS_INSTALL_SCRIPT) + @echo "Finalize the GitHub release based on the pushed tag." @echo "" @echo " https://$(PACKAGE_NAME)/releases/tag/$(VERSION)" @@ -642,6 +662,21 @@ build-windows-archive: $(WINDOWS_ARCHIVE_FILES) windows-packaging/nssm-$(WINDOWS $(WINDOWS_ARCHIVE_BINARY): $(WINDOWS_BINARY) cp $< $@ +# Build the tool to generate the install-calico-windows.ps1 installation script. +$(WINDOWS_GEN_INSTALL_SCRIPT_BIN): + mkdir -p hack/bin + $(DOCKER_RUN) $(CALICO_BUILD) sh -c ' \ + $(GIT_CONFIG_SSH) \ + go build -o $@ ./hack/gen-install-calico-windows-script' + +# Generate the install-calico-windows.ps1 installation script. +# For dev releases, override WINDOWS_ARCHIVE_BASE_URL. +install-calico-windows-script $(WINDOWS_INSTALL_SCRIPT): $(WINDOWS_GEN_INSTALL_SCRIPT_BIN) + $(WINDOWS_GEN_INSTALL_SCRIPT_BIN) \ + -product "$(WINDOWS_INSTALL_SCRIPT_PRODUCT)" \ + -version $(GIT_VERSION) \ + -templatePath windows-packaging/install-calico-windows.ps1.tpl \ + -baseUrl $(WINDOWS_ARCHIVE_BASE_URL) > $(WINDOWS_INSTALL_SCRIPT) ############################################################################### # Utilities diff --git a/hack/gen-install-calico-windows-script/main.go b/hack/gen-install-calico-windows-script/main.go new file mode 100644 index 000000000..c5c366e89 --- /dev/null +++ b/hack/gen-install-calico-windows-script/main.go @@ -0,0 +1,126 @@ +// Copyright (c) 2021 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "errors" + "flag" + "fmt" + "log" + "os" + "text/template" +) + +type install struct { + Product string `json:"product"` + ProductName string `json:"productName"` + Version string `json:"version"` + BaseUrl string `json:"baseUrl"` + RootDir string `json:"rootDir"` + ZipFileName string `json:"zipFileName"` +} + +var installs = map[string]install{ + "Calico": { + Product: "Calico", + ProductName: "Calico for Windows", + RootDir: "CalicoWindows", + ZipFileName: "calico-windows.zip", + }, + "Calico Enterprise": { + Product: "Calico Enterprise", + ProductName: "Tigera Calico for Windows", + RootDir: "TigeraCalico", + ZipFileName: "tigera-calico-windows.zip", + }, +} + +func newInstall(product, version, baseUrl string) (install, error) { + var data install + + if install, ok := installs[product]; ok { + data = install + data.Version = version + data.BaseUrl = baseUrl + return data, nil + } + return data, fmt.Errorf("invalid product: %v", product) +} + +var ( + product string + version string + templatePath string + baseUrl string +) + +// This program generates the Calico for Windows installation script for a given product, version and baseUrl. +// +// Examples: +// +// For Calico v3.21.1: +// +// gen-install-calico-windows-script \ +// -product Calico \ +// -version v3.21.1 \ +// -templatePath windows-packaging/install-calico-windows.ps1.tpl \ +// -baseUrl https://docs.projectcalico.org > install-calico-windows.ps1 +// +// +// For Calico Enterprise v3.11.0: +// +// gen-install-calico-windows-script \ +// -product "Calico Enterprise" \ +// -version v3.11.0 \ +// -templatePath windows-packaging/install-calico-windows.ps1.tpl \ +// -baseUrl https://docs.tigera.io > install-calico-windows.ps1 +func main() { + flag.StringVar(&product, "product", "", `product to generate install script for. either "Calico" or "Calico Enterprise"`) + flag.StringVar(&version, "version", "", `version`) + flag.StringVar(&templatePath, "templatePath", "", `path to the template for the installation script`) + flag.StringVar(&baseUrl, "baseUrl", "", `URL where the installation zip file will be hosted. Required for Calico only`) + flag.Parse() + + log.Printf("product: %v, version: %v, templatePath: %v, baseUrl: %v", product, version, templatePath, baseUrl) + + if product == "" || version == "" || templatePath == "" { + log.Fatalf("product, version, templatePath, and baseUrl must all be specified") + } + + if product == "Calico" && baseUrl == "" { + log.Fatalf("baseUrl is required for Calico") + } + + if _, err := os.Stat(templatePath); errors.Is(err, os.ErrNotExist) { + log.Fatalf("templatePath %v does not exist", templatePath) + } + + data, err := newInstall(product, version, baseUrl) + if err != nil { + log.Fatalf("error generating installation script data: %v", err) + } + + log.Printf("using install data: %+v", data) + + t, err := template.ParseFiles(templatePath) + if err != nil { + log.Fatalf("error parsing template: %v", err) + } + + err = t.Execute(os.Stdout, data) + if err != nil { + log.Fatalf("error rendering template: %v", err) + } +} diff --git a/windows-packaging/install-calico-windows.ps1.tpl b/windows-packaging/install-calico-windows.ps1.tpl new file mode 100644 index 000000000..95126030e --- /dev/null +++ b/windows-packaging/install-calico-windows.ps1.tpl @@ -0,0 +1,439 @@ +# Copyright (c) 2020-2021 Tigera, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +<# +.DESCRIPTION + This script installs and starts {{.Product}} services on a Windows node. + + Note: EKS requires downloading kubectl.exe to c:\k before running this script: https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html +#> + +Param( + +{{- if eq .Product "Calico" }} +{{- if eq .BaseUrl "https://docs.projectcalico.org" }} + [parameter(Mandatory = $false)] $ReleaseBaseURL="https://github.com/projectcalico/calico/releases/download/{{.Version}}/", +{{- else }} + [parameter(Mandatory = $false)] $ReleaseBaseURL="{{.BaseUrl}}/files/windows/", +{{- end }} + [parameter(Mandatory = $false)] $ReleaseFile="calico-windows-{{.Version}}.zip", +{{- end }} + [parameter(Mandatory = $false)] $KubeVersion="", + [parameter(Mandatory = $false)] $DownloadOnly="no", + [parameter(Mandatory = $false)] $Datastore="kubernetes", + [parameter(Mandatory = $false)] $EtcdEndpoints="", + [parameter(Mandatory = $false)] $EtcdTlsSecretName="", + [parameter(Mandatory = $false)] $EtcdKey="", + [parameter(Mandatory = $false)] $EtcdCert="", + [parameter(Mandatory = $false)] $EtcdCaCert="", + [parameter(Mandatory = $false)] $ServiceCidr="10.96.0.0/12", + [parameter(Mandatory = $false)] $DNSServerIPs="10.96.0.10", + [parameter(Mandatory = $false)] $CalicoBackend="" +) + +function DownloadFiles() +{ + Write-Host "Creating CNI directory" + md $BaseDir\cni\config -ErrorAction Ignore + + Write-Host "Downloading Windows Kubernetes scripts" + DownloadFile -Url https://github.com/Microsoft/SDN/raw/master/Kubernetes/windows/hns.psm1 -Destination $BaseDir\hns.psm1 + DownloadFile -Url https://github.com/Microsoft/SDN/raw/master/Kubernetes/windows/InstallImages.ps1 -Destination $BaseDir\InstallImages.ps1 + DownloadFile -Url https://github.com/Microsoft/SDN/raw/master/Kubernetes/windows/Dockerfile -Destination $BaseDir\Dockerfile +} + +function PrepareDockerFile() +{ + # Update Dockerfile for windows + $OSInfo = (Get-ComputerInfo | select WindowsVersion, OsBuildNumber) + $OSNumber = $OSInfo.WindowsVersion + $ExistOSNumber = cat c:\k\Dockerfile | findstr.exe $OSNumber + if (!$ExistOSNumber) + { + Write-Host "Update dockerfile for $OSNumber" + + $ImageWithOSNumber = "nanoserver:" + $OSNumber + (get-content c:\k\Dockerfile) | foreach-object {$_ -replace "nanoserver", "$ImageWithOSNumber"} | set-content c:\k\Dockerfile + } +} + +function PrepareKubernetes() +{ + DownloadFiles + PrepareDockerFile + ipmo C:\k\hns.psm1 + + # Prepare POD infra Images + c:\k\InstallImages.ps1 + + InstallK8sBinaries +} + +function InstallK8sBinaries() +{ + Install-7Zip + $Source = "" | Select Release + $Source.Release=$KubeVersion + InstallKubernetesBinaries -Destination $BaseDir -Source $Source + cp c:\k\kubernetes\node\bin\*.exe c:\k +} + +function GetPlatformType() +{ + # AKS + $hnsNetwork = Get-HnsNetwork | ? Name -EQ azure + if ($hnsNetwork.name -EQ "azure") { + return ("aks") + } + + # EKS + $hnsNetwork = Get-HnsNetwork | ? Name -like "vpcbr*" + if ($hnsNetwork.name -like "vpcbr*") { + return ("eks") + } + + # EC2 + $restError = $null + Try { + $awsNodeName=Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/local-hostname -ErrorAction Ignore + } Catch { + $restError = $_ + } + if ($restError -eq $null) { + return ("ec2") + } + + # GCE + $restError = $null + Try { + $gceNodeName = Invoke-RestMethod -UseBasicParsing -Headers @{"Metadata-Flavor"="Google"} "http://metadata.google.internal/computeMetadata/v1/instance/hostname" -ErrorAction Ignore + } Catch { + $restError = $_ + } + if ($restError -eq $null) { + return ("gce") + } + + return ("bare-metal") +} + +function GetBackendType() +{ + param( + [parameter(Mandatory=$true)] $CalicoNamespace, + [parameter(Mandatory=$false)] $KubeConfigPath = "$RootDir\calico-kube-config" + ) + + if (-Not [string]::IsNullOrEmpty($CalicoBackend)) { + return $CalicoBackend + } + + # Auto detect backend type + if ($Datastore -EQ "kubernetes") { + $encap=c:\k\kubectl.exe --kubeconfig="$RootDir\calico-kube-config" get felixconfigurations.crd.projectcalico.org default -o jsonpath='{.spec.ipipEnabled}' -n $CalicoNamespace + if ($encap -EQ "true") { + throw "{{.Product}} on Linux has IPIP enabled. IPIP is not supported on Windows nodes." + } + + $encap=c:\k\kubectl.exe --kubeconfig="$RootDir\calico-kube-config" get felixconfigurations.crd.projectcalico.org default -o jsonpath='{.spec.vxlanEnabled}' -n $CalicoNamespace + if ($encap -EQ "true") { + return ("vxlan") + } + return ("bgp") + } else { + $CalicoBackend=c:\k\kubectl.exe --kubeconfig="$RootDir\calico-kube-config" get configmap calico-config -n $CalicoNamespace -o jsonpath='{.data.calico_backend}' + if ($CalicoBackend -EQ "vxlan") { + return ("vxlan") + } + return ("bgp") + } +} + +function GetCalicoNamespace() { + param( + [parameter(Mandatory=$false)] $KubeConfigPath = "c:\\k\\config" + ) + + $name=c:\k\kubectl.exe --kubeconfig=$KubeConfigPath get ns calico-system + if ([string]::IsNullOrEmpty($name)) { + write-host "Calico running in kube-system namespace" + return ("kube-system") + } + write-host "Calico running in calico-system namespace" + return ("calico-system") +} + +function GetCalicoKubeConfig() +{ + param( + [parameter(Mandatory=$true)] $CalicoNamespace, + [parameter(Mandatory=$false)] $SecretName = "calico-node", + [parameter(Mandatory=$false)] $KubeConfigPath = "c:\\k\\config" + ) + + # On EKS, we need to have AWS tools loaded for kubectl authentication. + $eksAWSToolsModulePath="C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\AWSPowerShell.psd1" + if (Test-Path $eksAWSToolsModulePath) { + Write-Host "AWSPowerShell module exists, loading $eksAWSToolsModulePath ..." + Import-Module $eksAWSToolsModulePath + } + + $name=c:\k\kubectl.exe --kubeconfig=$KubeConfigPath get secret -n $CalicoNamespace --field-selector=type=kubernetes.io/service-account-token --no-headers -o custom-columns=":metadata.name" | findstr $SecretName | select -first 1 + if ([string]::IsNullOrEmpty($name)) { + throw "$SecretName service account does not exist." + } + $ca=c:\k\kubectl.exe --kubeconfig=$KubeConfigPath get secret/$name -o jsonpath='{.data.ca\.crt}' -n $CalicoNamespace + $tokenBase64=c:\k\kubectl.exe --kubeconfig=$KubeConfigPath get secret/$name -o jsonpath='{.data.token}' -n $CalicoNamespace + $token=[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($tokenBase64)) + + $server=findstr https:// $KubeConfigPath + + (Get-Content $RootDir\calico-kube-config.template).replace('', $ca).replace('', $server.Trim()).replace('', $token) | Set-Content $RootDir\calico-kube-config -Force +} + +function EnableWinDsrForEKS() +{ + $OSInfo = (Get-ComputerInfo | select WindowsVersion, OsBuildNumber) + $PlatformSupportDSR = (($OSInfo.WindowsVersion -as [int]) -GE 1903 -And ($OSInfo.OsBuildNumber -as [int]) -GE 18317) + + if (-Not $PlatformSupportDSR) { + Write-Host "WinDsr is not supported ($OSInfo)" + return + } + + # Update and restart kube-proxy if WinDSR is not enabled by default. + $Path = Get-CimInstance -Query 'select * from win32_service where name="kube-proxy"' | Select -ExpandProperty pathname + if ($Path -like "*--enable-dsr=true*") { + Write-Host "WinDsr is enabled by default." + } else { + $UpdatedPath = $Path + " --enable-dsr=true --feature-gates=WinDSR=true" + Get-CimInstance win32_service -filter 'Name="kube-proxy"' | Invoke-CimMethod -Name Change -ArgumentList @($null,$null,$null,$null,$null,$UpdatedPath) + Restart-Service -name "kube-proxy" + Write-Host "WinDsr has been enabled for kube-proxy." + } +} + +function SetupEtcdTlsFiles() +{ + param( + [parameter(Mandatory=$true)] $CalicoNamespace, + [parameter(Mandatory=$true)] $SecretName, + [parameter(Mandatory=$false)] $KubeConfigPath = "c:\\k\\config" + ) + + $path = "$RootDir\etcd-tls" + + $found=c:\k\kubectl.exe --kubeconfig=$KubeConfigPath get secret/$SecretName -n $CalicoNamespace + if ([string]::IsNullOrEmpty($found)) { + throw "$SecretName does not exist." + } + + $keyB64=c:\k\kubectl.exe --kubeconfig=$KubeConfigPath get secret/$SecretName -o jsonpath='{.data.etcd-key}' -n $CalicoNamespace + $certB64=c:\k\kubectl.exe --kubeconfig=$KubeConfigPath get secret/$SecretName -o jsonpath='{.data.etcd-cert}' -n $CalicoNamespace + $caB64=c:\k\kubectl.exe --kubeconfig=$KubeConfigPath get secret/$SecretName -o jsonpath='{.data.etcd-ca}' -n $CalicoNamespace + + New-Item -Type Directory -Path $path -Force + + [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($keyB64)) | Set-Content "$path\server.key" -Force + [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($certB64)) | Set-Content "$path\server.crt" -Force + [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($caB64)) | Set-Content "$path\ca.crt" -Force + + $script:EtcdKey = "$path\server.key" + $script:EtcdCert = "$path\server.crt" + $script:EtcdCaCert = "$path\ca.crt" +} + +function SetConfigParameters { + param( + [parameter(Mandatory=$true)] $OldString, + [parameter(Mandatory=$true)] $NewString + ) + + (Get-Content $RootDir\config.ps1).replace($OldString, $NewString) | Set-Content $RootDir\config.ps1 -Force +} + +function SetAKSCalicoStaticRules { + $fileName = [Io.path]::Combine("$RootDir", "static-rules.json") + echo '{ + "Provider": "AKS", + "Rules": [ + { + "Name": "EndpointPolicy", + "Rule": { + "Action": "Block", + "Direction": "Out", + "Id": "block-wireserver", + "Priority": 200, + "Protocol": 6, + "RemoteAddresses": "168.63.129.16/32", + "RemotePorts": "80", + "RuleType": "Switch", + "Type": "ACL" + } + } + ], + "version": "0.1.0" +}' | Out-File -encoding ASCII -filepath $fileName +} + +function StartCalico() +{ + Write-Host "`nStart {{.ProductName}}...`n" + + pushd + cd $RootDir + .\install-calico.ps1 + popd + Write-Host "`n{{.ProductName}} Started`n" +} + +$BaseDir="c:\k" +$RootDir="c:\{{.RootDir}}" +$CalicoZip="c:\{{.ZipFileName}}" + +# Must load the helper modules before doing anything else. +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$helper = "$BaseDir\helper.psm1" +$helperv2 = "$BaseDir\helper.v2.psm1" +md $BaseDir -ErrorAction Ignore +if (!(Test-Path $helper)) +{ + Invoke-WebRequest https://raw.githubusercontent.com/Microsoft/SDN/master/Kubernetes/windows/helper.psm1 -O $BaseDir\helper.psm1 +} +if (!(Test-Path $helperv2)) +{ + Invoke-WebRequest https://raw.githubusercontent.com/Microsoft/SDN/master/Kubernetes/windows/helper.v2.psm1 -O $BaseDir\helper.v2.psm1 +} +ipmo -force $helper +ipmo -force $helperv2 + +if (!(Test-Path $CalicoZip)) +{ +{{- if eq .Product "Calico Enterprise" }} + throw "Cannot find {{.ProductName}} zip file $CalicoZip." +{{- else if eq .Product "Calico" }} + Write-Host "$CalicoZip not found, downloading {{.ProductName}} release..." + DownloadFile -Url $ReleaseBaseURL/$ReleaseFile -Destination c:\calico-windows.zip +{{- else }} + throw "Invalid product name - did prodname in _config.yml change?" +{{- end }} +} + +$platform=GetPlatformType + +if (-Not [string]::IsNullOrEmpty($KubeVersion) -and $platform -NE "eks") { + PrepareKubernetes +} + +if ((Get-Service -exclude 'CalicoUpgrade' | where Name -Like 'Calico*' | where Status -EQ Running) -NE $null) { +Write-Host "Calico services are still running. In order to re-run the installation script, stop the CalicoNode and CalicoFelix services or uninstall them by running: $RootDir\uninstall-calico.ps1" +Exit +} + +Remove-Item $RootDir -Force -Recurse -ErrorAction SilentlyContinue +Write-Host "Unzip {{.ProductName}} release..." +Expand-Archive -Force $CalicoZip c:\ + +Write-Host "Setup {{.ProductName}}..." +SetConfigParameters -OldString '' -NewString $Datastore +SetConfigParameters -OldString '' -NewString "$EtcdEndpoints" + +if (-Not [string]::IsNullOrEmpty($EtcdTlsSecretName)) { + $calicoNs = GetCalicoNamespace + SetupEtcdTlsFiles -SecretName "$EtcdTlsSecretName" -CalicoNamespace $calicoNs +} +SetConfigParameters -OldString '' -NewString "$EtcdKey" +SetConfigParameters -OldString '' -NewString "$EtcdCert" +SetConfigParameters -OldString '' -NewString "$EtcdCaCert" +SetConfigParameters -OldString '' -NewString $ServiceCidr +SetConfigParameters -OldString '' -NewString $DNSServerIPs + +if ($platform -EQ "aks") { + Write-Host "Setup {{.ProductName}} for AKS..." + $Backend="none" + SetConfigParameters -OldString 'CALICO_NETWORKING_BACKEND="vxlan"' -NewString 'CALICO_NETWORKING_BACKEND="none"' + SetConfigParameters -OldString 'KUBE_NETWORK = "Calico.*"' -NewString 'KUBE_NETWORK = "azure.*"' + + $calicoNs = "calico-system" + GetCalicoKubeConfig -CalicoNamespace $calicoNs + + SetAKSCalicoStaticRules +} +if ($platform -EQ "eks") { + EnableWinDsrForEKS + + $token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "300"} -Method PUT -Uri http://169.254.169.254/latest/api/token -ErrorAction Ignore + $awsNodeName = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/local-hostname -ErrorAction Ignore + Write-Host "Setup Calico for Windows for EKS, node name $awsNodeName ..." + $Backend = "none" + $awsNodeNameQuote = """$awsNodeName""" + SetConfigParameters -OldString '$(hostname).ToLower()' -NewString "$awsNodeNameQuote" + SetConfigParameters -OldString 'CALICO_NETWORKING_BACKEND="vxlan"' -NewString 'CALICO_NETWORKING_BACKEND="none"' + SetConfigParameters -OldString 'KUBE_NETWORK = "Calico.*"' -NewString 'KUBE_NETWORK = "vpc.*"' + + $calicoNs = GetCalicoNamespace -KubeConfigPath C:\ProgramData\kubernetes\kubeconfig + GetCalicoKubeConfig -CalicoNamespace $calicoNs -KubeConfigPath C:\ProgramData\kubernetes\kubeconfig +} +if ($platform -EQ "ec2") { + $token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "300"} -Method PUT -Uri http://169.254.169.254/latest/api/token -ErrorAction Ignore + $awsNodeName = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/local-hostname -ErrorAction Ignore + Write-Host "Setup Calico for Windows for AWS, node name $awsNodeName ..." + $awsNodeNameQuote = """$awsNodeName""" + SetConfigParameters -OldString '$(hostname).ToLower()' -NewString "$awsNodeNameQuote" + + $calicoNs = GetCalicoNamespace + GetCalicoKubeConfig -CalicoNamespace $calicoNs + $Backend = GetBackendType -CalicoNamespace $calicoNs + + Write-Host "Backend networking is $Backend" + if ($Backend -EQ "bgp") { + SetConfigParameters -OldString 'CALICO_NETWORKING_BACKEND="vxlan"' -NewString 'CALICO_NETWORKING_BACKEND="windows-bgp"' + } +} +if ($platform -EQ "gce") { + $gceNodeName = Invoke-RestMethod -UseBasicParsing -Headers @{"Metadata-Flavor"="Google"} "http://metadata.google.internal/computeMetadata/v1/instance/hostname" -ErrorAction Ignore + Write-Host "Setup {{.ProductName}} for GCE, node name $gceNodeName ..." + $gceNodeNameQuote = """$gceNodeName""" + SetConfigParameters -OldString '$(hostname).ToLower()' -NewString "$gceNodeNameQuote" + + $calicoNs = GetCalicoNamespace + GetCalicoKubeConfig -CalicoNamespace $calicoNs + $Backend = GetBackendType -CalicoNamespace $calicoNs + + Write-Host "Backend networking is $Backend" + if ($Backend -EQ "bgp") { + SetConfigParameters -OldString 'CALICO_NETWORKING_BACKEND="vxlan"' -NewString 'CALICO_NETWORKING_BACKEND="windows-bgp"' + } +} +if ($platform -EQ "bare-metal") { + $calicoNs = GetCalicoNamespace + GetCalicoKubeConfig -CalicoNamespace $calicoNs + $Backend = GetBackendType -CalicoNamespace $calicoNs + + Write-Host "Backend networking is $Backend" + if ($Backend -EQ "bgp") { + SetConfigParameters -OldString 'CALICO_NETWORKING_BACKEND="vxlan"' -NewString 'CALICO_NETWORKING_BACKEND="windows-bgp"' + } +} + +if ($DownloadOnly -EQ "yes") { + Write-Host "Downloaded {{.ProductName}}. Update c:\{{.RootDir}}\config.ps1 and run c:\CalicoWindows\install-calico.ps1" + Exit +} + +StartCalico + +if ($Backend -NE "none") { + New-NetFirewallRule -Name KubectlExec10250 -Description "Enable kubectl exec and log" -Action Allow -LocalPort 10250 -Enabled True -DisplayName "kubectl exec 10250" -Protocol TCP -ErrorAction SilentlyContinue +}