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

Add backward compatibility to API in support of the new managed identity features #816

Merged
merged 39 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
39 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
3be6e34
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@
},
{
"command": "containerApps.deployContainerApp",
"when": "view =~ /(azureResourceGroups|azureFocusView)/ && viewItem =~ /containerAppItem/i",
"when": "view =~ /(azureResourceGroups|azureFocusView)/ && viewItem =~ /containerAppItem(.*)revisionMode:single/i",
"group": "2@1"
},
{
Expand Down
7 changes: 5 additions & 2 deletions src/commands/api/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
# Change Log

### 0.0.2
### 0.0.3

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

### 0.0.2

### Changed
* [[615]](https://github.com/microsoft/vscode-azurecontainerapps/pull/615) Removed ability to set option `ignoreExistingDeploySettings`. This will now happen automatically by default.

## 0.0.1
* Initial release

### Added

* [[578]](https://github.com/microsoft/vscode-azurecontainerapps/pull/578) Added an API entry-point to the `deployWorkspaceProject` command
14 changes: 13 additions & 1 deletion src/commands/api/deployWorkspaceProjectApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,21 @@ import { type DeployWorkspaceProjectContext } from "../deployWorkspaceProject/De
import { getDeployWorkspaceProjectResults, type DeployWorkspaceProjectResults } from "../deployWorkspaceProject/getDeployWorkspaceProjectResults";
import { type DeployWorkspaceProjectInternalContext } from "../deployWorkspaceProject/internal/DeployWorkspaceProjectInternalContext";
import { deployWorkspaceProjectInternal } from "../deployWorkspaceProject/internal/deployWorkspaceProjectInternal";
import { RegistryCredentialType } from "../registryCredentials/RegistryCredentialsAddConfigurationListStep";
import type * as api from "./vscode-azurecontainerapps.api";

export async function deployWorkspaceProjectApi(deployWorkspaceProjectOptions: api.DeployWorkspaceProjectOptionsContract): Promise<DeployWorkspaceProjectResults> {
return await callWithTelemetryAndErrorHandling('containerApps.api.deployWorkspaceProject', async (context: IActionContext): Promise<DeployWorkspaceProjectResults> => {
const { resourceGroupId, rootPath, dockerfilePath, srcPath, suppressConfirmation, suppressContainerAppCreation, shouldSaveDeploySettings } = deployWorkspaceProjectOptions;
const {
resourceGroupId,
rootPath,
dockerfilePath,
srcPath,
suppressRegistryPrompt,
suppressConfirmation,
suppressContainerAppCreation,
shouldSaveDeploySettings
} = deployWorkspaceProjectOptions;

const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider, {
selectBySubscriptionId: getSubscriptionIdFromOptions(deployWorkspaceProjectOptions),
Expand All @@ -38,12 +48,14 @@ export async function deployWorkspaceProjectApi(deployWorkspaceProjectOptions: a
rootFolder,
srcPath: srcPath ? Uri.file(srcPath).fsPath : undefined,
dockerfilePath: dockerfilePath ? Uri.file(dockerfilePath).fsPath : undefined,
newRegistryCredentialType: RegistryCredentialType.DockerLogin,
Copy link
Contributor Author

@MicroFish91 MicroFish91 Dec 27, 2024

Choose a reason for hiding this comment

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

We need additional discussions about whether we want to default to managed identity here in the future. For now, I'm keeping it as Docker Login to preserve existing behavior.

shouldSaveDeploySettings: !!shouldSaveDeploySettings,
});

const deployWorkspaceProjectContext: DeployWorkspaceProjectContext = await deployWorkspaceProjectInternal(deployWorkspaceProjectInternalContext, {
suppressActivity: true,
suppressConfirmation,
suppressRegistryPrompt: suppressRegistryPrompt ?? true,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This PR introduced the prompt, so add ability to suppress and default it to true to preserve existing behavior

suppressContainerAppCreation,
suppressProgress: true,
suppressWizardTitle: true,
Expand Down
2 changes: 1 addition & 1 deletion src/commands/api/getAzureContainerAppsApiProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type * as api from "./vscode-azurecontainerapps.api";

export function getAzureContainerAppsApiProvider(): apiUtils.AzureExtensionApiProvider {
return createApiProvider([<api.AzureContainerAppsExtensionApi>{
// Todo: Change this to 0.0.2 later. 0.0.2 is backwards compatible anyway so this change should be fine either way.
// Todo: Change this to 0.0.3 later. 0.0.3 is backwards compatible anyway so this change should be fine either way.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

When we eventually add managed identity support for the api, I will bump the major version

Copy link
Member

Choose a reason for hiding this comment

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

Okay, but just so you know, this changing is purely aesthetic. semver doesn't actually register this as a different version number since there's no major version number.

// 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
Expand Down
1 change: 1 addition & 0 deletions src/commands/api/vscode-azurecontainerapps.api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface DeployWorkspaceProjectOptionsContract {
dockerfilePath?: string;

// Options
suppressRegistryPrompt?: boolean;
suppressConfirmation?: boolean; // Suppress any [resource] confirmation prompts
suppressContainerAppCreation?: boolean;
shouldSaveDeploySettings?: boolean;
Expand Down
9 changes: 9 additions & 0 deletions src/commands/deployContainerApp/deployContainerApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { KnownActiveRevisionsMode } from "@azure/arm-appcontainers";
import { type ResourceGroup } from "@azure/arm-resources";
import { LocationListStep, ResourceGroupListStep } from "@microsoft/vscode-azext-azureutils";
import { activityInfoIcon, activitySuccessContext, AzureWizard, createSubscriptionContext, createUniversallyUniqueContextValue, GenericTreeItem, nonNullProp, nonNullValue, type IActionContext, type ISubscriptionActionContext, type ISubscriptionContext } from "@microsoft/vscode-azext-utils";
Expand All @@ -25,6 +26,13 @@ export async function deployContainerApp(context: IActionContext, node?: Contain
const subscriptionContext: ISubscriptionContext = createSubscriptionContext(item.subscription);
const subscriptionActionContext: ISubscriptionActionContext = { ...context, ...subscriptionContext };

if (item.containerApp.revisionsMode === KnownActiveRevisionsMode.Multiple) {
throw new Error(localize('multipleRevisionsNotSupported', 'The container app "{0}" cannot be updated using "Deploy to Container App..." while in multiple revisions mode.', item.containerApp.name));
}
if ((item.containerApp.template?.containers?.length ?? 0) > 1) {
throw new Error(localize('multipleContainersNotSupported', 'The container app "{0}" cannot be updated using "Deploy to Container App..." while having more than one active container.', item.containerApp.name));
}

// Prompt for image source before initializing the wizard in case we need to redirect the call to 'deployWorkspaceProject' instead
const imageSource: ImageSource = await promptImageSource(subscriptionActionContext);
if (imageSource === ImageSource.RemoteAcrBuild) {
Expand All @@ -40,6 +48,7 @@ export async function deployContainerApp(context: IActionContext, node?: Contain
managedEnvironment: await getManagedEnvironmentFromContainerApp(subscriptionActionContext, item.containerApp),
imageSource,
};
wizardContext.telemetry.properties.revisionMode = item.containerApp.revisionsMode;

if (isAzdExtensionInstalled()) {
wizardContext.telemetry.properties.isAzdExtensionInstalled = 'true';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { ManagedEnvironmentItem } from "../../../tree/ManagedEnvironmentItem";
import { type IContainerAppContext } from "../../IContainerAppContext";
import { RootFolderStep } from "../../image/imageSource/buildImageInAzure/RootFolderStep";
import { type DeploymentConfiguration } from "./DeploymentConfiguration";
import { TryUseExistingWorkspaceRegistryStep } from "./workspace/azureResources/TryUseExistingWorkspaceRegistryStep";

type TreeItemDeploymentConfigurationContext = IContainerAppContext & DeploymentConfiguration;

Expand All @@ -18,7 +17,6 @@ export async function getTreeItemDeploymentConfiguration(context: IContainerAppC

const wizard: AzureWizard<TreeItemDeploymentConfigurationContext> = new AzureWizard(wizardContext, {
promptSteps: [new RootFolderStep()],
executeSteps: [new TryUseExistingWorkspaceRegistryStep()]
});

await wizard.prompt();
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { RootFolderStep } from "../../../image/imageSource/buildImageInAzure/Roo
import { type DeploymentConfiguration } from "../DeploymentConfiguration";
import { DeploymentConfigurationListStep } from "./DeploymentConfigurationListStep";
import { type WorkspaceDeploymentConfigurationContext } from "./WorkspaceDeploymentConfigurationContext";
import { TryUseExistingWorkspaceRegistryStep } from "./azureResources/TryUseExistingWorkspaceRegistryStep";

export async function getWorkspaceDeploymentConfiguration(context: IContainerAppContext & { rootFolder?: WorkspaceFolder }): Promise<DeploymentConfiguration> {
const wizardContext: WorkspaceDeploymentConfigurationContext = Object.assign(context, {
Expand All @@ -25,9 +24,6 @@ export async function getWorkspaceDeploymentConfiguration(context: IContainerApp
new RootFolderStep(),
new DeploymentConfigurationListStep(),
],
executeSteps: [
new TryUseExistingWorkspaceRegistryStep()
]
});

await wizard.prompt();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,22 @@ export class ShouldSaveDeploySettingsPromptStep extends AzureWizardPromptStep<De
const settings: DeploymentConfigurationSettings[] | undefined = await dwpSettingUtilsV2.getWorkspaceDeploymentConfigurations(rootFolder);
const setting: DeploymentConfigurationSettings | undefined = settings?.[context.configurationIdx];

const hasNewResourceGroupSetting: boolean = (!!context.newResourceGroupName && setting?.resourceGroup !== context.newResourceGroupName) ||
(!!context.resourceGroup && setting?.resourceGroup !== context.resourceGroup.name);
const hasNewContainerAppSetting: boolean = (!!context.newContainerAppName && setting?.containerApp !== context.newContainerAppName) ||
(!!context.containerApp && setting?.containerApp !== context.containerApp.name);
const hasNewRegistrySetting: boolean = (!!context.newRegistryName && setting?.containerRegistry !== context.newRegistryName) ||
(!!context.registry && setting?.containerRegistry !== context.registry.name);

const hasNewSettings: boolean =
!setting?.label ||
setting?.type !== 'AcrDockerBuildRequest' ||
(context.dockerfilePath && convertRelativeToAbsolutePath(rootPath, setting?.dockerfilePath) !== context.dockerfilePath) ||
(context.envPath && convertRelativeToAbsolutePath(rootPath, setting?.envPath) !== context.envPath) ||
(context.srcPath && convertRelativeToAbsolutePath(rootPath, setting?.srcPath) !== context.srcPath) ||
(!!context.resourceGroup && setting?.resourceGroup !== context.resourceGroup.name) ||
(!!context.containerApp && setting?.containerApp !== context.containerApp.name) ||
(!!context.registry && setting?.containerRegistry !== context.registry.name);
hasNewResourceGroupSetting ||
hasNewContainerAppSetting ||
hasNewRegistrySetting;

if (!hasNewSettings) {
context.telemetry.properties.hasNewSettings = 'false';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { KnownActiveRevisionsMode } from "@azure/arm-appcontainers";
import { LocationListStep, ResourceGroupCreateStep } from "@microsoft/vscode-azext-azureutils";
import { AzureWizard, GenericTreeItem, activityInfoIcon, activitySuccessContext, createUniversallyUniqueContextValue, nonNullValueAndProp, type AzureWizardExecuteStep, type AzureWizardPromptStep, type ExecuteActivityContext } from "@microsoft/vscode-azext-utils";
import { ProgressLocation, window } from "vscode";
Expand Down Expand Up @@ -31,6 +32,10 @@ export interface DeployWorkspaceProjectInternalOptions {
* Suppress showing the wizard execution through the activity log
*/
suppressActivity?: boolean;
/**
* Suppress registry selection prompt
*/
suppressRegistryPrompt?: boolean;
/**
* Suppress any [resource] confirmation prompts
*/
Expand Down Expand Up @@ -75,9 +80,16 @@ export async function deployWorkspaceProjectInternal(
undefined :
localize('loadingWorkspaceTitle', 'Loading workspace project starting configurations...')
}, async () => {
startingConfiguration = await getStartingConfiguration({ ...context });
startingConfiguration = await getStartingConfiguration({ ...context }, options);
});

if (startingConfiguration?.containerApp?.revisionsMode === KnownActiveRevisionsMode.Multiple) {
throw new Error(localize('multipleRevisionsNotSupported', 'The container app "{0}" cannot be updated using "Deploy Project from Workspace..." while in multiple revisions mode.', startingConfiguration?.containerApp?.name));
}
if ((startingConfiguration?.containerApp?.template?.containers?.length ?? 0) > 1) {
throw new Error(localize('multipleContainersNotSupported', 'The container app "{0}" cannot be updated using "Deploy Project from Workspace..." while having more than one active container.', startingConfiguration?.containerApp?.name));
}

const wizardContext: DeployWorkspaceProjectInternalContext = {
...context,
...activityContext,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { type Registry } from "@azure/arm-containerregistry";
import { AzureWizardPromptStep, type IAzureQuickPickItem } from "@microsoft/vscode-azext-utils";
import { localize } from "../../../../utils/localize";
import { isRecommendedPick } from "../../../../utils/pickUtils";
import { acrCreatePick, AcrListStep } from "../../../image/imageSource/containerRegistry/acr/AcrListStep";
import { type DeployWorkspaceProjectInternalContext } from "../DeployWorkspaceProjectInternalContext";

export class DwpAcrListStep<T extends DeployWorkspaceProjectInternalContext> extends AzureWizardPromptStep<T> {
public async prompt(context: T): Promise<void> {
const picks: IAzureQuickPickItem<Registry | undefined>[] = await this.getPicks(context);
if (!picks.length) {
// No container registries to choose from
return;
}

const placeHolder: string = localize('selectContainerRegistry', 'Select an Azure Container Registry to store your image');
const pick: IAzureQuickPickItem<Registry | undefined> = await context.ui.showQuickPick(picks, { placeHolder, suppressPersistence: true });

context.telemetry.properties.usedRecommendedRegistry = isRecommendedPick(pick) ? 'true' : 'false';
context.registry = pick.data;
}

public shouldPrompt(context: T): boolean {
return !context.registry;
}

public async getPicks(context: T): Promise<IAzureQuickPickItem<Registry | undefined>[]> {
return [
acrCreatePick,
...await AcrListStep.getSortedAndRecommendedPicks(context),
];
}
}

Loading