diff --git a/azure/index.d.ts b/azure/index.d.ts index 522ee85893..6fbf92711f 100644 --- a/azure/index.d.ts +++ b/azure/index.d.ts @@ -5,12 +5,12 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { AuthorizationManagementClient, type RoleDefinition } from '@azure/arm-authorization'; -import { Identity, ManagedServiceIdentityClient } from '@azure/arm-msi'; +import type { AuthorizationManagementClient, RoleDefinition } from '@azure/arm-authorization'; +import type { Identity, ManagedServiceIdentityClient } from '@azure/arm-msi'; import type { ExtendedLocation, ResourceGroup } from '@azure/arm-resources'; import type { Location } from '@azure/arm-resources-subscriptions'; import type { StorageAccount } from '@azure/arm-storage'; -import { type StorageManagementClient } from '@azure/arm-storage'; +import type { StorageManagementClient } from '@azure/arm-storage'; import type { ServiceClient, ServiceClientOptions } from '@azure/core-client'; import type { PagedAsyncIterableIterator } from '@azure/core-paging'; import type { PipelineRequestOptions, PipelineResponse } from '@azure/core-rest-pipeline'; diff --git a/azure/package-lock.json b/azure/package-lock.json index 05770ec620..2b9336d885 100644 --- a/azure/package-lock.json +++ b/azure/package-lock.json @@ -1,21 +1,21 @@ { "name": "@microsoft/vscode-azext-azureutils", - "version": "4.0.1", + "version": "5.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@microsoft/vscode-azext-azureutils", - "version": "4.0.1", + "version": "5.0.0", "license": "MIT", "dependencies": { "@azure/arm-authorization": "^9.0.0", "@azure/arm-authorization-profile-2020-09-01-hybrid": "^2.1.0", "@azure/arm-msi": "^2.2.0", - "@azure/arm-resources": "^5.0.0", + "@azure/arm-resources": "^7.0.0", "@azure/arm-resources-profile-2020-09-01-hybrid": "^2.1.0", "@azure/arm-resources-subscriptions": "^2.1.0", - "@azure/arm-storage": "^18.6.0", + "@azure/arm-storage": "^19.1.0", "@azure/arm-storage-profile-2020-09-01-hybrid": "^2.1.0", "@azure/core-client": "^1.10.1", "@azure/core-rest-pipeline": "^1.22.2", @@ -99,20 +99,21 @@ } }, "node_modules/@azure/arm-resources": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@azure/arm-resources/-/arm-resources-5.2.0.tgz", - "integrity": "sha512-wQyuhL8WQsLkW/KMdik8bLJIJCz3Z6mg/+AKm0KedgK73SKhicSqYP+ed3t+43tLlRFltcrmGKMcHLQ+Jhv/6A==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@azure/arm-resources/-/arm-resources-7.0.0.tgz", + "integrity": "sha512-ezC1YLuPp1bh0GQFALcBvBxAB+9H5O0ynS40jp1t6hTlYe2t61cSplM3M4+4+nt9FCFZOjQSgAwj4KWYb8gruA==", + "license": "MIT", "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.7.0", - "@azure/core-lro": "^2.5.0", - "@azure/core-paging": "^1.2.0", - "@azure/core-rest-pipeline": "^1.8.0", - "tslib": "^2.2.0" + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-lro": "^2.5.4", + "@azure/core-paging": "^1.6.2", + "@azure/core-rest-pipeline": "^1.19.0", + "tslib": "^2.8.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=20.0.0" } }, "node_modules/@azure/arm-resources-profile-2020-09-01-hybrid": { @@ -148,10 +149,22 @@ "node": ">=14.0.0" } }, + "node_modules/@azure/arm-resources/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@azure/arm-storage": { - "version": "18.6.0", - "resolved": "https://registry.npmjs.org/@azure/arm-storage/-/arm-storage-18.6.0.tgz", - "integrity": "sha512-dyN50fxts2xClCLIQY8qoDepYx2ql/eW5cVOy8XP+5zt9wIr1cgN2Mmv9/so2HDg6M/zOz8LhrvY+bS2blbhDQ==", + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/@azure/arm-storage/-/arm-storage-19.1.0.tgz", + "integrity": "sha512-eGwTw2lHVgAXNMOFN2Y6wWmZ700/Payubig4fSf0Yaz9nn3UzNqNor57wEtCxf4VxuhoXcD8k2bisjddu4jNGQ==", "license": "MIT", "dependencies": { "@azure/abort-controller": "^2.1.2", diff --git a/azure/package.json b/azure/package.json index bad7a0db3f..8c7ad07f69 100644 --- a/azure/package.json +++ b/azure/package.json @@ -1,7 +1,7 @@ { "name": "@microsoft/vscode-azext-azureutils", "author": "Microsoft Corporation", - "version": "4.0.1", + "version": "5.0.0", "description": "Common Azure utils for developing Azure extensions for VS Code", "tags": [ "azure", @@ -39,10 +39,10 @@ "@azure/arm-authorization": "^9.0.0", "@azure/arm-authorization-profile-2020-09-01-hybrid": "^2.1.0", "@azure/arm-msi": "^2.2.0", - "@azure/arm-resources": "^5.0.0", + "@azure/arm-resources": "^7.0.0", "@azure/arm-resources-profile-2020-09-01-hybrid": "^2.1.0", "@azure/arm-resources-subscriptions": "^2.1.0", - "@azure/arm-storage": "^18.6.0", + "@azure/arm-storage": "^19.1.0", "@azure/arm-storage-profile-2020-09-01-hybrid": "^2.1.0", "@azure/core-client": "^1.10.1", "@azure/core-rest-pipeline": "^1.22.2", diff --git a/azure/src/clients.ts b/azure/src/clients.ts index e5e3d36911..bea4fdafe7 100644 --- a/azure/src/clients.ts +++ b/azure/src/clients.ts @@ -4,29 +4,36 @@ *--------------------------------------------------------------------------------------------*/ import type { AuthorizationManagementClient } from '@azure/arm-authorization'; +import type { AuthorizationManagementClient as PAMC } from '@azure/arm-authorization-profile-2020-09-01-hybrid'; import type { ManagedServiceIdentityClient } from '@azure/arm-msi'; import type { ResourceManagementClient } from '@azure/arm-resources'; +import type { ResourceManagementClient as PRMC } from '@azure/arm-resources-profile-2020-09-01-hybrid'; import type { SubscriptionClient } from '@azure/arm-resources-subscriptions'; import type { StorageManagementClient } from '@azure/arm-storage'; +import type { StorageManagementClient as PSMC } from '@azure/arm-storage-profile-2020-09-01-hybrid'; import type { AzExtClientType } from '../index'; import { createAzureClient, createAzureSubscriptionClient, InternalAzExtClientContext, parseClientContext } from './createAzureClient'; +export type CommonAuthorizationManagementClient = AuthorizationManagementClient | PAMC; +export type CommonResourcesClient = ResourceManagementClient | PRMC; +export type CommonStorageManagementClient = StorageManagementClient | PSMC; + // Lazy-load @azure packages to improve startup performance. // NOTE: The client is the only import that matters, the rest of the types disappear when compiled to JavaScript -export async function createStorageClient(context: InternalAzExtClientContext): Promise { +export async function createStorageClient(context: InternalAzExtClientContext): Promise { if (parseClientContext(context).isCustomCloud) { - return createAzureClient(context, (await import('@azure/arm-storage-profile-2020-09-01-hybrid')).StorageManagementClient); + return createAzureClient(context, (await import('@azure/arm-storage-profile-2020-09-01-hybrid')).StorageManagementClient); } else { return createAzureClient(context, (await import('@azure/arm-storage')).StorageManagementClient as unknown as AzExtClientType); } } -export async function createResourcesClient(context: InternalAzExtClientContext): Promise { +export async function createResourcesClient(context: InternalAzExtClientContext): Promise { if (parseClientContext(context).isCustomCloud) { - return createAzureClient(context, (await import('@azure/arm-resources-profile-2020-09-01-hybrid')).ResourceManagementClient); + return createAzureClient(context, (await import('@azure/arm-resources-profile-2020-09-01-hybrid')).ResourceManagementClient); } else { - return createAzureClient(context, (await import('@azure/arm-resources')).ResourceManagementClient); + return createAzureClient(context, (await import('@azure/arm-resources')).ResourceManagementClient as unknown as AzExtClientType); } } @@ -34,14 +41,18 @@ export async function createManagedServiceIdentityClient(context: InternalAzExtC return createAzureClient(context, (await import('@azure/arm-msi')).ManagedServiceIdentityClient as unknown as AzExtClientType); } -export async function createAuthorizationManagementClient(context: InternalAzExtClientContext): Promise { +export async function createAuthorizationManagementClient(context: InternalAzExtClientContext): Promise { if (parseClientContext(context).isCustomCloud) { - return createAzureClient(context, (await import('@azure/arm-authorization-profile-2020-09-01-hybrid')).AuthorizationManagementClient); + return createAzureClient(context, (await import('@azure/arm-authorization-profile-2020-09-01-hybrid')).AuthorizationManagementClient); } else { return createAzureClient(context, (await import('@azure/arm-authorization')).AuthorizationManagementClient); } } +export function isProfileAuthorizationManagementClient(client: CommonAuthorizationManagementClient): client is PAMC { + return !('listForSubscription' in client.roleAssignments); +} + export async function createSubscriptionsClient(context: InternalAzExtClientContext): Promise { return createAzureSubscriptionClient(context, (await import('@azure/arm-resources-subscriptions')).SubscriptionClient); } diff --git a/azure/src/tree/RoleDefinitionsItem.ts b/azure/src/tree/RoleDefinitionsItem.ts index 199cde3868..259576b001 100644 --- a/azure/src/tree/RoleDefinitionsItem.ts +++ b/azure/src/tree/RoleDefinitionsItem.ts @@ -9,7 +9,7 @@ import { AzExtParentTreeItem, AzExtTreeItem, createGenericElement, createSubscri import { AzExtResourceType, AzureSubscription, getAzExtResourceType } from "@microsoft/vscode-azureresources-api"; import { ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from "vscode"; import * as types from '../../index'; -import { createAuthorizationManagementClient, createSubscriptionsClient } from "../clients"; +import { createAuthorizationManagementClient, createSubscriptionsClient, isProfileAuthorizationManagementClient } from "../clients"; import { createPortalUri } from "../utils/createPortalUri"; import { parseAzureResourceGroupId, parseAzureResourceId } from "../utils/parseAzureResourceId"; import { uiUtils } from "../utils/uiUtils"; @@ -18,6 +18,11 @@ import { getAzureIconPath } from "./IconPath"; export async function createRoleDefinitionsItems(context: IActionContext, subscription: AzureSubscription | ISubscriptionContext, msi: Identity, parentResourceId: string): Promise { const subContext = isAzureSubscription(subscription) ? createSubscriptionContext(subscription) : subscription; const authClient = await createAuthorizationManagementClient([context, subContext]); + + if (isProfileAuthorizationManagementClient(authClient)) { + throw new Error('TODO: no can do boss'); + } + const roleAssignment = await uiUtils.listAllIterator(authClient.roleAssignments.listForSubscription()); // filter the role assignments to only show the ones that are assigned to the msi const roleAssignments = roleAssignment.filter((ra) => ra.principalId === msi.principalId); diff --git a/azure/src/wizard/RoleAssignmentExecuteStep.ts b/azure/src/wizard/RoleAssignmentExecuteStep.ts index 3fef3ec99b..e4c3fef99b 100644 --- a/azure/src/wizard/RoleAssignmentExecuteStep.ts +++ b/azure/src/wizard/RoleAssignmentExecuteStep.ts @@ -81,7 +81,18 @@ class SingleRoleAssignmentExecuteStep { + private async validateStorageAccountName(client: CommonStorageManagementClient, name: string): Promise { name = name.trim(); if (!name || name.length < storageAccountNamingRules.minLength || name.length > storageAccountNamingRules.maxLength) { return vscode.l10n.t('The name must be between {0} and {1} characters.', storageAccountNamingRules.minLength, storageAccountNamingRules.maxLength);