Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@
"command": "containerApps.stopStreamingLogs",
"title": "%containerApps.stopStreamingLogs%",
"category": "Azure Container Apps"
},
{
"command": "containerApps.createAcr",
"title": "%containerApps.createAcr%",
"category": "Azure Container Apps"
}
],
"menus": {
Expand Down
3 changes: 2 additions & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@
"containerApps.disconnectRepo": "Disconnect from Repo",
"containerApps.openGitHubRepo": "Open Repo in GitHub",
"containerApps.startStreamingLogs": "Start Streaming Logs...",
"containerApps.stopStreamingLogs": "Stop Streaming Logs..."
"containerApps.stopStreamingLogs": "Stop Streaming Logs...",
"containerApps.createAcr": "Create Azure Container Registry"
Comment thread
MicroFish91 marked this conversation as resolved.
Outdated
}
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.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { KnownSkuName, Registry } from "@azure/arm-containerregistry";
import { IResourceGroupWizardContext } from "@microsoft/vscode-azext-azureutils";
import { ExecuteActivityContext } from "@microsoft/vscode-azext-utils";

export interface ICreateAcrContext extends IResourceGroupWizardContext, ExecuteActivityContext {
Comment thread
MicroFish91 marked this conversation as resolved.
Outdated
registryName?: string;
sku?: KnownSkuName;
Comment thread
MicroFish91 marked this conversation as resolved.
Outdated
registry?: Registry;
newResourceGroupName?: string;
}
Comment thread
MicroFish91 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { ContainerRegistryManagementClient } from "@azure/arm-containerregistry";
import { LocationListStep } from "@microsoft/vscode-azext-azureutils";
import { AzureWizardExecuteStep, nonNullProp } from "@microsoft/vscode-azext-utils";
import { createContainerRegistryManagementClient } from "../../../../../../utils/azureClients";
import { ICreateAcrContext } from "./ICreateAcrContext";

export class RegistryCreateStep extends AzureWizardExecuteStep<ICreateAcrContext> {
public priority: number = 150;

public async execute(context: ICreateAcrContext): Promise<void> {
const client: ContainerRegistryManagementClient = await createContainerRegistryManagementClient(context);

context.registry = await client.registries.beginCreateAndWait(
nonNullProp(context, 'newResourceGroupName'),
nonNullProp(context, 'registryName'),
{
location: (await LocationListStep.getLocation(context)).name,
sku: { name: nonNullProp(context, 'sku') },
adminUserEnabled: true
}
);
}

public shouldExecute(): boolean {
return true;
Comment thread
MicroFish91 marked this conversation as resolved.
Outdated
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { ContainerRegistryManagementClient, RegistryNameStatus } from "@azure/arm-containerregistry";
import { AzureWizardPromptStep } from "@microsoft/vscode-azext-utils";
import { createContainerRegistryManagementClient } from "../../../../../../utils/azureClients";
import { localize } from "../../../../../../utils/localize";
import { ICreateAcrContext } from "./ICreateAcrContext";

export class RegistryNameStep extends AzureWizardPromptStep<ICreateAcrContext> {
public async prompt(context: ICreateAcrContext): Promise<void> {
context.registryName = await context.ui.showInputBox({
prompt: localize('registryName', 'Enter a name for the new registry'),
validateInput: async (value: string | undefined): Promise<string | undefined> => await this.validateInput(context, value)
})
}

public shouldPrompt(context: ICreateAcrContext): boolean {
return !context.registryName;
}

private async validateInput(context: ICreateAcrContext, name: string | undefined): Promise<string | undefined> {
name = name ? name.trim() : '';

if (!/^[a-z][a-zA-Z0-9]*$/.test(name)) {
return localize('validateInputError', `Connection names can only consist of alphanumeric characters.`); //make it between 5 and 50 character
Comment thread
MicroFish91 marked this conversation as resolved.
Outdated
} else {
const client: ContainerRegistryManagementClient = await createContainerRegistryManagementClient(context);
Comment thread
MicroFish91 marked this conversation as resolved.
Outdated
const nameResponse: RegistryNameStatus = await client.registries.checkNameAvailability({ name: name, type: "Microsoft.ContainerRegistry/registries" });
if (nameResponse.nameAvailable === false) {
return localize('validateInputError', `The registry name ${name} is already in use.`);
}
}
return undefined;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { KnownSkuName } from "@azure/arm-containerregistry";
import { AzureWizardPromptStep, IAzureQuickPickItem } from "@microsoft/vscode-azext-utils";
import { ICreateAcrContext } from "./ICreateAcrContext";

export class SkuListStep extends AzureWizardPromptStep<ICreateAcrContext> {
public async prompt(context: ICreateAcrContext): Promise<void> {
const placeHolder: string = "Select a SKU";
Comment thread
MicroFish91 marked this conversation as resolved.
Outdated
const picks: IAzureQuickPickItem<KnownSkuName>[] = [
{ label: "Basic", data: KnownSkuName.Basic },
Comment thread
MicroFish91 marked this conversation as resolved.
Outdated
{ label: "Standard", data: KnownSkuName.Standard },
{ label: "Premium", data: KnownSkuName.Premium },
];

context.sku = (await context.ui.showQuickPick(picks, {
placeHolder,
suppressPersistence: true
})).data;
}

public shouldPrompt(context: ICreateAcrContext): boolean {
return !context.sku;
}
}
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.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { LocationListStep, ResourceGroupCreateStep } from "@microsoft/vscode-azext-azureutils";
import { AzureWizard, AzureWizardExecuteStep, AzureWizardPromptStep, IActionContext, createSubscriptionContext, nonNullValue, subscriptionExperience } from "@microsoft/vscode-azext-utils";
import { AzureSubscription } from "@microsoft/vscode-azureresources-api";
import { ext } from "../../../../../../extensionVariables";
import { createActivityContext } from "../../../../../../utils/activityUtils";
import { localize } from "../../../../../../utils/localize";
import { ICreateAcrContext } from "./ICreateAcrContext";
import { RegistryCreateStep } from "./RegistryCreateStep";
import { RegistryNameStep } from "./RegistryNameStep";
import { SkuListStep } from "./SkuListStep";

export async function createAcr(context: IActionContext, node?: { subscription: AzureSubscription }): Promise<void> {
const subscription = node?.subscription ?? await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider);

const wizardContext: ICreateAcrContext = {
...context,
...createSubscriptionContext(subscription),
...(await createActivityContext())
}

const title: string = localize('createAcr', "Create container registry");
Comment thread
MicroFish91 marked this conversation as resolved.
Outdated

const promptSteps: AzureWizardPromptStep<ICreateAcrContext>[] = [
new RegistryNameStep(),
new SkuListStep(),
];

const executeSteps: AzureWizardExecuteStep<ICreateAcrContext>[] = [
new ResourceGroupCreateStep(),
Comment thread
MicroFish91 marked this conversation as resolved.
new RegistryCreateStep(),
];

LocationListStep.addProviderForFiltering(wizardContext, 'Microsoft.App', 'managedEnvironments'); //need to see which provider to use
LocationListStep.addStep(wizardContext, promptSteps);


const wizard: AzureWizard<ICreateAcrContext> = new AzureWizard(wizardContext, {
title,
promptSteps,
executeSteps,
showLoadingPrompt: true
});

await wizard.prompt();

wizardContext.newResourceGroupName = nonNullValue(wizardContext.registryName);
wizardContext.activityTitle = localize('createAcr', 'Create Azure Container Registry "{0}"', wizardContext.registryName);

await wizard.execute();
}
4 changes: 4 additions & 0 deletions src/commands/registerCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { deleteContainerApp } from './deleteContainerApp/deleteContainerApp';
import { deleteManagedEnvironment } from './deleteManagedEnvironment/deleteManagedEnvironment';
import { deployImage } from './deployImage/deployImage';
import { deployImageApi } from './deployImage/deployImageApi';
import { createAcr } from './deployImage/imageSource/containerRegistry/acr/createAcr/createAcr';
import { editContainerApp } from './editContainerApp';
import { connectToGitHub } from './gitHub/connectToGitHub/connectToGitHub';
import { disconnectRepo } from './gitHub/disconnectRepo/disconnectRepo';
Expand Down Expand Up @@ -91,4 +92,7 @@ export function registerCommands(): void {
// Suppress "Report an Issue" button for all errors in favor of the command
registerErrorHandler(c => c.errorHandling.suppressReportIssue = true);
registerReportIssueCommand('containerApps.reportIssue');

// registries
registerCommandWithTreeNodeUnwrapping('containerApps.createAcr', createAcr);
}