Skip to content

Commit

Permalink
Added Back Azure Deploy to ACA & Azure Deploy to AAS (#4038)
Browse files Browse the repository at this point in the history
* added back basic implementation of deploy ACA

* saving progress

* added step for selecting subscriptions

* small tweaks

* progress on deploy image to azure app service

* improved azure subscription selection experience

* actually made deploy image to AAS work

* remove accidetal change to settings.json

* fix small mistake

* fixed more mistakes

* fix more mistakes

* fixed even more mistakes...
  • Loading branch information
alexyaang authored Aug 23, 2023
1 parent 6df7928 commit ea8f0bc
Show file tree
Hide file tree
Showing 15 changed files with 759 additions and 591 deletions.
208 changes: 184 additions & 24 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -516,12 +516,12 @@
},
{
"command": "vscode-docker.registries.deployImageToAzure",
"when": "view == dockerRegistries && viewItem =~ /(DockerV2|DockerHubV2);Tag;/ && isAzureAccountInstalled",
"when": "view == dockerRegistries && viewItem =~ /commontag/i",
"group": "regs_tag_1_general@4"
},
{
"command": "vscode-docker.registries.deployImageToAca",
"when": "view == dockerRegistries && viewItem =~ /(DockerV2|DockerHubV2|GitLabV4);Tag;/ && isAzureAccountInstalled",
"when": "view == dockerRegistries && viewItem =~ /commontag/i",
"group": "regs_tag_1_general@6"
},
{
Expand Down Expand Up @@ -3030,10 +3030,10 @@
"@azure/arm-containerregistry": "^10.1.0",
"@azure/storage-blob": "^12.14.0",
"@microsoft/compose-language-service": "^0.2.0",
"@microsoft/vscode-azext-azureappservice": "^1.0.2",
"@microsoft/vscode-azext-azureappservice": "^2.2.0",
"@microsoft/vscode-azext-azureauth": "^1.1.2",
"@microsoft/vscode-azext-azureutils": "^1.1.5",
"@microsoft/vscode-azext-utils": "^1.2.2",
"@microsoft/vscode-azext-azureutils": "^2.0.1",
"@microsoft/vscode-azext-utils": "^2.0.1",
"@microsoft/vscode-container-client": "^0.1.0",
"@microsoft/vscode-docker-registries": "file:../vscode-docker-extensibility/packages/vscode-docker-registries/microsoft-vscode-docker-registries-0.0.1-alpha.tgz",
"dayjs": "^1.11.7",
Expand Down
6 changes: 4 additions & 2 deletions src/commands/registerCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ import { registerWorkspaceCommand } from "./registerWorkspaceCommand";
import { createAzureRegistry } from "./registries/azure/createAzureRegistry";
import { deleteAzureRegistry } from "./registries/azure/deleteAzureRegistry";
import { deleteAzureRepository } from "./registries/azure/deleteAzureRepository";
import { deployImageToAca } from "./registries/azure/deployImageToAca";
import { deployImageToAzure } from "./registries/azure/deployImageToAzure";
import { openInAzurePortal } from "./registries/azure/openInAzurePortal";
import { buildImageInAzure } from "./registries/azure/tasks/buildImageInAzure";
import { runAzureTask } from "./registries/azure/tasks/runAzureTask";
Expand Down Expand Up @@ -164,8 +166,8 @@ export function registerCommands(): void {
registerCommand('vscode-docker.registries.copyImageDigest', copyRemoteImageDigest);
registerCommand('vscode-docker.registries.copyRemoteFullTag', copyRemoteFullTag);
// registerCommand('vscode-docker.registries.deleteImage', deleteRemoteImage);
// registerCommand('vscode-docker.registries.deployImageToAzure', deployImageToAzure);
// registerCommand('vscode-docker.registries.deployImageToAca', deployImageToAca);
registerCommand('vscode-docker.registries.deployImageToAzure', deployImageToAzure);
registerCommand('vscode-docker.registries.deployImageToAca', deployImageToAca);
registerCommand('vscode-docker.registries.disconnectRegistry', disconnectRegistry);
registerCommand('vscode-docker.registries.help', registryHelp);
registerWorkspaceCommand('vscode-docker.registries.logInToDockerCli', logInToDockerCli);
Expand Down
180 changes: 91 additions & 89 deletions src/commands/registries/azure/DockerAssignAcrPullRoleStep.ts
Original file line number Diff line number Diff line change
@@ -1,89 +1,91 @@
// /*---------------------------------------------------------------------------------------------
// * Copyright (c) Microsoft Corporation. All rights reserved.
// * Licensed under the MIT License. See LICENSE.md in the project root for license information.
// *--------------------------------------------------------------------------------------------*/

// import type { IAppServiceWizardContext } from "@microsoft/vscode-azext-azureappservice"; // These are only dev-time imports so don't need to be lazy
// import { AzureWizardExecuteStep } from "@microsoft/vscode-azext-utils";
// import { randomUUID } from "crypto";
// import { l10n, Progress } from "vscode";
// import { ext } from "../../../extensionVariables";
// import { AzureRegistryTreeItem } from '../../../tree/registries/azure/AzureRegistryTreeItem';
// import { RemoteTagTreeItem } from '../../../tree/registries/RemoteTagTreeItem';
// import { getArmAuth, getArmContainerRegistry, getAzExtAppService, getAzExtAzureUtils } from "../../../utils/lazyPackages";

// export class DockerAssignAcrPullRoleStep extends AzureWizardExecuteStep<IAppServiceWizardContext> {
// public priority: number = 141; // execute after DockerSiteCreateStep

// public constructor(private readonly tagTreeItem: RemoteTagTreeItem) {
// super();
// }

// public async execute(context: IAppServiceWizardContext, progress: Progress<{ message?: string; increment?: number }>): Promise<void> {
// const message: string = l10n.t('Granting permission for App Service to pull image from ACR...');
// ext.outputChannel.info(message);
// progress.report({ message: message });

// const azExtAzureUtils = await getAzExtAzureUtils();
// const vscAzureAppService = await getAzExtAppService();
// const armAuth = await getArmAuth();
// const armContainerRegistry = await getArmContainerRegistry();
// const authClient = azExtAzureUtils.createAzureClient(context, armAuth.AuthorizationManagementClient);
// const crmClient = azExtAzureUtils.createAzureClient(context, armContainerRegistry.ContainerRegistryManagementClient);
// const appSvcClient = await vscAzureAppService.createWebSiteClient(context);

// // If we're in `execute`, then `shouldExecute` passed and `this.tagTreeItem.parent.parent` is guaranteed to be an AzureRegistryTreeItem
// const registryTreeItem: AzureRegistryTreeItem = this.tagTreeItem.parent.parent as unknown as AzureRegistryTreeItem;

// // 1. Get the registry resource. We will need the ID.
// const registry = await crmClient.registries.get(registryTreeItem.resourceGroup, registryTreeItem.registryName);

// if (!(registry?.id)) {
// throw new Error(
// l10n.t('Unable to get details from Container Registry {0}', registryTreeItem.baseUrl)
// );
// }

// // 2. Get the role definition for the AcrPull role. We will need the definition ID. This role is built-in and should always exist.
// const acrPullRoleDefinition = (await azExtAzureUtils.uiUtils.listAllIterator(authClient.roleDefinitions.list(registry.id, { filter: `roleName eq 'AcrPull'` })))[0];

// if (!(acrPullRoleDefinition?.id)) {
// throw new Error(
// l10n.t('Unable to get AcrPull role definition on subscription {0}', context.subscriptionId)
// );
// }

// // 3. Get the info for the now-created web site. We will need the principal ID.
// const siteInfo = await appSvcClient.webApps.get(context.site.resourceGroup, context.site.name);

// if (!(siteInfo?.identity?.principalId)) {
// throw new Error(
// l10n.t('Unable to get identity principal ID for web site {0}', context.site.name)
// );
// }

// // 4. On the registry, assign the AcrPull role to the principal representing the website
// await authClient.roleAssignments.create(registry.id, randomUUID(), {
// principalId: siteInfo.identity.principalId,
// roleDefinitionId: acrPullRoleDefinition.id,
// principalType: 'ServicePrincipal',
// });

// // 5. Set the web app to use the desired ACR image, which was not done in DockerSiteCreateStep. Get the config and then update it.
// const config = await appSvcClient.webApps.getConfiguration(context.site.resourceGroup, context.site.name);

// if (!config) {
// throw new Error(
// l10n.t('Unable to get configuration for web site {0}', context.site.name)
// );
// }

// config.linuxFxVersion = `DOCKER|${this.tagTreeItem.fullTag}`;
// await appSvcClient.webApps.updateConfiguration(context.site.resourceGroup, context.site.name, config);
// }

// public shouldExecute(context: IAppServiceWizardContext): boolean {
// return !!(context.site) && !!(this.tagTreeItem?.parent?.parent) && this.tagTreeItem.parent.parent instanceof AzureRegistryTreeItem
// && !context.customLocation;
// }
// }
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import type { IAppServiceWizardContext } from "@microsoft/vscode-azext-azureappservice"; // These are only dev-time imports so don't need to be lazy
import { AzureWizardExecuteStep } from "@microsoft/vscode-azext-utils";
import { CommonTag } from "@microsoft/vscode-docker-registries";
import { randomUUID } from "crypto";
import { Progress, l10n } from "vscode";
import { ext } from "../../../extensionVariables";
import { AzureRegistry, isAzureTagItem } from "../../../tree/registries/Azure/AzureRegistryDataProvider";
import { UnifiedRegistryItem } from "../../../tree/registries/UnifiedRegistryTreeDataProvider";
import { getFullImageNameFromRegistryTagItem, getResourceGroupFromAzureRegistryItem } from "../../../tree/registries/registryTreeUtils";
import { getArmAuth, getArmContainerRegistry, getAzExtAppService, getAzExtAzureUtils } from "../../../utils/lazyPackages";

export class DockerAssignAcrPullRoleStep extends AzureWizardExecuteStep<IAppServiceWizardContext> {
public priority: number = 141; // execute after DockerSiteCreateStep

public constructor(private readonly tagTreeItem: UnifiedRegistryItem<CommonTag>) {
super();
}

public async execute(context: IAppServiceWizardContext, progress: Progress<{ message?: string; increment?: number }>): Promise<void> {
const message: string = l10n.t('Granting permission for App Service to pull image from ACR...');
ext.outputChannel.info(message);
progress.report({ message: message });

const azExtAzureUtils = await getAzExtAzureUtils();
const vscAzureAppService = await getAzExtAppService();
const armAuth = await getArmAuth();
const armContainerRegistry = await getArmContainerRegistry();
const authClient = azExtAzureUtils.createAzureClient(context, armAuth.AuthorizationManagementClient);
const crmClient = azExtAzureUtils.createAzureClient(context, armContainerRegistry.ContainerRegistryManagementClient);
const appSvcClient = await vscAzureAppService.createWebSiteClient(context);

// If we're in `execute`, then `shouldExecute` passed and `this.tagTreeItem.parent.parent` is guaranteed to be an AzureRegistryTreeItem
const registryTreeItem: UnifiedRegistryItem<AzureRegistry> = this.tagTreeItem.parent.parent as unknown as UnifiedRegistryItem<AzureRegistry>;

// 1. Get the registry resource. We will need the ID.
const registry = await crmClient.registries.get(getResourceGroupFromAzureRegistryItem(registryTreeItem.wrappedItem), registryTreeItem.wrappedItem.label);

if (!(registry?.id)) {
throw new Error(
l10n.t('Unable to get details from Container Registry {0}', registryTreeItem.wrappedItem.baseUrl)
);
}

// 2. Get the role definition for the AcrPull role. We will need the definition ID. This role is built-in and should always exist.
const acrPullRoleDefinition = (await azExtAzureUtils.uiUtils.listAllIterator(authClient.roleDefinitions.list(registry.id, { filter: `roleName eq 'AcrPull'` })))[0];

if (!(acrPullRoleDefinition?.id)) {
throw new Error(
l10n.t('Unable to get AcrPull role definition on subscription {0}', context.subscriptionId)
);
}

// 3. Get the info for the now-created web site. We will need the principal ID.
const siteInfo = await appSvcClient.webApps.get(context.site.resourceGroup, context.site.name);

if (!(siteInfo?.identity?.principalId)) {
throw new Error(
l10n.t('Unable to get identity principal ID for web site {0}', context.site.name)
);
}

// 4. On the registry, assign the AcrPull role to the principal representing the website
await authClient.roleAssignments.create(registry.id, randomUUID(), {
principalId: siteInfo.identity.principalId,
roleDefinitionId: acrPullRoleDefinition.id,
principalType: 'ServicePrincipal',
});

// 5. Set the web app to use the desired ACR image, which was not done in DockerSiteCreateStep. Get the config and then update it.
const config = await appSvcClient.webApps.getConfiguration(context.site.resourceGroup, context.site.name);

if (!config) {
throw new Error(
l10n.t('Unable to get configuration for web site {0}', context.site.name)
);
}

const fullTag = getFullImageNameFromRegistryTagItem(this.tagTreeItem.wrappedItem);
config.linuxFxVersion = `DOCKER|${fullTag}`;
await appSvcClient.webApps.updateConfiguration(context.site.resourceGroup, context.site.name, config);
}

public shouldExecute(context: IAppServiceWizardContext): boolean {
return !!(context.site) && isAzureTagItem(this.tagTreeItem.wrappedItem) && !context.customLocation;
}
}
Loading

0 comments on commit ea8f0bc

Please sign in to comment.