@@ -6,7 +6,7 @@ import nodeunit = require('nodeunit');
6
6
import cloudformation = require( '../lib' ) ;
7
7
8
8
export = nodeunit . testCase ( {
9
- CreateReplaceChangeSet : {
9
+ ' CreateReplaceChangeSet' : {
10
10
works ( test : nodeunit . Test ) {
11
11
const stack = new cdk . Stack ( ) ;
12
12
const pipelineRole = new RoleDouble ( stack , 'PipelineRole' ) ;
@@ -21,11 +21,7 @@ export = nodeunit.testCase({
21
21
22
22
_assertPermissionGranted ( test , pipelineRole . statements , 'iam:PassRole' , action . role . roleArn ) ;
23
23
24
- const stackArn = cdk . ArnUtils . fromComponents ( {
25
- service : 'cloudformation' ,
26
- resource : 'stack' ,
27
- resourceName : 'MyStack/*'
28
- } ) ;
24
+ const stackArn = _stackArn ( 'MyStack' ) ;
29
25
const changeSetCondition = { StringEquals : { 'cloudformation:ChangeSetName' : 'MyChangeSet' } } ;
30
26
_assertPermissionGranted ( test , pipelineRole . statements , 'cloudformation:DescribeStacks' , stackArn ) ;
31
27
_assertPermissionGranted ( test , pipelineRole . statements , 'cloudformation:DescribeChangeSet' , stackArn , changeSetCondition ) ;
@@ -44,7 +40,7 @@ export = nodeunit.testCase({
44
40
test . done ( ) ;
45
41
}
46
42
} ,
47
- ExecuteChangeSet : {
43
+ ' ExecuteChangeSet' : {
48
44
works ( test : nodeunit . Test ) {
49
45
const stack = new cdk . Stack ( ) ;
50
46
const pipelineRole = new RoleDouble ( stack , 'PipelineRole' ) ;
@@ -55,11 +51,7 @@ export = nodeunit.testCase({
55
51
stackName : 'MyStack' ,
56
52
} ) ;
57
53
58
- const stackArn = cdk . ArnUtils . fromComponents ( {
59
- service : 'cloudformation' ,
60
- resource : 'stack' ,
61
- resourceName : 'MyStack/*'
62
- } ) ;
54
+ const stackArn = _stackArn ( 'MyStack' ) ;
63
55
_assertPermissionGranted ( test , pipelineRole . statements , 'cloudformation:ExecuteChangeSet' , stackArn ,
64
56
{ StringEquals : { 'cloudformation:ChangeSetName' : 'MyChangeSet' } } ) ;
65
57
@@ -71,7 +63,44 @@ export = nodeunit.testCase({
71
63
72
64
test . done ( ) ;
73
65
}
74
- }
66
+ } ,
67
+
68
+ 'the CreateUpdateStack Action sets the DescribeStack*, Create/Update/DeleteStack & PassRole permissions' ( test : nodeunit . Test ) {
69
+ const stack = new cdk . Stack ( ) ;
70
+ const pipelineRole = new RoleDouble ( stack , 'PipelineRole' ) ;
71
+ const action = new cloudformation . PipelineCreateUpdateStackAction ( stack , 'Action' , {
72
+ stage : new StageDouble ( { pipelineRole } ) ,
73
+ templatePath : new cpapi . Artifact ( stack as any , 'TestArtifact' ) . atPath ( 'some/file' ) ,
74
+ stackName : 'MyStack' ,
75
+ } ) ;
76
+ const stackArn = _stackArn ( 'MyStack' ) ;
77
+
78
+ _assertPermissionGranted ( test , pipelineRole . statements , 'cloudformation:DescribeStack*' , stackArn ) ;
79
+ _assertPermissionGranted ( test , pipelineRole . statements , 'cloudformation:CreateStack' , stackArn ) ;
80
+ _assertPermissionGranted ( test , pipelineRole . statements , 'cloudformation:UpdateStack' , stackArn ) ;
81
+ _assertPermissionGranted ( test , pipelineRole . statements , 'cloudformation:DeleteStack' , stackArn ) ;
82
+
83
+ _assertPermissionGranted ( test , pipelineRole . statements , 'iam:PassRole' , action . role . roleArn ) ;
84
+
85
+ test . done ( ) ;
86
+ } ,
87
+
88
+ 'the DeleteStack Action sets the DescribeStack*, DeleteStack & PassRole permissions' ( test : nodeunit . Test ) {
89
+ const stack = new cdk . Stack ( ) ;
90
+ const pipelineRole = new RoleDouble ( stack , 'PipelineRole' ) ;
91
+ const action = new cloudformation . PipelineDeleteStackAction ( stack , 'Action' , {
92
+ stage : new StageDouble ( { pipelineRole } ) ,
93
+ stackName : 'MyStack' ,
94
+ } ) ;
95
+ const stackArn = _stackArn ( 'MyStack' ) ;
96
+
97
+ _assertPermissionGranted ( test , pipelineRole . statements , 'cloudformation:DescribeStack*' , stackArn ) ;
98
+ _assertPermissionGranted ( test , pipelineRole . statements , 'cloudformation:DeleteStack' , stackArn ) ;
99
+
100
+ _assertPermissionGranted ( test , pipelineRole . statements , 'iam:PassRole' , action . role . roleArn ) ;
101
+
102
+ test . done ( ) ;
103
+ } ,
75
104
} ) ;
76
105
77
106
interface PolicyStatementJson {
@@ -121,7 +150,7 @@ function _assertPermissionGranted(test: nodeunit.Test, statements: PolicyStateme
121
150
: '' ;
122
151
const statementsStr = JSON . stringify ( cdk . resolve ( statements ) , null , 2 ) ;
123
152
test . ok ( _grantsPermission ( statements , action , resource , conditions ) ,
124
- `Expected to find a statement granting ${ action } on ${ cdk . resolve ( resource ) } ${ conditionStr } , found:\n${ statementsStr } ` ) ;
153
+ `Expected to find a statement granting ${ action } on ${ JSON . stringify ( cdk . resolve ( resource ) ) } ${ conditionStr } , found:\n${ statementsStr } ` ) ;
125
154
}
126
155
127
156
function _grantsPermission ( statements : PolicyStatementJson [ ] , action : string , resource : string , conditions ?: any ) {
@@ -145,6 +174,14 @@ function _isOrContains(entity: string | string[], value: string): boolean {
145
174
return false ;
146
175
}
147
176
177
+ function _stackArn ( stackName : string ) : string {
178
+ return cdk . ArnUtils . fromComponents ( {
179
+ service : 'cloudformation' ,
180
+ resource : 'stack' ,
181
+ resourceName : `${ stackName } /*` ,
182
+ } ) ;
183
+ }
184
+
148
185
class StageDouble implements cpapi . IStage , cpapi . IInternalStage {
149
186
public readonly name : string ;
150
187
public readonly pipelineArn : string ;
0 commit comments