1
+ package aws
2
+
3
+ import (
4
+ "fmt"
5
+ "github.com/hashicorp/terraform-plugin-sdk/helper/resource"
6
+ "log"
7
+ "regexp"
8
+ "strings"
9
+ "time"
10
+
11
+ "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
12
+ "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
13
+
14
+ "github.com/aws/aws-sdk-go/aws"
15
+ "github.com/aws/aws-sdk-go/service/quicksight"
16
+ )
17
+
18
+ var resourceAwsQuickSighIAMPolicyAttachmentCUPendingStates = []string {
19
+ quicksight .AssignmentStatusDisabled ,
20
+ quicksight .AssignmentStatusDraft ,
21
+ "" ,
22
+ }
23
+
24
+ func resourceAwsQuickSightIAMPolicyAssignment () * schema.Resource {
25
+ return & schema.Resource {
26
+ Create : resourceAwsQuickSightIAMPolicyAssignmentCreate ,
27
+ Read : resourceAwsQuickSightIAMPolicyAssignmentRead ,
28
+ Update : resourceAwsQuickSightIAMPolicyAssignmentUpdate ,
29
+ Delete : resourceAwsQuickSightIAMPolicyAssignmentDelete ,
30
+
31
+ Importer : & schema.ResourceImporter {
32
+ State : schema .ImportStatePassthrough ,
33
+ },
34
+
35
+ Timeouts : & schema.ResourceTimeout {
36
+ Create : schema .DefaultTimeout (60 * time .Second ),
37
+ Read : schema .DefaultTimeout (60 * time .Second ),
38
+ Update : schema .DefaultTimeout (60 * time .Second ),
39
+ Delete : schema .DefaultTimeout (60 * time .Second ),
40
+ },
41
+
42
+ Schema : map [string ]* schema.Schema {
43
+ "assignment_name" : {
44
+ Type : schema .TypeString ,
45
+ Required : true ,
46
+ ValidateFunc : validation .StringMatch (
47
+ regexp .MustCompile ("^[a-zA-Z0-9]*$" ),
48
+ "The value may only contain alphanumeric value. Special chars not allowed" ),
49
+ },
50
+
51
+ "assignment_status" : {
52
+ Type : schema .TypeString ,
53
+ Required : true ,
54
+ },
55
+
56
+ "aws_account_id" : {
57
+ Type : schema .TypeString ,
58
+ Optional : true ,
59
+ Computed : true ,
60
+ ForceNew : true ,
61
+ },
62
+
63
+ "groups" : {
64
+ Type : schema .TypeSet ,
65
+ Elem : & schema.Schema {Type : schema .TypeString },
66
+ Set : schema .HashString ,
67
+ Optional : true ,
68
+ },
69
+
70
+ "users" : {
71
+ Type : schema .TypeSet ,
72
+ Elem : & schema.Schema {Type : schema .TypeString },
73
+ Set : schema .HashString ,
74
+ Optional : true ,
75
+ },
76
+
77
+ "policy_arn" : {
78
+ Type : schema .TypeString ,
79
+ Required : true ,
80
+ },
81
+
82
+ "namespace" : {
83
+ Type : schema .TypeString ,
84
+ Default : "default" ,
85
+ Optional : true ,
86
+ ValidateFunc : validation .StringInSlice ([]string {
87
+ "default" ,
88
+ }, false ),
89
+ },
90
+ },
91
+ }
92
+ }
93
+
94
+ func resourceAwsQuickSightIAMPolicyAssignmentCreate (d * schema.ResourceData , meta interface {}) error {
95
+ conn := meta .(* AWSClient ).quicksightconn
96
+
97
+ awsAccountId := d .Get ("aws_account_id" ).(string )
98
+ namespace := d .Get ("namespace" ).(string )
99
+ assignmentName := d .Get ("assignment_name" ).(string )
100
+
101
+ if v , ok := d .GetOk ("aws_account_id" ); ok {
102
+ awsAccountId = v .(string )
103
+ }
104
+
105
+ identities := make (map [string ][]* string )
106
+ if groupAttr := d .Get ("groups" ).(* schema.Set ); groupAttr .Len () > 0 {
107
+ identities ["Group" ] = expandStringList (groupAttr .List ())
108
+ }
109
+
110
+ if userAttr := d .Get ("users" ).(* schema.Set ); userAttr .Len () > 0 {
111
+ identities ["User" ] = expandStringList (userAttr .List ())
112
+ }
113
+
114
+ createOpts := & quicksight.CreateIAMPolicyAssignmentInput {
115
+ AssignmentName : aws .String (assignmentName ),
116
+ AssignmentStatus : aws .String (d .Get ("assignment_status" ).(string )),
117
+ AwsAccountId : aws .String (awsAccountId ),
118
+ Identities : identities ,
119
+ Namespace : aws .String (namespace ),
120
+ PolicyArn : aws .String (d .Get ("policy_arn" ).(string )),
121
+ }
122
+
123
+ resp , err := conn .CreateIAMPolicyAssignment (createOpts )
124
+ if err != nil {
125
+ return fmt .Errorf ("Error creating QuickSight IAM Policy Assignment: %s" , err )
126
+ }
127
+
128
+ _ , err = waitIAMPolicyAttachmentCreate (conn , awsAccountId , assignmentName , namespace , d .Timeout (schema .TimeoutCreate ))
129
+ if err != nil {
130
+ return fmt .Errorf ("Error waiting for Data Source (%s) to become available: %s" , assignmentName , err )
131
+ }
132
+
133
+ d .SetId (fmt .Sprintf ("%s/%s/%s" , awsAccountId , namespace , aws .StringValue (resp .AssignmentName )))
134
+ return resourceAwsQuickSightIAMPolicyAssignmentRead (d , meta )
135
+ }
136
+
137
+ func waitIAMPolicyAttachmentCreate (conn * quicksight.QuickSight , awsAccountId , assignmentName , namespace string , timeout time.Duration ) (interface {}, error ) {
138
+ stateChangeConf := & resource.StateChangeConf {
139
+ Pending : resourceAwsQuickSighIAMPolicyAttachmentCUPendingStates ,
140
+ Target : []string {quicksight .AssignmentStatusEnabled },
141
+ Refresh : iamPolicyAttachmentStateRefreshFunc (conn , awsAccountId , assignmentName , namespace ),
142
+ Timeout : timeout ,
143
+ Delay : 5 * time .Second ,
144
+ }
145
+ return stateChangeConf .WaitForState ()
146
+ }
147
+
148
+ func iamPolicyAttachmentStateRefreshFunc (conn * quicksight.QuickSight , awsAccountId , assignmentName , namespace string ) resource.StateRefreshFunc {
149
+ return func () (interface {}, string , error ) {
150
+ req := & quicksight.DescribeIAMPolicyAssignmentInput {
151
+ AssignmentName : aws .String (assignmentName ),
152
+ AwsAccountId : aws .String (awsAccountId ),
153
+ Namespace : aws .String (namespace ),
154
+ }
155
+ resp , err := conn .DescribeIAMPolicyAssignment (req )
156
+ if err != nil {
157
+ return nil , "" , err
158
+ }
159
+
160
+ assignmentId := resp .IAMPolicyAssignment .AssignmentId
161
+ state := ""
162
+ if aws .StringValue (resp .IAMPolicyAssignment .AssignmentStatus ) == quicksight .AssignmentStatusEnabled {
163
+ state = quicksight .AssignmentStatusEnabled
164
+ }
165
+ return assignmentId , state , nil
166
+ }
167
+ }
168
+
169
+ func resourceAwsQuickSightIAMPolicyAssignmentRead (d * schema.ResourceData , meta interface {}) error {
170
+ conn := meta .(* AWSClient ).quicksightconn
171
+
172
+ awsAccountID , namespace , assignmentName , err := resourceAwsQuickSightIAMPolicyAssignmentParseID (d .Id ())
173
+ if err != nil {
174
+ return err
175
+ }
176
+
177
+ descOpts := & quicksight.DescribeIAMPolicyAssignmentInput {
178
+ AssignmentName : aws .String (assignmentName ),
179
+ AwsAccountId : aws .String (awsAccountID ),
180
+ Namespace : aws .String (namespace ),
181
+ }
182
+
183
+ resp , err := conn .DescribeIAMPolicyAssignment (descOpts )
184
+ if isAWSErr (err , quicksight .ErrCodeResourceNotFoundException , "" ) {
185
+ log .Printf ("[WARN] QuickSight IAM Policy Assignment %s not found" , d .Id ())
186
+ d .SetId ("" )
187
+ return nil
188
+ }
189
+ if err != nil {
190
+ return fmt .Errorf ("Error describing QuickSight IAM Policy Assignment (%s): %s" , d .Id (), err )
191
+ }
192
+
193
+ d .Set ("aws_account_id" , resp .IAMPolicyAssignment .AwsAccountId )
194
+ d .Set ("namespace" , namespace )
195
+ d .Set ("assignment_id" , resp .IAMPolicyAssignment .AssignmentId )
196
+ d .Set ("assignment_name" , resp .IAMPolicyAssignment .AssignmentName )
197
+ d .Set ("assignment_status" , resp .IAMPolicyAssignment .AssignmentStatus )
198
+ d .Set ("identities" , resp .IAMPolicyAssignment .Identities )
199
+ d .Set ("groups" , resp .IAMPolicyAssignment .Identities ["group" ])
200
+ d .Set ("users" , resp .IAMPolicyAssignment .Identities ["user" ])
201
+ d .Set ("policy_arn" , resp .IAMPolicyAssignment .PolicyArn )
202
+
203
+ return nil
204
+ }
205
+
206
+ func resourceAwsQuickSightIAMPolicyAssignmentUpdate (d * schema.ResourceData , meta interface {}) error {
207
+ conn := meta .(* AWSClient ).quicksightconn
208
+ awsAccountID , namespace , assignmentName , err := resourceAwsQuickSightIAMPolicyAssignmentParseID (d .Id ())
209
+ if err != nil {
210
+ return err
211
+ }
212
+
213
+ identities := make (map [string ][]* string )
214
+ if groupAttr := d .Get ("groups" ).(* schema.Set ); groupAttr .Len () > 0 {
215
+ identities ["Group" ] = expandStringList (groupAttr .List ())
216
+ }
217
+ if userAttr := d .Get ("users" ).(* schema.Set ); userAttr .Len () > 0 {
218
+ identities ["User" ] = expandStringList (userAttr .List ())
219
+ }
220
+
221
+ updateOpts := & quicksight.UpdateIAMPolicyAssignmentInput {
222
+ AssignmentName : aws .String (assignmentName ),
223
+ AssignmentStatus : aws .String (d .Get ("assignment_status" ).(string )),
224
+ AwsAccountId : aws .String (awsAccountID ),
225
+ Identities : identities ,
226
+ Namespace : aws .String (namespace ),
227
+ PolicyArn : aws .String (d .Get ("policy_arn" ).(string )),
228
+ }
229
+
230
+ _ , err = conn .UpdateIAMPolicyAssignment (updateOpts )
231
+ if isAWSErr (err , quicksight .ErrCodeResourceNotFoundException , "" ) {
232
+ log .Printf ("[ERROR] QuickSight IAM Policy Assignment %s not found" , d .Id ())
233
+ d .SetId ("" )
234
+ return nil
235
+ }
236
+ if err != nil {
237
+ return fmt .Errorf ("Error updating QuickSight IAM Policy Assignment %s: %s" , d .Id (), err )
238
+ }
239
+ return resourceAwsQuickSightIAMPolicyAssignmentRead (d , meta )
240
+ }
241
+
242
+ func resourceAwsQuickSightIAMPolicyAssignmentDelete (d * schema.ResourceData , meta interface {}) error {
243
+ conn := meta .(* AWSClient ).quicksightconn
244
+
245
+ awsAccountID , namespace , assignmentName , err := resourceAwsQuickSightIAMPolicyAssignmentParseID (d .Id ())
246
+ if err != nil {
247
+ return err
248
+ }
249
+
250
+ deleteOpts := & quicksight.DeleteIAMPolicyAssignmentInput {
251
+ AssignmentName : aws .String (assignmentName ),
252
+ AwsAccountId : aws .String (awsAccountID ),
253
+ Namespace : aws .String (namespace ),
254
+ }
255
+
256
+ if _ , err := conn .DeleteIAMPolicyAssignment (deleteOpts ); err != nil {
257
+ if isAWSErr (err , quicksight .ErrCodeResourceNotFoundException , "" ) {
258
+ return nil
259
+ }
260
+ return fmt .Errorf ("Error deleting QuickSight IAM Policy Assignment %s: %s" , d .Id (), err )
261
+ }
262
+
263
+ return nil
264
+ }
265
+
266
+ func resourceAwsQuickSightIAMPolicyAssignmentParseID (id string ) (string , string , string , error ) {
267
+ parts := strings .SplitN (id , "/" , 3 )
268
+ if len (parts ) < 3 || parts [0 ] == "" || parts [1 ] == "" || parts [2 ] == "" {
269
+ return "" , "" , "" , fmt .Errorf ("unexpected format of ID (%s), expected AWS_ACCOUNT_ID/NAMESPACE/GROUP_NAME" , id )
270
+ }
271
+ return parts [0 ], parts [1 ], parts [2 ], nil
272
+ }
0 commit comments