Skip to content

Commit 55a8019

Browse files
committed
Add AcrPullVerifyStep
1 parent ce1794d commit 55a8019

File tree

4 files changed

+74
-28
lines changed

4 files changed

+74
-28
lines changed

src/commands/EXECUTE_PRIORITY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ When creating or updating resources, execute steps should occupy certain priorit
2929
#### Steps
3030
##### Managed Identity Registry Credential
3131
- ManagedEnvironmentIdentityEnableStep: 450
32-
- AcrPullEnableStep: 460
32+
- AcrPullVerifyStep: 460
33+
- AcrPullEnableStep: 461
3334
- ManagedIdentityRegistryCredentialAddConfigurationStep: 470
3435

3536
##### Admin User Registry Credential

src/commands/registryCredentials/identity/AcrPullEnableStep.ts

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,28 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { KnownPrincipalType, type AuthorizationManagementClient, type RoleAssignment, type RoleAssignmentCreateParameters } from "@azure/arm-authorization";
7-
import { uiUtils } from "@microsoft/vscode-azext-azureutils";
6+
import { KnownPrincipalType, type AuthorizationManagementClient, type RoleAssignmentCreateParameters } from "@azure/arm-authorization";
87
import { AzureWizardExecuteStep, GenericParentTreeItem, GenericTreeItem, activityFailContext, activityFailIcon, activitySuccessContext, activitySuccessIcon, createUniversallyUniqueContextValue, nonNullValueAndProp, type ExecuteActivityOutput } from "@microsoft/vscode-azext-utils";
98
import * as crypto from "crypto";
109
import { type Progress } from "vscode";
1110
import { createAuthorizationManagementClient } from "../../../utils/azureClients";
1211
import { localize } from "../../../utils/localize";
12+
import { acrPullRoleId } from "./AcrPullVerifyStep";
1313
import { type ManagedIdentityRegistryCredentialsContext } from "./ManagedIdentityRegistryCredentialsContext";
1414

15-
const acrPullRoleId: string = '7f951dda-4ed3-4680-a7ca-43fe172d538d';
16-
1715
export class AcrPullEnableStep extends AzureWizardExecuteStep<ManagedIdentityRegistryCredentialsContext> {
18-
public priority: number = 460;
19-
20-
// Add a configureBeforeExecute
16+
public priority: number = 461;
2117

2218
public async execute(context: ManagedIdentityRegistryCredentialsContext, progress: Progress<{ message?: string | undefined; increment?: number | undefined }>): Promise<void> {
2319
const client: AuthorizationManagementClient = await createAuthorizationManagementClient(context);
24-
const registryId: string = nonNullValueAndProp(context.registry, 'id');
25-
const managedEnvironmentIdentity: string = nonNullValueAndProp(context.managedEnvironment?.identity, 'principalId');
26-
27-
if (await this.hasAcrPullAssignment(client, registryId, managedEnvironmentIdentity)) {
28-
return;
29-
}
30-
3120
const roleCreateParams: RoleAssignmentCreateParameters = {
3221
description: 'acr pull',
3322
roleDefinitionId: `/providers/Microsoft.Authorization/roleDefinitions/${acrPullRoleId}`,
3423
principalId: nonNullValueAndProp(context.managedEnvironment?.identity, 'principalId'),
3524
principalType: KnownPrincipalType.ServicePrincipal,
3625
};
3726

38-
progress.report({ message: localize('updatingRegistryCredentials', 'Updating registry credentials...') });
27+
progress.report({ message: localize('addingAcrPull', 'Adding ACR pull role...') });
3928
await client.roleAssignments.create(
4029
nonNullValueAndProp(context.registry, 'id'),
4130
crypto.randomUUID(),
@@ -44,18 +33,7 @@ export class AcrPullEnableStep extends AzureWizardExecuteStep<ManagedIdentityReg
4433
}
4534

4635
public shouldExecute(context: ManagedIdentityRegistryCredentialsContext): boolean {
47-
return !!context.registry;
48-
}
49-
50-
private async hasAcrPullAssignment(client: AuthorizationManagementClient, registryId: string, managedEnvironmentIdentity: string): Promise<boolean> {
51-
const roleAssignments: RoleAssignment[] = await uiUtils.listAllIterator(client.roleAssignments.listForScope(
52-
registryId,
53-
{
54-
// $filter=principalId eq {id}
55-
filter: `principalId eq '{${managedEnvironmentIdentity}}'`,
56-
}
57-
));
58-
return roleAssignments.some(r => !!r.roleDefinitionId?.endsWith(acrPullRoleId));
36+
return !!context.registry && !context.hasAcrPullRole;
5937
}
6038

6139
public createSuccessOutput(): ExecuteActivityOutput {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { type AuthorizationManagementClient, type RoleAssignment } from "@azure/arm-authorization";
7+
import { uiUtils } from "@microsoft/vscode-azext-azureutils";
8+
import { AzureWizardExecuteStep, GenericParentTreeItem, GenericTreeItem, activityFailContext, activityFailIcon, activitySuccessContext, activitySuccessIcon, createUniversallyUniqueContextValue, nonNullValueAndProp, type ExecuteActivityOutput } from "@microsoft/vscode-azext-utils";
9+
import { type Progress } from "vscode";
10+
import { createAuthorizationManagementClient } from "../../../utils/azureClients";
11+
import { localize } from "../../../utils/localize";
12+
import { type ManagedIdentityRegistryCredentialsContext } from "./ManagedIdentityRegistryCredentialsContext";
13+
14+
export const acrPullRoleId: string = '7f951dda-4ed3-4680-a7ca-43fe172d538d';
15+
16+
export class AcrPullVerifyStep extends AzureWizardExecuteStep<ManagedIdentityRegistryCredentialsContext> {
17+
public priority: number = 460;
18+
19+
public async execute(context: ManagedIdentityRegistryCredentialsContext, progress: Progress<{ message?: string | undefined; increment?: number | undefined }>): Promise<void> {
20+
const client: AuthorizationManagementClient = await createAuthorizationManagementClient(context);
21+
const registryId: string = nonNullValueAndProp(context.registry, 'id');
22+
const managedEnvironmentIdentity: string = nonNullValueAndProp(context.managedEnvironment?.identity, 'principalId');
23+
24+
progress.report({ message: localize('verifyingAcrPull', 'Verifying ACR pull role...') })
25+
const roleAssignments: RoleAssignment[] = await uiUtils.listAllIterator(client.roleAssignments.listForScope(
26+
registryId,
27+
{
28+
// $filter=principalId eq {id}
29+
filter: `principalId eq '{${managedEnvironmentIdentity}}'`,
30+
}
31+
));
32+
33+
context.hasAcrPullRole = roleAssignments.some(r => !!r.roleDefinitionId?.endsWith(acrPullRoleId));
34+
}
35+
36+
public shouldExecute(context: ManagedIdentityRegistryCredentialsContext): boolean {
37+
return !!context.registry;
38+
}
39+
40+
public createSuccessOutput(context: ManagedIdentityRegistryCredentialsContext): ExecuteActivityOutput {
41+
if (context.hasAcrPullRole) {
42+
return {
43+
item: new GenericTreeItem(undefined, {
44+
contextValue: createUniversallyUniqueContextValue(['containerRegistryAcrPullVerifyStepSuccessItem', activitySuccessContext]),
45+
label: localize('verifyAcrPull', 'Verify "{0}" access for container environment identity', 'acrPull'),
46+
iconPath: activitySuccessIcon
47+
}),
48+
message: localize('verifyAcrPullSuccess', 'Successfully verified "{0}" access for container environment identity.', 'acrPull'),
49+
};
50+
} else {
51+
// 'AcrPullEnableStep' will cover showing this output
52+
return {};
53+
}
54+
}
55+
56+
public createFailOutput(): ExecuteActivityOutput {
57+
return {
58+
item: new GenericParentTreeItem(undefined, {
59+
contextValue: createUniversallyUniqueContextValue(['containerRegistryAcrPullVerifyStepFailItem', activityFailContext]),
60+
label: localize('verifyAcrPull', 'Verify "{0}" access for container environment identity"', 'acrPull'),
61+
iconPath: activityFailIcon
62+
}),
63+
message: localize('verifyAcrPullFail', 'Failed to verify "{0}" access for container environment identity.', 'acrPull'),
64+
};
65+
}
66+
}

src/commands/registryCredentials/identity/ManagedIdentityRegistryCredentialsContext.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ import { type CreateAcrContext } from "../../image/imageSource/containerRegistry
99
import { type ManagedEnvironmentRequiredContext } from "../../ManagedEnvironmentContext";
1010

1111
export interface ManagedIdentityRegistryCredentialsContext extends CreateAcrContext, ManagedEnvironmentRequiredContext, IContainerAppContext {
12+
hasAcrPullRole?: boolean;
1213
newRegistryCredential?: RegistryCredentials;
1314
}

0 commit comments

Comments
 (0)