Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@
"category": "Azure Container Apps"
},
{
"command": "containerApps.editScalingRange",
"title": "%containerApps.editScalingRange%",
"command": "containerApps.editScaleRange",
"title": "%containerApps.editScaleRange%",
"category": "Azure Container Apps"
},
{
Expand Down Expand Up @@ -405,7 +405,7 @@
"group": "2@1"
},
{
"command": "containerApps.editScalingRange",
"command": "containerApps.editScaleRange",
"when": "view =~ /(azureResourceGroups|azureFocusView)/ && viewItem =~ /scaleItem/i",
"group": "1@1"
},
Expand Down
2 changes: 1 addition & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"containerApps.deleteConfirmation.ClickButton": "Prompts with a warning dialog where you click a button to delete.",
"containerApps.openInPortal": "Open in Portal",
"containerApps.openConsoleInPortal": "Open Console in Portal",
"containerApps.editScalingRange": "Edit Scaling Range...",
"containerApps.editScaleRange": "Edit Scaling Range...",
"containerApps.addScaleRule": "Add Scale Rule...",
"containerApps.deleteScaleRule": "Delete Scale Rule...",
"containerApps.connectToGitHub": "Connect to GitHub Repository...",
Expand Down
1 change: 1 addition & 0 deletions src/commands/EXECUTE_PRIORITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Reserved

#### Steps

- ScaleRangeUpdateStep: 1110
- AddScaleRuleStep: 1120

### 10. Unallocated Space
Expand Down
4 changes: 2 additions & 2 deletions src/commands/registerCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { createRevisionDraft } from './revisionDraft/createRevisionDraft';
import { deployRevisionDraft } from './revisionDraft/deployRevisionDraft/deployRevisionDraft';
import { discardRevisionDraft } from './revisionDraft/discardRevisionDraft';
import { editRevisionDraft } from './revisionDraft/editRevisionDraft';
import { editScalingRange } from './scaling/editScalingRange';
import { editScaleRange } from './scaling/scaleRange/editScaleRange';
import { addScaleRule } from './scaling/scaleRule/addScaleRule/addScaleRule';
import { deleteScaleRule } from './scaling/scaleRule/deleteScaleRule/deleteScaleRule';
import { addSecret } from './secret/addSecret/addSecret';
Expand Down Expand Up @@ -87,7 +87,7 @@ export function registerCommands(): void {
registerCommandWithTreeNodeUnwrapping('containerApps.discardRevisionDraft', discardRevisionDraft);

// scaling
registerCommandWithTreeNodeUnwrapping('containerApps.editScalingRange', editScalingRange);
registerCommandWithTreeNodeUnwrapping('containerApps.editScaleRange', editScaleRange);
registerCommandWithTreeNodeUnwrapping('containerApps.addScaleRule', addScaleRule);
registerCommandWithTreeNodeUnwrapping('containerApps.deleteScaleRule', deleteScaleRule);

Expand Down
62 changes: 0 additions & 62 deletions src/commands/scaling/editScalingRange.ts

This file was deleted.

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

import type { ExecuteActivityContext } from "@microsoft/vscode-azext-utils";
import type { IContainerAppContext } from "../../IContainerAppContext";

export interface ScaleRangeContext extends IContainerAppContext, ExecuteActivityContext {
newMinRange?: number;
newMaxRange?: number;

scaleMinRange: number;
scaleMaxRange: number;
}
44 changes: 44 additions & 0 deletions src/commands/scaling/scaleRange/ScaleRangePromptStep.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { AzureWizardPromptStep } from '@microsoft/vscode-azext-utils';
import { localize } from '../../../utils/localize';
import type { ScaleRangeContext } from './ScaleRangeContext';

export class ScaleRangePromptStep extends AzureWizardPromptStep<ScaleRangeContext> {
public async prompt(context: ScaleRangeContext): Promise<void> {
const scaleRange: string = (await context.ui.showInputBox({
prompt: localize('editScalingRange', 'Set the range of application replicas that get created in response to a scale rule. Set any range within the minimum of 0 and the maximum of 10 replicas'),
value: `${context.scaleMinRange}-${context.scaleMaxRange}`,
validateInput: this.validateInput,
})).trim();

const [min, max] = scaleRange.split('-').map(range => Number(range));
context.newMinRange = min;
context.newMaxRange = max;
}

public shouldPrompt(context: ScaleRangeContext): boolean {
return !context.newMinRange || !context.newMaxRange;
}

private validateInput(range: string | undefined): string | undefined {
const formatRegex = /^\d{1,2}-\d{1,2}$/;
if (!range || !formatRegex.test(range)) {
return localize('enterRange', 'Please enter the range in the following format "0-10"');
}

const [min, max] = range.split('-').map(range => Number(range));
if (min > 10 || max > 10) {
return localize('maxRangeExceeded', 'The maximum number of replicas is 10.');
} else if (min > max) {
return localize('minHigherThanMax', 'The minimum range cannot be larger than the maximum range.');
} else if (max === 0) {
return localize('maxGreaterThan0', 'The maximum replicas must be greater than 0.');
}

return undefined;
}
}
40 changes: 40 additions & 0 deletions src/commands/scaling/scaleRange/ScaleRangeUpdateStep.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { nonNullProp } from "@microsoft/vscode-azext-utils";
import { ext } from "../../../extensionVariables";
import type { RevisionsItemModel } from "../../../tree/revisionManagement/RevisionItem";
import { localize } from "../../../utils/localize";
import { getParentResourceFromItem } from "../../../utils/revisionDraftUtils";
import { RevisionDraftUpdateBaseStep } from "../../revisionDraft/RevisionDraftUpdateBaseStep";
import type { ScaleRangeContext } from "./ScaleRangeContext";

export class ScaleRangeUpdateStep<T extends ScaleRangeContext> extends RevisionDraftUpdateBaseStep<T> {
public priority: number = 1110;

constructor(baseItem: RevisionsItemModel) {
super(baseItem);
}

public async execute(context: ScaleRangeContext): Promise<void> {
this.revisionDraftTemplate.scale ||= {};
this.revisionDraftTemplate.scale.minReplicas = context.newMinRange;
this.revisionDraftTemplate.scale.maxReplicas = context.newMaxRange;

this.updateRevisionDraftWithTemplate();

context.scaleMinRange = nonNullProp(context, 'newMinRange');
context.scaleMaxRange = nonNullProp(context, 'newMaxRange');

const parentResourceName = getParentResourceFromItem(this.baseItem).name;
ext.outputChannel.appendLog(localize('updatedScaleRange', 'Updated replica scaling range to {0}-{1} for "{2}".', context.newMinRange, context.newMaxRange, parentResourceName));
}

public shouldExecute(context: ScaleRangeContext): boolean {
return context.newMinRange !== undefined && context.newMaxRange !== undefined;
}
}


Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: excessive breaks

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

import type { Revision, Scale } from "@azure/arm-appcontainers";
import { AzureWizard, IActionContext, createSubscriptionContext, nonNullValueAndProp } from "@microsoft/vscode-azext-utils";
import type { ContainerAppModel } from "../../../tree/ContainerAppItem";
import type { ScaleItem } from "../../../tree/scaling/ScaleItem";
import { createActivityContext } from "../../../utils/activityUtils";
import { localize } from "../../../utils/localize";
import { pickScale } from "../../../utils/pickItem/pickScale";
import { getParentResource } from "../../../utils/revisionDraftUtils";
import type { ScaleRangeContext } from "./ScaleRangeContext";
import { ScaleRangePromptStep } from "./ScaleRangePromptStep";
import { ScaleRangeUpdateStep } from "./ScaleRangeUpdateStep";

export async function editScaleRange(context: IActionContext, node?: ScaleItem): Promise<void> {
const item: ScaleItem = node ?? await pickScale(context, { autoSelectDraft: true });
const { containerApp, revision, subscription } = item;

const parentResource: ContainerAppModel | Revision = getParentResource(containerApp, revision);
const scale: Scale = nonNullValueAndProp(parentResource.template, 'scale');

const wizardContext: ScaleRangeContext = {
...context,
...createSubscriptionContext(subscription),
...await createActivityContext(),
containerApp,
subscription,
scaleMinRange: scale.minReplicas ?? 0,
scaleMaxRange: scale.maxReplicas ?? 0
};

const wizard: AzureWizard<ScaleRangeContext> = new AzureWizard(wizardContext, {
title: localize('editScaleRangePre', 'Update replica scaling range for "{0}" (draft)', parentResource.name),
promptSteps: [new ScaleRangePromptStep()],
executeSteps: [new ScaleRangeUpdateStep(item)],
showLoadingPrompt: true
});

await wizard.prompt();
wizardContext.activityTitle = localize('editScaleRange', 'Update replica scaling range to "{0}-{1}" for "{2}" (draft)', wizardContext.newMinRange, wizardContext.newMaxRange, parentResource.name);
await wizard.execute();
}
15 changes: 14 additions & 1 deletion src/utils/revisionDraftUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
*--------------------------------------------------------------------------------------------*/

import { KnownActiveRevisionsMode, Revision } from "@azure/arm-appcontainers";
import { ContainerAppModel } from "../tree/ContainerAppItem";
import { ContainerAppItem, ContainerAppModel } from "../tree/ContainerAppItem";
import type { RevisionsItemModel } from "../tree/revisionManagement/RevisionItem";

/**
* Use to always select the correct parent resource model
Expand All @@ -13,3 +14,15 @@ import { ContainerAppModel } from "../tree/ContainerAppItem";
export function getParentResource(containerApp: ContainerAppModel, revision: Revision): ContainerAppModel | Revision {
return containerApp.revisionsMode === KnownActiveRevisionsMode.Single ? containerApp : revision;
}

/**
* Use to always select the correct parent resource model from an item
* https://github.com/microsoft/vscode-azurecontainerapps/blob/main/src/commands/revisionDraft/README.md
*/
export function getParentResourceFromItem(item: ContainerAppItem | RevisionsItemModel): ContainerAppModel | Revision {
if (ContainerAppItem.isContainerAppItem(item) || item.containerApp.revisionsMode === KnownActiveRevisionsMode.Single) {
return item.containerApp;
} else {
return item.revision;
}
}