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

Added Back Azure Deploy to ACA & Azure Deploy to AAS #4038

Merged
merged 13 commits into from
Aug 23, 2023
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