Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
87841ca
Initial scaffold for deployContainerApp
MicroFish91 Dec 18, 2024
1088867
Improve wizard title
MicroFish91 Dec 18, 2024
3e85ad6
Add retries for failed updates
MicroFish91 Dec 18, 2024
e0a7003
Update throw condition
MicroFish91 Dec 18, 2024
c35bd08
Improve activity children and output logs
MicroFish91 Dec 19, 2024
ef87f0f
Add todo
MicroFish91 Dec 19, 2024
631be79
Add resource output logs
MicroFish91 Dec 19, 2024
b537741
Add comment
MicroFish91 Dec 19, 2024
146661f
Merge branch 'mwf/adorable-plum' of https://github.com/microsoft/vsco…
MicroFish91 Dec 19, 2024
e4ede57
Fix a log message
MicroFish91 Dec 19, 2024
7906366
Always prompt registry
MicroFish91 Dec 19, 2024
7c8d543
Improvements to finding recommended pick
MicroFish91 Dec 19, 2024
b8a81fb
Impl
MicroFish91 Dec 20, 2024
a5db872
Add fix for imageSourceListStep
MicroFish91 Dec 20, 2024
c9292be
Merge branch 'mwf/homely-emerald' of https://github.com/microsoft/vsc…
MicroFish91 Dec 20, 2024
1feaddd
Improve placeHolder prompt
MicroFish91 Dec 20, 2024
a139430
Fix deployImage
MicroFish91 Dec 20, 2024
f2cd6a7
Merge branch 'mwf/homely-emerald' of https://github.com/microsoft/vsc…
MicroFish91 Dec 20, 2024
300a5da
Merge with main
MicroFish91 Dec 21, 2024
2d05935
Improve acr pick recommendations
MicroFish91 Dec 24, 2024
209d1ac
Only sort if sr exists
MicroFish91 Dec 24, 2024
e2c87c6
Add draft boolean to context and register more children for editConta…
MicroFish91 Dec 24, 2024
7a8787c
Update editContainerImage
MicroFish91 Dec 24, 2024
eff6574
Improve comment
MicroFish91 Dec 24, 2024
5b22cc9
Improve comment again
MicroFish91 Dec 24, 2024
bd3e538
Add guard clauses to key commands
MicroFish91 Dec 24, 2024
57661f6
Small improvements
MicroFish91 Dec 24, 2024
d2eddbb
Make pick description search case insensitive
MicroFish91 Dec 24, 2024
4ec09bb
Change to pickUtils
MicroFish91 Dec 24, 2024
85eba7d
Consolidate with pickUtils
MicroFish91 Dec 26, 2024
85d8d1c
Merge branch 'mwf/fiscal-beige' of https://github.com/microsoft/vscod…
MicroFish91 Dec 26, 2024
ac5b4dc
Merge branch 'mwf/obliged-gold' of https://github.com/microsoft/vscod…
MicroFish91 Dec 26, 2024
31db97f
Initial functions api support
MicroFish91 Dec 26, 2024
6f7cb74
Update changelog
MicroFish91 Dec 27, 2024
75df8de
Update suppress option
MicroFish91 Dec 27, 2024
6a98700
Feedback
MicroFish91 Dec 27, 2024
08428a0
Remove container app name
MicroFish91 Dec 27, 2024
7849f25
Merge branch 'mwf/gentle-amber' of https://github.com/microsoft/vscod…
MicroFish91 Dec 27, 2024
5faccfc
Update deployImageApi
MicroFish91 Dec 27, 2024
21cf2c0
Add todos
MicroFish91 Dec 27, 2024
a5ddc53
Update changelog
MicroFish91 Dec 30, 2024
6a433d9
Add activity children and support template updates
MicroFish91 Dec 30, 2024
316ea8c
Add parent resource reference
MicroFish91 Dec 30, 2024
d3c884c
Make command consistent with other deploy commands
MicroFish91 Dec 30, 2024
85c4efa
Reorganize files
MicroFish91 Jan 3, 2025
2310f79
Merge with main
MicroFish91 Jan 10, 2025
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
3 changes: 3 additions & 0 deletions src/commands/api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

### 0.0.3

### Added
* [[817]](https://github.com/microsoft/vscode-azurecontainerapps/pull/817) Added an API entry-point and compat wrapper for existing `deployImageApi` command

### Changed
* [[816]](https://github.com/microsoft/vscode-azurecontainerapps/pull/816) Added backward compatibility to ensure existing functionality remains unaffected by new managed identity features.

Expand Down
55 changes: 55 additions & 0 deletions src/commands/api/deployImageApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { callWithMaskHandling, callWithTelemetryAndErrorHandling, createSubscriptionContext, type ExecuteActivityContext, type IActionContext, type ISubscriptionActionContext } from "@microsoft/vscode-azext-utils";
import { ImageSource, acrDomain } from "../../constants";
import { type DeployImageApiTelemetryProps as TelemetryProps } from "../../telemetry/commandTelemetryProps";
import { type SetTelemetryProps } from "../../telemetry/SetTelemetryProps";
import { getDomainFromRegistryName, getRegistryFromAcrName } from "../../utils/imageNameUtils";
import { pickContainer } from "../../utils/pickItem/pickContainer";
import { deployImage } from "../deployImage/deployImage";
import { type ContainerRegistryImageSourceContext } from "../image/imageSource/containerRegistry/ContainerRegistryImageSourceContext";
import { type ImageSourceBaseContext } from "../image/imageSource/ImageSourceContext";
import { type DeployImageToAcaOptionsContract } from "./vscode-azurecontainerapps.api";

export type DeployImageApiContext = ImageSourceBaseContext & ExecuteActivityContext & SetTelemetryProps<TelemetryProps>;

export async function deployImageApi(deployImageOptions: DeployImageToAcaOptionsContract): Promise<void> {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is all carryover code except with a new callWithTelemetryAndErrorHandling wrapper

return await callWithTelemetryAndErrorHandling('containerApps.api.deployImage', async (context: IActionContext & Partial<ContainerRegistryImageSourceContext>) => {
const node = await pickContainer(context);
const { subscription } = node;

Object.assign(context, { ...createSubscriptionContext(subscription), imageSource: ImageSource.ContainerRegistry }, deployImageOptions);

context.registryDomain = getDomainFromRegistryName(deployImageOptions.registryName);
if (context.registryDomain === acrDomain) {
context.registry = await getRegistryFromAcrName(<ISubscriptionActionContext>context, deployImageOptions.registryName);
}

// Mask sensitive data
if (deployImageOptions.secret) {
context.valuesToMask.push(deployImageOptions.secret);
}
if (deployImageOptions.username) {
context.valuesToMask.push(deployImageOptions.username);
}
context.valuesToMask.push(deployImageOptions.image);

if (deployImageOptions.secret) {
context.telemetry.properties.hasRegistrySecrets = 'true';
return callWithMaskHandling<void>(() => deployImage(context, node), deployImageOptions.secret);
} else {
context.telemetry.properties.hasRegistrySecrets = 'false';
return deployImage(context, node);
}
});
}

/**
* A compatibility wrapper for the legacy entrypoint utilizing `deployImageApi`
*/
export async function deployImageApiCompat(_: IActionContext & Partial<ContainerRegistryImageSourceContext>, deployImageOptions: DeployImageToAcaOptionsContract): Promise<void> {
return await deployImageApi(deployImageOptions);
}
4 changes: 3 additions & 1 deletion src/commands/api/getAzureContainerAppsApiProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { createApiProvider, type apiUtils } from "@microsoft/vscode-azext-utils";
import { deployImageApi } from "./deployImageApi";
import { deployWorkspaceProjectApi } from "./deployWorkspaceProjectApi";
import type * as api from "./vscode-azurecontainerapps.api";

Expand All @@ -12,6 +13,7 @@ export function getAzureContainerAppsApiProvider(): apiUtils.AzureExtensionApiPr
// Todo: Change this to 0.0.3 later. 0.0.3 is backwards compatible anyway so this change should be fine either way.
// For some reason it's causing a block on Function side, so just keep it at 0.0.1 until we figure out why
apiVersion: '0.0.1',
deployWorkspaceProject: deployWorkspaceProjectApi
deployImage: deployImageApi,
deployWorkspaceProject: deployWorkspaceProjectApi,
}]);
}
9 changes: 9 additions & 0 deletions src/commands/api/vscode-azurecontainerapps.api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ export interface AzureContainerAppsExtensionApi {
deployWorkspaceProject(options: DeployWorkspaceProjectOptionsContract): Promise<DeployWorkspaceProjectResults>;
}

// The interface of the command options passed to the Azure Container Apps extension's deployImageToAca command
// This interface is shared with the Docker extension (https://github.com/microsoft/vscode-docker)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Carryover of existing interface, but moved into the api type definition

export interface DeployImageToAcaOptionsContract {
image: string;
registryName: string;
username?: string;
secret?: string;
}

export interface DeployWorkspaceProjectOptionsContract {
// Existing resources
subscriptionId?: string;
Expand Down
12 changes: 12 additions & 0 deletions src/commands/deployImage/DeployImageContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { type Template } from "@azure/arm-appcontainers";
import { type DeployImageApiContext } from "../api/deployImageApi";

export interface DeployImageContext extends DeployImageApiContext {
containersIdx: number;
template: Template;
}
91 changes: 91 additions & 0 deletions src/commands/deployImage/deployImage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +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 ResourceGroup } from "@azure/arm-resources";
import { LocationListStep, ResourceGroupListStep } from "@microsoft/vscode-azext-azureutils";
import { activityInfoIcon, activitySuccessContext, AzureWizard, createSubscriptionContext, createUniversallyUniqueContextValue, GenericTreeItem, nonNullValue, nonNullValueAndProp, type IActionContext, type ISubscriptionContext } from "@microsoft/vscode-azext-utils";
import { ext } from "../../extensionVariables";
import { type ContainerItem } from "../../tree/containers/ContainerItem";
import { createActivityContext } from "../../utils/activityUtils";
import { isAzdExtensionInstalled } from "../../utils/azdUtils";
import { getManagedEnvironmentFromContainerApp } from "../../utils/getResourceUtils";
import { getVerifyProvidersStep } from "../../utils/getVerifyProvidersStep";
import { localize } from "../../utils/localize";
import { getParentResource } from "../../utils/revisionDraftUtils";
import { ContainerAppOverwriteConfirmStep } from "../ContainerAppOverwriteConfirmStep";
import { showContainerAppNotification } from "../createContainerApp/showContainerAppNotification";
import { ContainerAppUpdateStep } from "../image/imageSource/ContainerAppUpdateStep";
import { ImageSourceListStep } from "../image/imageSource/ImageSourceListStep";
import { type ContainerRegistryImageSourceContext } from "../image/imageSource/containerRegistry/ContainerRegistryImageSourceContext";
import { type DeployImageContext } from "./DeployImageContext";

export async function deployImage(context: IActionContext & Partial<ContainerRegistryImageSourceContext>, node: ContainerItem): Promise<void> {
Copy link
Copy Markdown
Contributor Author

@MicroFish91 MicroFish91 Dec 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New changes:

  1. Wizard context now includes containersIdx and template which are used to allow targets to each revision's container while in multiple revisions mode
  2. Added activity children for logging the existing resource group and container app to keep formatting similar to the other major commands

const { subscription, containerApp } = node;
const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription);

const wizardContext: DeployImageContext = {
...context,
...subscriptionContext,
...await createActivityContext(true),
subscription,
managedEnvironment: await getManagedEnvironmentFromContainerApp({ ...context, ...subscriptionContext }, containerApp),
containerApp,
containersIdx: node.containersIdx,
template: nonNullValueAndProp(getParentResource(containerApp, node.revision), 'template'),
};

if (isAzdExtensionInstalled()) {
wizardContext.telemetry.properties.isAzdExtensionInstalled = 'true';
}

const resourceGroups: ResourceGroup[] = await ResourceGroupListStep.getResourceGroups(wizardContext);
wizardContext.resourceGroup = nonNullValue(
resourceGroups.find(rg => rg.name === containerApp.resourceGroup),
localize('containerAppResourceGroup', 'Expected to find the container app\'s resource group.'),
);

// Log resource group
wizardContext.activityChildren?.push(
new GenericTreeItem(undefined, {
contextValue: createUniversallyUniqueContextValue(['useExistingResourceGroupInfoItem', activitySuccessContext]),
label: localize('useResourceGroup', 'Using resource group "{0}"', wizardContext.resourceGroup.name),
iconPath: activityInfoIcon
})
);
ext.outputChannel.appendLog(localize('usingResourceGroup', 'Using resource group "{0}".', wizardContext.resourceGroup.name));

// Log container app
wizardContext.activityChildren?.push(
new GenericTreeItem(undefined, {
contextValue: createUniversallyUniqueContextValue(['useExistingContainerAppInfoItem', activitySuccessContext]),
label: localize('useContainerApp', 'Using container app "{0}"', wizardContext.containerApp?.name),
iconPath: activityInfoIcon
})
);
ext.outputChannel.appendLog(localize('usingContainerApp', 'Using container app "{0}".', wizardContext.containerApp?.name));

await LocationListStep.setLocation(wizardContext, containerApp.location);

const parentResourceName: string = getParentResource(containerApp, node.revision).name ?? containerApp.name;
const wizard: AzureWizard<DeployImageContext> = new AzureWizard(wizardContext, {
title: localize('deployImageTitle', 'Deploy image to "{0}"', parentResourceName),
promptSteps: [
new ImageSourceListStep(),
new ContainerAppOverwriteConfirmStep(),
],
executeSteps: [
getVerifyProvidersStep<DeployImageContext>(),
new ContainerAppUpdateStep(),
],
showLoadingPrompt: true
});

await wizard.prompt();
await wizard.execute();

if (!wizardContext.suppressNotification) {
void showContainerAppNotification(containerApp, true /** isUpdate */);
}
}
53 changes: 0 additions & 53 deletions src/commands/image/deployImageApi/deployImage.ts

This file was deleted.

59 changes: 0 additions & 59 deletions src/commands/image/deployImageApi/deployImageApi.ts

This file was deleted.

16 changes: 10 additions & 6 deletions src/commands/image/imageSource/ContainerAppUpdateStep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { type Ingress } from "@azure/arm-appcontainers";
import { type Container, type Ingress } from "@azure/arm-appcontainers";
import { activityFailContext, activityFailIcon, activitySuccessContext, activitySuccessIcon, AzureWizardExecuteStep, createUniversallyUniqueContextValue, GenericParentTreeItem, GenericTreeItem, nonNullProp, type ExecuteActivityOutput } from "@microsoft/vscode-azext-utils";
import * as retry from "p-retry";
import { type Progress } from "vscode";
Expand Down Expand Up @@ -57,15 +57,19 @@ export class ContainerAppUpdateStep<T extends ImageSourceContext & IngressContex
containerAppEnvelope.configuration.secrets = context.secrets;
containerAppEnvelope.configuration.registries = context.registryCredentials;

// We want to replace the old image
containerAppEnvelope.template ||= {};
containerAppEnvelope.template.containers = [];
containerAppEnvelope.template = context.template ?? containerAppEnvelope.template ?? {};
containerAppEnvelope.template.containers ||= [];

containerAppEnvelope.template.containers.push({
const newContainer: Container = {
env: context.environmentVariables,
image: context.image,
name: getContainerNameForImage(nonNullProp(context, 'image')),
});
};
if (context.containersIdx) {
containerAppEnvelope.template.containers[context.containersIdx] = newContainer;
} else {
containerAppEnvelope.template.containers = [newContainer];
}

// Related: https://github.com/microsoft/vscode-azurecontainerapps/pull/805
const retries = 4;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/image/imageSource/EnvFileListStep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class EnvFileListStep<T extends EnvFileListContext> extends AzureWizardPr
}

public async prompt(context: T): Promise<void> {
const existingData = context.containerApp?.template?.containers?.[context.containersIdx ?? 0].env;
const existingData = context.template?.containers?.[context.containersIdx ?? 0].env ?? context.containerApp?.template?.containers?.[context.containersIdx ?? 0].env;
context.envPath ??= await this.promptForEnvPath(context, !!existingData /** showHasExistingData */);

if (!context.envPath && existingData) {
Expand Down
Loading