diff --git a/package.json b/package.json
index aff482298..d7fe00c3f 100644
--- a/package.json
+++ b/package.json
@@ -226,6 +226,12 @@
"shortTitle": "%containerApps.editEnvironmentVariableValue.shortTitle%",
"category": "Azure Container Apps"
},
+ {
+ "command": "containerApps.convertEnvironmentVariable",
+ "title": "%containerApps.convertEnvironmentVariable.title%",
+ "shortTitle": "%containerApps.convertEnvironmentVariable.shortTitle%",
+ "category": "Azure Container Apps"
+ },
{
"command": "containerApps.editEnvironmentVariables",
"title": "%containerApps.editEnvironmentVariables%",
@@ -522,6 +528,11 @@
"when": "view =~ /(azureResourceGroups|azureFocusView)/ && viewItem =~ /environmentVariableItem/i",
"group": "1@2"
},
+ {
+ "command": "containerApps.convertEnvironmentVariable",
+ "when": "view =~ /(azureResourceGroups|azureFocusView)/ && viewItem =~ /environmentVariableItem/i",
+ "group": "1@3"
+ },
{
"command": "containerApps.deleteEnvironmentVariable",
"when": "view =~ /(azureResourceGroups|azureFocusView)/ && viewItem =~ /environmentVariableItem/i",
diff --git a/package.nls.json b/package.nls.json
index c0ecc08b7..5f4caa2ef 100644
--- a/package.nls.json
+++ b/package.nls.json
@@ -17,6 +17,8 @@
"containerApps.editEnvironmentVariableName.shortTitle": "Edit Name...",
"containerApps.editEnvironmentVariableValue.title": "Edit Environment Variable Value...",
"containerApps.editEnvironmentVariableValue.shortTitle": "Edit Value...",
+ "containerApps.convertEnvironmentVariable.title": "Convert Environment Variable to Secret...",
+ "containerApps.convertEnvironmentVariable.shortTitle": "Convert to Secret...",
"containerApps.editEnvironmentVariables": "Edit Environment Variables (.env)...",
"containerApps.deleteEnvironmentVariable.title": "Delete Environment Variable...",
"containerApps.deleteEnvironmentVariable.shortTitle": "Delete...",
diff --git a/src/commands/EXECUTE_PRIORITY.md b/src/commands/EXECUTE_PRIORITY.md
index 36f189686..f7eaf23d1 100644
--- a/src/commands/EXECUTE_PRIORITY.md
+++ b/src/commands/EXECUTE_PRIORITY.md
@@ -93,15 +93,28 @@ When creating or updating resources, execute steps should occupy certain priorit
- SecretCreateStep: 820
- SecretUpdateStep: 850
-### 8. Unallocated Space
+### 8. Environment Variables
-Priority Range: 900 - 1090
+Priority Range: 900 - 990
+
+#### Steps
+
+- EnvironmentVariablesEditDraftStep: 920 (single command)
+
+
+- EnvironmentVariableAddDraftStep: 940 (single command)
+- EnvironmentVariableEditDraftStep: 960 (single command)
+- EnvironmentVariableDeleteDraftStep: 980 (single command)
+
+### 9. Unallocated Space
+
+Priority Range: 1000 - 1090
#### Steps
- Reserved for future commands TBD.
-### 9. Scaling
+### 10. Scaling
Priority Range: 1100 - 1190
@@ -109,7 +122,7 @@ When creating or updating resources, execute steps should occupy certain priorit
- AddScaleRuleStep: 1120 (revision draft)
-### 10. Unallocated Space
+### 11. Unallocated Space
Priority Range: 1200 - 1390
@@ -117,7 +130,7 @@ When creating or updating resources, execute steps should occupy certain priorit
- Reserved for future commands TBD.
-### 11. Deploy
+### 12. Deploy
Priority Range: 1400 - 1490
diff --git a/src/commands/environmentVariables/addEnvironmentVariable/EnvironmentVariableAddDraftStep.ts b/src/commands/environmentVariables/addEnvironmentVariable/EnvironmentVariableAddDraftStep.ts
index 57b266290..8061208b0 100644
--- a/src/commands/environmentVariables/addEnvironmentVariable/EnvironmentVariableAddDraftStep.ts
+++ b/src/commands/environmentVariables/addEnvironmentVariable/EnvironmentVariableAddDraftStep.ts
@@ -12,7 +12,7 @@ import { RevisionDraftUpdateBaseStep } from "../../revisionDraft/RevisionDraftUp
import { type EnvironmentVariableAddContext } from "./EnvironmentVariableAddContext";
export class EnvironmentVariableAddDraftStep extends RevisionDraftUpdateBaseStep {
- public priority: number = 590;
+ public priority: number = 940;
constructor(baseItem: ContainerAppItem | RevisionsItemModel) {
super(baseItem);
diff --git a/src/commands/environmentVariables/convertEnvironmentVariable/EnvironmentVariableConvertContext.ts b/src/commands/environmentVariables/convertEnvironmentVariable/EnvironmentVariableConvertContext.ts
new file mode 100644
index 000000000..cc5a3e454
--- /dev/null
+++ b/src/commands/environmentVariables/convertEnvironmentVariable/EnvironmentVariableConvertContext.ts
@@ -0,0 +1,16 @@
+/*---------------------------------------------------------------------------------------------
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the MIT License. See License.md in the project root for license information.
+*--------------------------------------------------------------------------------------------*/
+
+import { type ContainerUpdateTelemetryProps as TelemetryProps } from "../../../telemetry/commandTelemetryProps";
+import { type SetTelemetryProps } from "../../../telemetry/SetTelemetryProps";
+import { type ISecretContext } from "../../secret/ISecretContext";
+import { type EnvironmentVariableEditBaseContext } from "../editEnvironmentVariable/EnvironmentVariableEditContext";
+
+export interface EnvironmentVariableConvertBaseContext extends EnvironmentVariableEditBaseContext, ISecretContext {
+ // Make newSecretValue required
+ newSecretValue: string;
+}
+
+export type EnvironmentVariableConvertContext = EnvironmentVariableConvertBaseContext & SetTelemetryProps;
diff --git a/src/commands/environmentVariables/convertEnvironmentVariable/convertEnvironmentVariable.ts b/src/commands/environmentVariables/convertEnvironmentVariable/convertEnvironmentVariable.ts
new file mode 100644
index 000000000..0b389d50f
--- /dev/null
+++ b/src/commands/environmentVariables/convertEnvironmentVariable/convertEnvironmentVariable.ts
@@ -0,0 +1,68 @@
+/*---------------------------------------------------------------------------------------------
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the MIT License. See License.md in the project root for license information.
+*--------------------------------------------------------------------------------------------*/
+
+import { AzureWizard, createSubscriptionContext, nonNullValueAndProp, type IActionContext, type ISubscriptionContext } from "@microsoft/vscode-azext-utils";
+import { type EnvironmentVariableItem } from "../../../tree/containers/EnvironmentVariableItem";
+import { createActivityContext } from "../../../utils/activityUtils";
+import { getManagedEnvironmentFromContainerApp } from "../../../utils/getResourceUtils";
+import { getVerifyProvidersStep } from "../../../utils/getVerifyProvidersStep";
+import { localize } from "../../../utils/localize";
+import { pickEnvironmentVariable } from "../../../utils/pickItem/pickEnvironmentVariables";
+import { isTemplateItemEditable, TemplateItemNotEditableError } from "../../../utils/revisionDraftUtils";
+import { RevisionDraftDeployPromptStep } from "../../revisionDraft/RevisionDraftDeployPromptStep";
+import { SecretCreateStep } from "../../secret/addSecret/SecretCreateStep";
+import { SecretNameStep } from "../../secret/addSecret/SecretNameStep";
+import { EnvironmentVariableType } from "../addEnvironmentVariable/EnvironmentVariableTypeListStep";
+import { EnvironmentVariableEditDraftStep } from "../editEnvironmentVariable/EnvironmentVariableEditDraftStep";
+import { type EnvironmentVariableConvertContext } from "./EnvironmentVariableConvertContext";
+
+/**
+ * Automatically convert a 'Manual Input' environment variable to use a container app secret instead
+ */
+export async function convertEnvironmentVariable(context: IActionContext, node?: EnvironmentVariableItem): Promise {
+ const item: EnvironmentVariableItem = node ?? await pickEnvironmentVariable(context, { autoSelectDraft: true });
+ const { subscription, containerApp } = item;
+
+ if (!isTemplateItemEditable(item)) {
+ throw new TemplateItemNotEditableError(item);
+ }
+
+ if (item.envVariable.secretRef) {
+ throw new Error(localize('alreadySecret', 'The environment variable you chose to convert already uses a secret reference.'));
+ }
+
+ const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription);
+ const wizardContext: EnvironmentVariableConvertContext = {
+ ...context,
+ ...subscriptionContext,
+ ...await createActivityContext(true),
+ subscription,
+ managedEnvironment: await getManagedEnvironmentFromContainerApp({ ...context, ...subscriptionContext }, containerApp),
+ containerApp,
+ containersIdx: item.containersIdx,
+ environmentVariable: item.envVariable,
+ newSecretValue: nonNullValueAndProp(item.envVariable, 'value'),
+ newEnvironmentVariableType: EnvironmentVariableType.SecretRef,
+ isDraftCommand: true,
+ };
+ wizardContext.telemetry.properties.revisionMode = containerApp.revisionsMode;
+
+ const wizard: AzureWizard = new AzureWizard(wizardContext, {
+ title: localize('convertEnvironmentVariableTitle', 'Convert environment variable "{0}" to use a secret (draft)', wizardContext.environmentVariable.name),
+ promptSteps: [
+ new SecretNameStep(),
+ new RevisionDraftDeployPromptStep(),
+ ],
+ executeSteps: [
+ getVerifyProvidersStep(),
+ new SecretCreateStep(),
+ new EnvironmentVariableEditDraftStep(item),
+ ],
+ });
+
+ await wizard.prompt();
+ wizardContext.activityTitle = localize('convertEnvironmentVariableActivityTitle', 'Convert environment variable "{0}" to use secret "{1}" (draft)', wizardContext.environmentVariable.name, wizardContext.newSecretName);
+ await wizard.execute();
+}
diff --git a/src/commands/environmentVariables/deleteEnvironmentVariable/EnvironmentVariableDeleteDraftStep.ts b/src/commands/environmentVariables/deleteEnvironmentVariable/EnvironmentVariableDeleteDraftStep.ts
index bc6d9d40f..0f8cbbaa6 100644
--- a/src/commands/environmentVariables/deleteEnvironmentVariable/EnvironmentVariableDeleteDraftStep.ts
+++ b/src/commands/environmentVariables/deleteEnvironmentVariable/EnvironmentVariableDeleteDraftStep.ts
@@ -12,7 +12,7 @@ import { RevisionDraftUpdateBaseStep } from "../../revisionDraft/RevisionDraftUp
import { type EnvironmentVariableDeleteContext } from "./EnvironmentVariableDeleteContext";
export class EnvironmentVariableDeleteDraftStep extends RevisionDraftUpdateBaseStep {
- public priority: number = 590;
+ public priority: number = 980;
constructor(baseItem: ContainerAppItem | RevisionsItemModel) {
super(baseItem);
diff --git a/src/commands/environmentVariables/editEnvironmentVariable/EnvironmentVariableEditContext.ts b/src/commands/environmentVariables/editEnvironmentVariable/EnvironmentVariableEditContext.ts
index 1948620ca..1f2e79cbd 100644
--- a/src/commands/environmentVariables/editEnvironmentVariable/EnvironmentVariableEditContext.ts
+++ b/src/commands/environmentVariables/editEnvironmentVariable/EnvironmentVariableEditContext.ts
@@ -6,9 +6,9 @@
import { type EnvironmentVar } from "@azure/arm-appcontainers";
import { type SetTelemetryProps } from "../../../telemetry/SetTelemetryProps";
import { type ContainerUpdateTelemetryProps as TelemetryProps } from "../../../telemetry/commandTelemetryProps";
-import { type EnvironmentVariableAddContext } from "../addEnvironmentVariable/EnvironmentVariableAddContext";
+import { type EnvironmentVariableAddBaseContext } from "../addEnvironmentVariable/EnvironmentVariableAddContext";
-export interface EnvironmentVariableEditBaseContext extends EnvironmentVariableAddContext {
+export interface EnvironmentVariableEditBaseContext extends EnvironmentVariableAddBaseContext {
// Require the environment variable upfront so we can make edits
environmentVariable: EnvironmentVar;
}
diff --git a/src/commands/environmentVariables/editEnvironmentVariable/EnvironmentVariableEditDraftStep.ts b/src/commands/environmentVariables/editEnvironmentVariable/EnvironmentVariableEditDraftStep.ts
index f85ea1248..b75c1d101 100644
--- a/src/commands/environmentVariables/editEnvironmentVariable/EnvironmentVariableEditDraftStep.ts
+++ b/src/commands/environmentVariables/editEnvironmentVariable/EnvironmentVariableEditDraftStep.ts
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { type Container, type EnvironmentVar } from "@azure/arm-appcontainers";
-import { nonNullValue } from "@microsoft/vscode-azext-utils";
+import { activityFailContext, activityFailIcon, activitySuccessContext, activitySuccessIcon, createUniversallyUniqueContextValue, GenericParentTreeItem, GenericTreeItem, nonNullValue, type ExecuteActivityOutput } from "@microsoft/vscode-azext-utils";
import { type Progress } from "vscode";
import { type ContainerAppItem } from "../../../tree/ContainerAppItem";
import { type RevisionsItemModel } from "../../../tree/revisionManagement/RevisionItem";
@@ -14,7 +14,7 @@ import { EnvironmentVariableType } from "../addEnvironmentVariable/EnvironmentVa
import { type EnvironmentVariableEditContext } from "./EnvironmentVariableEditContext";
export class EnvironmentVariableEditDraftStep extends RevisionDraftUpdateBaseStep {
- public priority: number = 590;
+ public priority: number = 960;
constructor(baseItem: ContainerAppItem | RevisionsItemModel) {
super(baseItem);
@@ -49,4 +49,26 @@ export class EnvironmentVariableEditDraftStep extends RevisionDraftUpdateBaseStep {
- public priority: number = 590;
+ public priority: number = 920;
constructor(baseItem: ContainerAppItem | RevisionsItemModel) {
super(baseItem);
diff --git a/src/commands/secret/addSecret/SecretCreateStep.ts b/src/commands/secret/addSecret/SecretCreateStep.ts
index ab90c74d7..d7451a334 100644
--- a/src/commands/secret/addSecret/SecretCreateStep.ts
+++ b/src/commands/secret/addSecret/SecretCreateStep.ts
@@ -3,16 +3,21 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { AzureWizardExecuteStep, nonNullProp } from "@microsoft/vscode-azext-utils";
+import { nonNullProp } from "@microsoft/vscode-azext-utils";
import { type Progress } from "vscode";
import { ext } from "../../../extensionVariables";
import { getContainerEnvelopeWithSecrets, type ContainerAppModel } from "../../../tree/ContainerAppItem";
import { localize } from "../../../utils/localize";
+import { AzureWizardActivityOutputExecuteStep } from "../../AzureWizardActivityOutputExecuteStep";
import { updateContainerApp } from "../../updateContainerApp";
import { type ISecretContext } from "../ISecretContext";
-export class SecretCreateStep extends AzureWizardExecuteStep {
+export class SecretCreateStep extends AzureWizardActivityOutputExecuteStep {
public priority: number = 820;
+ public stepName: string = 'secretCreateStep';
+ protected getSuccessString = (context: T) => localize('createSecretSuccess', 'Successfully created secret "{0}" for container app "{1}".', context.secretName, context.containerApp?.name);
+ protected getFailString = (context: T) => localize('createSecretFail', 'Failed to create secret "{0}" for container app "{1}".', context.newSecretName, context.containerApp?.name);
+ protected getTreeItemLabel = (context: T) => localize('createSecretLabel', 'Create secret "{0}" for container app "{1}"', context.secretName, context.containerApp?.name);
public async execute(context: ISecretContext, progress: Progress<{ message?: string | undefined; increment?: number | undefined }>): Promise {
const containerApp: ContainerAppModel = nonNullProp(context, 'containerApp');