Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Az.ConnectedKubernetes] support proxy environments and fix issues (from generation) #20955

Merged
merged 18 commits into from
Feb 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 159 additions & 17 deletions src/ConnectedKubernetes/custom/New-AzConnectedKubernetes.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,55 @@ function New-AzConnectedKubernetes {
# The ID of the target subscription.
${SubscriptionId},

[Parameter()]
[Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.Category('Path')]
[System.Uri]
# The http URI of the proxy server for the kubernetes cluster to use
${HttpProxy},

[Parameter()]
[Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.Category('Path')]
[System.Uri]
# The https URI of the proxy server for the kubernetes cluster to use
${HttpsProxy},

[Parameter()]
[Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.Category('Path')]
[System.String]
# The comma-separated list of hostnames that should be excluded from the proxy server for the kubernetes cluster to use
${NoProxy},

[Parameter()]
[Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.Category('Path')]
[System.String]
# The path to the certificate file for proxy or custom Certificate Authority.
${ProxyCert},

[Parameter()]
[Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.Category('Path')]
[ValidateRange(0,3600)]
[Int]
# The time required (in seconds) for the arc-agent pods to be installed on the kubernetes cluster.
${OnboardingTimeout} = 600,

[Parameter()]
[Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.Category('Path')]
[System.Management.Automation.SwitchParameter]
# Flag to disable auto upgrade of arc agents.
${DisableAutoUpgrade},

[Parameter()]
[Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.Category('Path')]
[System.String]
# Override the default container log path to enable fluent-bit logging.
${ContainerLogPath},

[Parameter(HelpMessage="Path to the kube config file")]
[Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.Category('Body')]
[System.String]
# Path to the kube config file
${KubeConfig},

[Parameter(HelpMessage="Kubconfig context from current machine")]
[Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.Category('Body')]
[System.String]
Expand Down Expand Up @@ -172,14 +215,14 @@ function New-AzConnectedKubernetes {
[Parameter(DontShow)]
[Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.Category('Runtime')]
[System.Uri]
# The URI for the proxy server to use
# The URI of the proxy server for host os to use
${Proxy},

[Parameter(DontShow)]
[ValidateNotNull()]
[Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.Category('Runtime')]
[System.Management.Automation.PSCredential]
# Credentials for a proxy server to use for the remote call
# The credential of the proxy server for host os to use
${ProxyCredential},

[Parameter(DontShow)]
Expand Down Expand Up @@ -224,7 +267,7 @@ function New-AzConnectedKubernetes {
if ($PSBoundParameters.ContainsKey('KubeContext')) {
$Null = $PSBoundParameters.Remove('KubeContext')
}
if (($KubeContext -eq $null) -or ($KubeContext -eq '')) {
if (($null -eq $KubeContext) -or ($KubeContext -eq '')) {
$KubeContext = kubectl config current-context
}

Expand Down Expand Up @@ -260,9 +303,10 @@ function New-AzConnectedKubernetes {
#EndRegion

#Region get release namespace
Set-Variable ReleaseInstallNamespace -option Constant -value "azure-arc-release"
$ReleaseNamespace = $null
try {
$ReleaseNamespace = (helm status azure-arc -o json --kubeconfig $KubeConfig --kube-context $KubeContext | ConvertFrom-Json).namespace
$ReleaseNamespace = (helm status azure-arc -o json --kubeconfig $KubeConfig --kube-context $KubeContext -n $ReleaseInstallNamespace | ConvertFrom-Json).namespace
} catch {
Write-Error "Fail to find the namespace for azure-arc."
}
Expand Down Expand Up @@ -292,7 +336,12 @@ function New-AzConnectedKubernetes {
$HelmRepoUrl = Get-ChildItem -Path Env:HELMREPOURL
helm repo add $HelmRepoName $HelmRepoUrl --kubeconfig $KubeConfig --kube-context $KubeContext
}


$resources = Get-Module Az.Resources -ListAvailable
if ($null -eq $resources) {
Write-Error "Missing required module(s): Az.Resources. Please run 'Install-Module Az.Resources -Repository PSGallery' to install Az.Resources."
return
}
if (Test-Path Env:HELMREGISTRY) {
$RegisteryPath = Get-ChildItem -Path Env:HELMREGISTRY
} else {
Expand All @@ -301,7 +350,15 @@ function New-AzConnectedKubernetes {
$ReleaseTrain = Get-ChildItem -Path Env:RELEASETRAIN
} else {
$ReleaseTrain = 'stable'
}
}
$AzLocation = Get-AzLocation | Where-Object { ($_.DisplayName -ieq $Location) -or ($_.Location -ieq $Location)}
$Region = $AzLocation.Location
if ($null -eq $Region) {
Write-Error "Invalid location: $Location"
return
} else {
$Location = $Region
}
$ChartLocationUrl = "https://${Location}.dp.kubernetesconfiguration.azure.com/azure-arc-k8sagents/GetLatestHelmPackagePath?api-version=2019-11-01-preview&releaseTrain=${ReleaseTrain}"

$Uri = [System.Uri]::New($ChartLocationUrl)
Expand All @@ -315,21 +372,20 @@ function New-AzConnectedKubernetes {
$HeaderParameter = @{
"Authorization" = "Bearer $AccessToken"
}
$Response = Invoke-WebRequest -Uri $Uri -Headers $HeaderParameter -Method Post
$Response = Invoke-WebRequest -Uri $Uri -Headers $HeaderParameter -Method Post -UseBasicParsing
if ($Response.StatusCode -eq 200) {
$RegisteryPath = ($Response.Content | ConvertFrom-Json).repositoryPath
} else {
Write-Error "Error while fetching helm chart registry path: ${$Response.RawContent}"
throw
throw "Error while fetching helm chart registry path: ${$Response.RawContent}"

}
}
Set-Item -Path Env:HELM_EXPERIMENTAL_OCI -Value 1
#Region pull helm chart
try {
helm chart pull $RegisteryPath --kubeconfig $KubeConfig --kube-context $KubeContext
} catch {
Write-Error "Unable to pull helm chart from the registery $RegisteryPath"
throw
throw "Unable to pull helm chart from the registery $RegisteryPath"
}
#Endregion

Expand All @@ -349,21 +405,107 @@ function New-AzConnectedKubernetes {
#Endregion

$RSA = [System.Security.Cryptography.RSA]::Create(4096)
$AgentPublicKey = [System.Convert]::ToBase64String($RSA.ExportRSAPublicKey())
$AgentPrivateKey = "-----BEGIN RSA PRIVATE KEY-----`n" + [System.Convert]::ToBase64String($RSA.ExportRSAPrivateKey()) + "`n-----END RSA PRIVATE KEY-----"

if ($PSVersionTable.PSVersion.Major -eq 5) {
try {
. "$PSScriptRoot/RSAHelper.ps1"
$AgentPublicKey = ExportRSAPublicKeyBase64($RSA)
$AgentPrivateKey = ExportRSAPrivateKeyBase64($RSA)
$AgentPrivateKey = "-----BEGIN RSA PRIVATE KEY-----`n" + $AgentPrivateKey + "`n-----END RSA PRIVATE KEY-----"
} catch {
throw "Unable to generate RSA keys"
}
} else {
$AgentPublicKey = [System.Convert]::ToBase64String($RSA.ExportRSAPublicKey())
$AgentPrivateKey = "-----BEGIN RSA PRIVATE KEY-----`n" + [System.Convert]::ToBase64String($RSA.ExportRSAPrivateKey()) + "`n-----END RSA PRIVATE KEY-----"
}

$HelmChartPath = Join-Path -Path $ChartExportPath -ChildPath 'azure-arc-k8sagents'
if (Test-Path Env:HELMCHART) {
$ChartPath = Get-ChildItem -Path Env:HELMCHART
} else {
$ChartPath = $HelmChartPath
}

#Region helm options
$options = ""
$proxyEnableState = $false
if (-not ([string]::IsNullOrEmpty($HttpProxy))) {
$HttpProxyStr = $HttpProxy.ToString()
$HttpProxyStr = $HttpProxyStr -replace ',','\,'
$HttpProxyStr = $HttpProxyStr -replace '/','\/'
$options += " --set global.httpProxy=$HttpProxyStr"
$proxyEnableState = $true
$Null = $PSBoundParameters.Remove('HttpProxy')
}
if (-not ([string]::IsNullOrEmpty($HttpsProxy))) {
$HttpsProxyStr = $HttpsProxy.ToString()
$HttpsProxyStr = $HttpsProxyStr -replace ',','\,'
$HttpsProxyStr = $HttpsProxyStr -replace '/','\/'
$options += " --set global.httpsProxy=$HttpsProxyStr"
$proxyEnableState = $true
$Null = $PSBoundParameters.Remove('HttpsProxy')
}
if (-not ([string]::IsNullOrEmpty($NoProxy))) {
$NoProxy = $NoProxy -replace ',','\,'
$NoProxy = $NoProxy -replace '/','\/'
$options += " --set global.noProxy=$NoProxy"
$proxyEnableState = $true
$Null = $PSBoundParameters.Remove('NoProxy')
}
if ($proxyEnableState) {
$options += " --set global.isProxyEnabled=true"
}
try {
if ((-not ([string]::IsNullOrEmpty($ProxyCert))) -and (Test-Path $ProxyCert)) {
$options += " --set-file global.proxyCert=$ProxyCert"
$options += " --set global.isCustomCert=true"
}
} catch {
throw "Unable to find ProxyCert from file path"
}
if ($DisableAutoUpgrade) {
$options += " --set systemDefaultValues.azureArcAgents.autoUpdate=false"
$Null = $PSBoundParameters.Remove('DisableAutoUpgrade')
}
if (-not ([string]::IsNullOrEmpty($ContainerLogPath))) {
$options += " --set systemDefaultValues.fluent-bit.containerLogPath=$ContainerLogPath"
$Null = $PSBoundParameters.Remove('ContainerLogPath')
}
if (-not ([string]::IsNullOrEmpty($KubeConfig))) {
$options += " --kubeconfig $KubeConfig"
}
if (-not ([string]::IsNullOrEmpty($KubeContext))) {
$options += " --kube-context $KubeContext"
}
if (!$NoWait) {
$options += " --wait --timeout $OnboardingTimeout"
$options += "s"
}
#Endregion
if ($PSBoundParameters.ContainsKey('OnboardingTimeout')) {
$PSBoundParameters.Remove('OnboardingTimeout')
}
if ((-not ([string]::IsNullOrEmpty($Proxy))) -and (-not $PSBoundParameters.ContainsKey('ProxyCredential'))) {
if (-not ([string]::IsNullOrEmpty($Proxy.UserInfo))) {
try{
$userInfo = $Proxy.UserInfo -Split ':'
$pass = ConvertTo-SecureString $userInfo[1] -AsPlainText -Force
$ProxyCredential = New-Object System.Management.Automation.PSCredential ($userInfo[0] , $pass)
$PSBoundParameters.Add('ProxyCredential', $ProxyCredential)
} catch {
Write-Warning "Please set ProxyCredential or provide username and password in the Proxy parameter"
throw
}
} else {
Write-Warning "If the proxy is a private proxy, pass ProxyCredential parameter or provide username and password in the Proxy parameter"
}
}

$PSBoundParameters.Add('AgentPublicKeyCertificate', $AgentPublicKey)
$Response = Az.ConnectedKubernetes.internal\New-AzConnectedKubernetes @PSBoundParameters

$TenantId = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext.Tenant.Id
helm upgrade --install azure-arc $ChartPath --set global.subscriptionId=$SubscriptionId --set global.resourceGroupName=$ResourceGroupName --set global.resourceName=$ClusterName --set global.tenantId=$TenantId --set global.location=$Location --set global.onboardingPrivateKey=$AgentPrivateKey --set systemDefaultValues.spnOnboarding=false --set global.azureEnvironment=AZUREPUBLICCLOUD --set systemDefaultValues.clusterconnect-agent.enabled=true --set global.kubernetesDistro=$Distribution --set global.kubernetesInfra=$Infrastructure --kubeconfig $KubeConfig --kube-context $KubeContext --wait --timeout 600s
$TenantId = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext.Tenant.Id
helm upgrade --install azure-arc $ChartPath --namespace $ReleaseInstallNamespace --create-namespace --set global.subscriptionId=$SubscriptionId --set global.resourceGroupName=$ResourceGroupName --set global.resourceName=$ClusterName --set global.tenantId=$TenantId --set global.location=$Location --set global.onboardingPrivateKey=$AgentPrivateKey --set systemDefaultValues.spnOnboarding=false --set global.azureEnvironment=AZUREPUBLICCLOUD --set systemDefaultValues.clusterconnect-agent.enabled=true --set global.kubernetesDistro=$Distribution --set global.kubernetesInfra=$Infrastructure (-split $options)
Return $Response
}
}
2 changes: 1 addition & 1 deletion src/ConnectedKubernetes/custom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ These provide functionality to our HTTP pipeline and other useful features. In s
### Attributes
For processing the cmdlets, we've created some additional attributes:
- `Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.DescriptionAttribute`
- Used in C# cmdlets to provide a high-level description of the cmdlet. This is propagated to reference documentation via [help comments](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_comment_based_help) in the exported scripts.
- Used in C# cmdlets to provide a high-level description of the cmdlet. This is propagated to reference documentation via [help comments](https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_comment_based_help) in the exported scripts.
- `Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.DoNotExportAttribute`
- Used in C# and script cmdlets to suppress creating an exported cmdlet at build-time. These cmdlets will *not be exposed* by `Az.ConnectedKubernetes`.
- `Microsoft.Azure.PowerShell.Cmdlets.ConnectedKubernetes.InternalExportAttribute`
Expand Down
Loading