4
4
"encoding/json"
5
5
"fmt"
6
6
"log"
7
+ "reflect"
7
8
"sort"
8
9
9
10
"github.com/hashicorp/errwrap"
@@ -88,8 +89,8 @@ func resourceGoogleProjectIamPolicyRead(d *schema.ResourceData, meta interface{}
88
89
return err
89
90
}
90
91
91
- // we only marshal the bindings, because only the bindings get set in the config
92
- policyBytes , err := json .Marshal (& cloudresourcemanager.Policy {Bindings : policy .Bindings })
92
+ // we only marshal the bindings and audit configs , because only the bindings and audit configs get set in the config
93
+ policyBytes , err := json .Marshal (& cloudresourcemanager.Policy {Bindings : policy .Bindings , AuditConfigs : policy . AuditConfigs })
93
94
if err != nil {
94
95
return fmt .Errorf ("Error marshaling IAM policy: %v" , err )
95
96
}
@@ -157,7 +158,7 @@ func setProjectIamPolicy(policy *cloudresourcemanager.Policy, config *Config, pi
157
158
pbytes , _ := json .Marshal (policy )
158
159
log .Printf ("[DEBUG] Setting policy %#v for project: %s" , string (pbytes ), pid )
159
160
_ , err := config .clientResourceManager .Projects .SetIamPolicy (pid ,
160
- & cloudresourcemanager.SetIamPolicyRequest {Policy : policy }).Do ()
161
+ & cloudresourcemanager.SetIamPolicyRequest {Policy : policy , UpdateMask : "bindings,etag,auditConfigs" }).Do ()
161
162
162
163
if err != nil {
163
164
return errwrap .Wrapf (fmt .Sprintf ("Error applying IAM policy for project %q. Policy is %#v, error is {{err}}" , pid , policy ), err )
@@ -197,34 +198,67 @@ func jsonPolicyDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
197
198
log .Printf ("[ERROR] Could not unmarshal new policy %s: %v" , new , err )
198
199
return false
199
200
}
200
- oldPolicy .Bindings = mergeBindings (oldPolicy .Bindings )
201
- newPolicy .Bindings = mergeBindings (newPolicy .Bindings )
202
201
if newPolicy .Etag != oldPolicy .Etag {
203
202
return false
204
203
}
205
204
if newPolicy .Version != oldPolicy .Version {
206
205
return false
207
206
}
208
- if len ( newPolicy .Bindings ) != len ( oldPolicy .Bindings ) {
207
+ if ! compareBindings ( oldPolicy .Bindings , newPolicy .Bindings ) {
209
208
return false
210
209
}
211
- sort .Sort (sortableBindings (newPolicy .Bindings ))
212
- sort .Sort (sortableBindings (oldPolicy .Bindings ))
213
- for pos , newBinding := range newPolicy .Bindings {
214
- oldBinding := oldPolicy .Bindings [pos ]
215
- if oldBinding .Role != newBinding .Role {
216
- return false
217
- }
218
- if len (oldBinding .Members ) != len (newBinding .Members ) {
210
+ if ! compareAuditConfigs (oldPolicy .AuditConfigs , newPolicy .AuditConfigs ) {
211
+ return false
212
+ }
213
+ return true
214
+ }
215
+
216
+ func derefBindings (b []* cloudresourcemanager.Binding ) []cloudresourcemanager.Binding {
217
+ db := make ([]cloudresourcemanager.Binding , len (b ))
218
+
219
+ for i , v := range b {
220
+ db [i ] = * v
221
+ sort .Strings (db [i ].Members )
222
+ }
223
+ return db
224
+ }
225
+
226
+ func compareBindings (a , b []* cloudresourcemanager.Binding ) bool {
227
+ a = mergeBindings (a )
228
+ b = mergeBindings (b )
229
+ sort .Sort (sortableBindings (a ))
230
+ sort .Sort (sortableBindings (b ))
231
+ return reflect .DeepEqual (derefBindings (a ), derefBindings (b ))
232
+ }
233
+
234
+ func compareAuditConfigs (a , b []* cloudresourcemanager.AuditConfig ) bool {
235
+ a = mergeAuditConfigs (a )
236
+ b = mergeAuditConfigs (b )
237
+ sort .Sort (sortableAuditConfigs (a ))
238
+ sort .Sort (sortableAuditConfigs (b ))
239
+ if len (a ) != len (b ) {
240
+ return false
241
+ }
242
+ for i , v := range a {
243
+ if len (v .AuditLogConfigs ) != len (b [i ].AuditLogConfigs ) {
219
244
return false
220
245
}
221
- sort .Strings (oldBinding .Members )
222
- sort .Strings (newBinding .Members )
223
- for i , newMember := range newBinding .Members {
224
- oldMember := oldBinding .Members [i ]
225
- if newMember != oldMember {
246
+ sort .Sort (sortableAuditLogConfigs (v .AuditLogConfigs ))
247
+ sort .Sort (sortableAuditLogConfigs (b [i ].AuditLogConfigs ))
248
+ for x , logConfig := range v .AuditLogConfigs {
249
+ if b [i ].AuditLogConfigs [x ].LogType != logConfig .LogType {
250
+ return false
251
+ }
252
+ sort .Strings (logConfig .ExemptedMembers )
253
+ sort .Strings (b [i ].AuditLogConfigs [x ].ExemptedMembers )
254
+ if len (logConfig .ExemptedMembers ) != len (b [i ].AuditLogConfigs [x ].ExemptedMembers ) {
226
255
return false
227
256
}
257
+ for pos , mem := range logConfig .ExemptedMembers {
258
+ if b [i ].AuditLogConfigs [x ].ExemptedMembers [pos ] != mem {
259
+ return false
260
+ }
261
+ }
228
262
}
229
263
}
230
264
return true
@@ -242,6 +276,30 @@ func (b sortableBindings) Less(i, j int) bool {
242
276
return b [i ].Role < b [j ].Role
243
277
}
244
278
279
+ type sortableAuditConfigs []* cloudresourcemanager.AuditConfig
280
+
281
+ func (b sortableAuditConfigs ) Len () int {
282
+ return len (b )
283
+ }
284
+ func (b sortableAuditConfigs ) Swap (i , j int ) {
285
+ b [i ], b [j ] = b [j ], b [i ]
286
+ }
287
+ func (b sortableAuditConfigs ) Less (i , j int ) bool {
288
+ return b [i ].Service < b [j ].Service
289
+ }
290
+
291
+ type sortableAuditLogConfigs []* cloudresourcemanager.AuditLogConfig
292
+
293
+ func (b sortableAuditLogConfigs ) Len () int {
294
+ return len (b )
295
+ }
296
+ func (b sortableAuditLogConfigs ) Swap (i , j int ) {
297
+ b [i ], b [j ] = b [j ], b [i ]
298
+ }
299
+ func (b sortableAuditLogConfigs ) Less (i , j int ) bool {
300
+ return b [i ].LogType < b [j ].LogType
301
+ }
302
+
245
303
func getProjectIamPolicyMutexKey (pid string ) string {
246
304
return fmt .Sprintf ("iam-project-%s" , pid )
247
305
}
0 commit comments