3
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
- import { parseAzureResourceId } from '@microsoft/vscode-azext-azureutils' ;
7
- import { AzureWizardPromptStep , nonNullProp , type IAzureQuickPickItem , type IWizardOptions } from '@microsoft/vscode-azext-utils' ;
6
+ import { CommonRoleDefinitions , createAuthorizationManagementClient , createRoleId , parseAzureResourceId , RoleAssignmentExecuteStep , uiUtils , type Role } from '@microsoft/vscode-azext-azureutils' ;
7
+ import { ActivityChildItem , ActivityChildType , activitySuccessContext , activitySuccessIcon , AzureWizardPromptStep , createContextValue , nonNullProp , type AzureWizardExecuteStep , type IAzureQuickPickItem , type IWizardOptions } from '@microsoft/vscode-azext-utils' ;
8
8
import { localSettingsDescription } from '../../../../../constants-nls' ;
9
+ import { ext } from '../../../../../extensionVariables' ;
9
10
import { localize } from '../../../../../localize' ;
10
11
import { HttpDurableTaskSchedulerClient , type DurableTaskHubResource , type DurableTaskSchedulerClient } from '../../../../../tree/durableTaskScheduler/DurableTaskSchedulerClient' ;
12
+ import { FunctionAppUserAssignedIdentitiesListStep } from '../../../../identity/FunctionAppUserAssignedIdentitiesListStep' ;
11
13
import { type IDTSAzureConnectionWizardContext } from '../IDTSConnectionWizardContext' ;
12
14
import { DurableTaskHubCreateStep } from './DurableTaskHubCreateStep' ;
13
15
import { DurableTaskHubNameStep } from './DurableTaskHubNameStep' ;
@@ -22,7 +24,7 @@ export class DurableTaskHubListStep<T extends IDTSAzureConnectionWizardContext>
22
24
23
25
public async prompt ( context : T ) : Promise < void > {
24
26
context . dtsHub = ( await context . ui . showQuickPick ( await this . getPicks ( context ) , {
25
- placeHolder : localize ( 'selectTaskScheduler' , 'Select a Durable Task Scheduler ' ) ,
27
+ placeHolder : localize ( 'selectTaskScheduler' , 'Select a durable task hub ' ) ,
26
28
} ) ) . data ;
27
29
28
30
if ( context . dtsHub ) {
@@ -35,17 +37,6 @@ export class DurableTaskHubListStep<T extends IDTSAzureConnectionWizardContext>
35
37
return ! context . dtsHub ;
36
38
}
37
39
38
- public async getSubWizard ( context : T ) : Promise < IWizardOptions < T > | undefined > {
39
- if ( context . dtsHub ) {
40
- return undefined ;
41
- }
42
-
43
- return {
44
- promptSteps : [ new DurableTaskHubNameStep ( this . schedulerClient ) ] ,
45
- executeSteps : [ new DurableTaskHubCreateStep ( this . schedulerClient ) ] ,
46
- } ;
47
- }
48
-
49
40
private async getPicks ( context : T ) : Promise < IAzureQuickPickItem < DurableTaskHubResource | undefined > [ ] > {
50
41
const taskHubs : DurableTaskHubResource [ ] = context . dts ?
51
42
await this . schedulerClient . getSchedulerTaskHubs ( nonNullProp ( context , 'subscription' ) , parseAzureResourceId ( context . dts . id ) . resourceGroup , context . dts . name ) : [ ] ;
@@ -66,4 +57,65 @@ export class DurableTaskHubListStep<T extends IDTSAzureConnectionWizardContext>
66
57
} ) ,
67
58
] ;
68
59
}
60
+
61
+ public async getSubWizard ( context : T ) : Promise < IWizardOptions < T > | undefined > {
62
+ const promptSteps : AzureWizardPromptStep < T > [ ] = [ ] ;
63
+ const executeSteps : AzureWizardExecuteStep < T > [ ] = [ ] ;
64
+
65
+ if ( ! context . dtsHub ) {
66
+ promptSteps . push ( new DurableTaskHubNameStep ( this . schedulerClient ) ) ;
67
+ executeSteps . push ( new DurableTaskHubCreateStep ( this . schedulerClient ) ) ;
68
+ }
69
+
70
+ const dtsContributorRole : Role = {
71
+ scopeId : context . dtsHub ?. id ,
72
+ roleDefinitionId : createRoleId ( context . subscriptionId , CommonRoleDefinitions . durableTaskDataContributor ) ,
73
+ roleDefinitionName : CommonRoleDefinitions . durableTaskDataContributor . roleName ,
74
+ } ;
75
+
76
+ promptSteps . push ( new FunctionAppUserAssignedIdentitiesListStep ( dtsContributorRole /** targetRole */ , { identityAssignStepPriority : 180 } ) ) ;
77
+ executeSteps . push ( new RoleAssignmentExecuteStep ( this . getDTSRoleAssignmentCallback ( context , dtsContributorRole ) , { priority : 190 } ) ) ;
78
+
79
+ return { promptSteps, executeSteps } ;
80
+ }
81
+
82
+ private getDTSRoleAssignmentCallback ( context : T , role : Role ) : ( ) => Promise < Role [ ] > {
83
+ return async ( ) => {
84
+ const roleAssignment : Role = {
85
+ ...role ,
86
+ // This id may be missing when the role is initially passed in,
87
+ // but by the time we run the step, we should have the populated id ready.
88
+ scopeId : context . dtsHub ?. id ,
89
+ } ;
90
+
91
+ if ( ! roleAssignment . scopeId ) {
92
+ return [ ] ;
93
+ }
94
+
95
+ const amClient = await createAuthorizationManagementClient ( context ) ;
96
+ const roleAssignments = await uiUtils . listAllIterator ( amClient . roleAssignments . listForScope (
97
+ roleAssignment . scopeId ,
98
+ {
99
+ // $filter=principalId eq {id}
100
+ filter : `principalId eq '{${ context . managedIdentity ?. principalId } }'` ,
101
+ }
102
+ ) ) ;
103
+
104
+ const hasRoleAssignment = roleAssignments . some ( r => ! ! r . roleDefinitionId ?. endsWith ( role . roleDefinitionId ) ) ;
105
+ if ( hasRoleAssignment ) {
106
+ context . activityChildren ?. push (
107
+ new ActivityChildItem ( {
108
+ label : localize ( 'verifyIdentityWithRoleLabel' , 'Verify identity "{0}" has role "{1}"' , context . managedIdentity ?. name , role . roleDefinitionName ) ,
109
+ description : '0s' ,
110
+ contextValue : createContextValue ( [ 'roleAssignmentExecuteStepItem' , activitySuccessContext ] ) ,
111
+ activityType : ActivityChildType . Success ,
112
+ iconPath : activitySuccessIcon ,
113
+ } ) ,
114
+ ) ;
115
+ ext . outputChannel . appendLog ( localize ( 'verifyIdentity' , 'Successfully verified identity "{0}" has role "{1}".' , context . managedIdentity ?. name , role . roleDefinitionName ) ) ;
116
+ }
117
+
118
+ return hasRoleAssignment ? [ ] : [ roleAssignment ] ;
119
+ } ;
120
+ }
69
121
}
0 commit comments