import { window } from 'vscode' ; import { kubernetesTools } from '../kubernetes/kubernetesTools' ; import { ClusterProvider , ConfigMap } from '../kubernetes/kubernetesTypes' ; import { shell , ShellResult } from '../shell' ; import { parseJson } from '../utils/jsonUtils' ; import { ClusterContextNode } from '../views/nodes/clusterContextNode' ; import { askUserForAzureMetadata } from './getAzureMetadata' ; export type AzureClusterProvider = ClusterProvider . AKS | ClusterProvider . AzureARC ; /**
 * Return true when the cluster provider is either AKS or Azure Arc.
 */ export function isAzureProvider ( provider ) { return provider === ClusterProvider . AKS || provider === ClusterProvider . AzureARC ; } export const enum AzureConstants { ArcNamespace = 'azure-arc' , KubeSystemNamespace = 'kube-system' , FluxExtensionName = 'flux' } class AzureTools { param command param clusterNode param clusterProvider private async invokeAzCommand ( command , contextName , clusterProvider ) { let azureMetadata = await this . getAzureMetadata ( contextName , clusterProvider ) ; if ( ! azureMetadata ) { window . showWarningMessage ( 'Failed to get Azure resource name or resource group or subscription ID.' ) ; azureMetadata = await askUserForAzureMetadata ( contextName ) ; } if ( ! azureMetadata ) { return ; } const clusterType = clusterProvider === ClusterProvider . AKS ? 'managedClusters' : 'connectedClusters' ; const metadata = `--cluster-name ${ azureMetadata . resourceName } --cluster-type ${ clusterType } --resource-group ${ azureMetadata . resourceGroup } --subscription ${ azureMetadata . subscriptionId }` ; return await shell . execWithOutput ( `${ command } ${ metadata }` ) ; } param clusterNode param clusterProvider async getAzureMetadata ( contextName , clusterProvider ) { let configMapShellResult ; if ( clusterProvider === ClusterProvider . AKS ) { configMapShellResult = await kubernetesTools . invokeKubectlCommand ( `get configmaps extension-manager-config -n ${ AzureConstants . KubeSystemNamespace } --context=${ contextName } --ignore-not-found -o json` ) ; } else { configMapShellResult = await kubernetesTools . invokeKubectlCommand ( `get configmaps azure-clusterconfig -n ${ AzureConstants . ArcNamespace } --context=${ contextName } --ignore-not-found -o json` ) ; } if ( configMapShellResult ?. code !== 0 ) { return ; } const configMap = parseJson ( configMapShellResult . stdout ) ; if ( configMap === undefined ) { return ; } const result = { resourceGroup : configMap . data [ 'AZURE_RESOURCE_GROUP' ] , resourceName : configMap . data [ 'AZURE_RESOURCE_NAME' ] , subscriptionId : configMap . data [ 'AZURE_SUBSCRIPTION_ID' ] , } ; if ( ! result . resourceGroup || ! result . resourceName || ! result . subscriptionId ) { return ; } return result ; } see https param clusterNode param clusterProvider async enableGitOps ( clusterNode , clusterProvider ) { await this . invokeAzCommand ( `az k8s-extension create --name ${ AzureConstants . FluxExtensionName } --extension-type microsoft.flux --scope cluster` , clusterNode . contextName , clusterProvider ) ; } see https param clusterNode param clusterProvider async disableGitOps ( clusterNode , clusterProvider ) { const fluxConfigurations = await this . listFluxConfigurations ( clusterNode , clusterProvider ) ; if ( ! fluxConfigurations ) { return ; } const namesOfFluxConfigs = fluxConfigurations . map ( ( configuration ) => configuration . name ) ; await Promise . all ( namesOfFluxConfigs . map ( fluxConfigName => this . invokeAzCommand ( `az k8s-configuration flux delete -n ${ fluxConfigName } --yes` , clusterNode . contextName , clusterProvider ) ) ) ; await this . invokeAzCommand ( `az k8s-extension delete --name ${ AzureConstants . FluxExtensionName } --yes` , clusterNode . contextName , clusterProvider ) ; } see https param clusterNode param clusterProvider private async listFluxConfigurations ( clusterNode , clusterProvider ) { const configurationShellResult = await this . invokeAzCommand ( 'az k8s-configuration flux list' , clusterNode . contextName , clusterProvider ) ; if ( configurationShellResult ?. code !== 0 ) { return ; } return parseJson ( configurationShellResult . stdout ) ; } see https param newGitRepositorySourceName param gitUrl param gitBranch param isSSH param clusterNode param clusterProvider param kustomizationName param kustomizationPath async createGitRepository ( newGitRepositorySourceName , gitUrl , gitBranch , isSSH , clusterNode , clusterProvider , kustomizationName ? , kustomizationPath ? ) { let kustomizationQueryPart = '' ; if ( kustomizationName !== undefined && kustomizationPath !== undefined ) { kustomizationQueryPart = `--kustomization name=${ kustomizationName } path=${ kustomizationPath } prune=true` ; } const gitCreateShellResult = await this . invokeAzCommand ( `az k8s-configuration flux create -n ${ newGitRepositorySourceName } --scope cluster -u ${ gitUrl } --branch ${ gitBranch } ${ kustomizationQueryPart }` , clusterNode . contextName , clusterProvider ) ; if ( ! isSSH || gitCreateShellResult ?. code !== 0 ) { return ; } const output = parseJson ( gitCreateShellResult . stdout ) ; if ( ! output ) { return ; } return { deployKey : output . repositoryPublicKey , } ; } see https param kustomizationName param gitRepositoryName param kustomizationPath async createKustomization ( kustomizationName , gitRepositoryName , kustomizationPath , clusterNode , clusterProvider ) { const createKustomizationShellResult = await this . invokeAzCommand ( `az k8s-configuration flux kustomization create --kustomization-name ${ kustomizationName } --name ${ gitRepositoryName } --path "${ kustomizationPath }" --prune true` , clusterNode . contextName , clusterProvider ) ; if ( createKustomizationShellResult ?. code !== 0 ) { window . showErrorMessage ( createKustomizationShellResult ?. stderr || '' ) ; return ; } } see https async createSourceGit2 ( args ) { const urlArg = ` --url "${ args . url }"` ; const branchArg = args . branch ? ` --branch "${ args . branch }"` : '' ; const tagArg = args . tag ? ` --tag "${ args . tag }"` : '' ; const semverArg = args . semver ? ` --semver "${ args . semver }"` : '' ; const commitArg = args . commit ? ` --commit "${ args . commit }"` : '' ; const intervalArg = args . interval ? ` --interval "${ args . interval }"` : '' ; const timeoutArg = args . timeout ? ` --timeout "${ args . timeout }"` : '' ; const caCertArg = args . caCert ? ` --https-ca-cert "${ args . caCert }"` : '' ; const caCertFileArg = args . caCertFile ? ` --https-ca-cert-file "${ args . caCertFile }"` : '' ; const httpsKeyArg = args . httpsKey ? ` --https-key "${ args . httpsKey }"` : '' ; const httpsUserArg = args . httpsUser ? ` --https-user "${ args . httpsUser }"` : '' ; const knownHostsArg = args . knownHosts ? ` --known-hosts "${ args . knownHosts }"` : '' ; const knownHostsFileArg = args . knownHostsFile ? ` --known-hosts-file "${ args . knownHostsFile }"` : '' ; const localAuthRefArg = args . localAuthRef ? ` --local-auth-ref "${ args . localAuthRef }"` : '' ; const sshPrivateKeyArg = args . sshPrivateKey ? ` --ssh-private-key "${ args . sshPrivateKey }"` : '' ; const sshPrivateKeyFileArg = args . sshPrivateKeyFile ? ` --ssh-private-key-file "${ args . sshPrivateKeyFile }"` : '' ; let kustomizationPart = '' ; const kustomizationName = args . kustomizationName ? ` name="${ args . kustomizationName }"` : '' ; const kustomizationPath = args . kustomizationPath ? ` path="${ args . kustomizationPath }"` : '' ; const kustomizationDependsOn = args . kustomizationDependsOn ? ` depends_on="${ args . kustomizationDependsOn }"` : '' ; const kustomizationTimeout = args . kustomizationTimeout ? ` timeout="${ args . kustomizationTimeout }"` : '' ; const kustomizationSyncInterval = args . kustomizationSyncInterval ? ` sync_interval="${ args . kustomizationSyncInterval }"` : '' ; const kustomizationRetryInterval = args . kustomizationRetryInterval ? ` retry_interval="${ args . kustomizationRetryInterval }"` : '' ; const kustomizationPrune = args . kustomizationPrune ? ' prune=true' : '' ; const kustomizationForce = args . kustomizationForce ? ' force=true' : '' ; if ( kustomizationName || kustomizationPath || kustomizationDependsOn || kustomizationTimeout || kustomizationSyncInterval || kustomizationRetryInterval || kustomizationPrune || kustomizationForce ) { kustomizationPart = ` --kustomization${ kustomizationName }${ kustomizationPath }${ kustomizationDependsOn }${ kustomizationTimeout }${ kustomizationSyncInterval }${ kustomizationRetryInterval }${ kustomizationPrune }${ kustomizationForce }` ; } const createSourceShellResult = await this . invokeAzCommand ( `az k8s-configuration flux create -n ${ args . sourceName }${ urlArg }${ branchArg }${ tagArg }${ semverArg }${ commitArg }${ intervalArg }${ timeoutArg }${ caCertArg }${ caCertFileArg }${ httpsKeyArg }${ httpsUserArg }${ knownHostsArg }${ knownHostsFileArg }${ localAuthRefArg }${ sshPrivateKeyArg }${ sshPrivateKeyFileArg }${ kustomizationPart }` , args . contextName , args . clusterProvider ) ; if ( createSourceShellResult ?. code !== 0 || args . sourceKind !== 'git' ) { return ; } const createSourceOutput = parseJson ( createSourceShellResult . stdout ) ; if ( ! createSourceOutput ) { return ; } const deployKey = createSourceOutput . repositoryPublicKey ; if ( ! deployKey ) { return ; } return { deployKey , } ; } see https param sourceName param clusterNode param clusterProvider async deleteSource ( sourceName , clusterNode , clusterProvider ) { await this . invokeAzCommand ( `az k8s-configuration flux delete -n ${ sourceName } --yes` , clusterNode . contextName , clusterProvider ) ; } see https param sourceName param clusterNode param clusterProvider async suspend ( sourceName , clusterNode , clusterProvider ) { await this . invokeAzCommand ( `az k8s-configuration flux update -n ${ sourceName } --suspend true` , clusterNode . contextName , clusterProvider ) ; } see https param sourceName param clusterNode param clusterProvider async resume ( sourceName , clusterNode , clusterProvider ) { await this . invokeAzCommand ( `az k8s-configuration flux update -n ${ sourceName } --suspend false` , clusterNode . contextName , clusterProvider ) ; } } /**
 * Helper methods for running `az` commands.
 */ export const azureTools = new AzureTools ( ) ;