-
Notifications
You must be signed in to change notification settings - Fork 0
fix: customdiff #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -59,35 +59,62 @@ func ResourceStorageBucketAcl() *schema.Resource { | |||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| func resourceStorageRoleEntityCustomizeDiff(_ context.Context, diff *schema.ResourceDiff, meta interface{}) error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| keys := diff.GetChangedKeysPrefix("role_entity") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(keys) < 1 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| count := diff.Get("role_entity.#").(int) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if count < 1 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| oldData, newData := diff.GetChange("role_entity") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| oldList, _ := oldData.([]interface{}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| newList, _ := newData.([]interface{}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(oldList) == 0 || len(newList) == 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| state := map[string]struct{}{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| conf := map[string]struct{}{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| for i := 0; i < count; i++ { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| old, new := diff.GetChange(fmt.Sprintf("role_entity.%d", i)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| state[old.(string)] = struct{}{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| conf[new.(string)] = struct{}{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| newSet := make(map[string]struct{}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, item := range newList { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| newSet[fmt.Sprint(item)] = struct{}{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(state) != len(conf) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| visited := make(map[string]struct{}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| var finalAcls []interface{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Preserve order from oldList and handle removals, this will help avoid permadiff | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Iterate through the original list to maintain its order. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, item := range oldList { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| key := fmt.Sprint(item) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if _, exists := newSet[key]; exists || isDefaultGcpAcl(key) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| visited[key] = struct{}{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| finalAcls = append(finalAcls, item) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| for k := range state { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if _, ok := conf[k]; !ok { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| // project-owners- is explicitly stripped from the roles that this | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| // resource will delete | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if strings.Contains(k, "OWNER:project-owners-") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Append any new additions | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Iterate through the new config to find items that weren't in the old list or newly added | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, item := range newList { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| key := fmt.Sprint(item) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if _, exists := visited[key]; !exists { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| visited[key] = struct{}{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| finalAcls = append(finalAcls, item) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return diff.Clear("role_entity") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| // finaclAcls will be applied if any change in existing config otherwise not diff is displayed | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err := diff.SetNew("role_entity", finalAcls); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("error setting new role entities in CustomizeDiff: %w", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| func isDefaultGcpAcl(key string) bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if strings.HasPrefix(key, "OWNER:project-owners-") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if strings.HasPrefix(key, "OWNER:project-editors-") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if strings.HasPrefix(key, "READER:project-viewers-") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+107
to
111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function can be written more concisely by combining the conditions with a logical OR ( func isDefaultGcpAcl(key string) bool {
return strings.HasPrefix(key, "OWNER:project-owners-") ||
strings.HasPrefix(key, "OWNER:project-editors-") ||
strings.HasPrefix(key, "READER:project-viewers-")
}
Comment on lines
+107
to
111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| type RoleEntity struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -173,6 +200,7 @@ func resourceStorageBucketAclCreate(d *schema.ResourceData, meta interface{}) er | |||||||||||||||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if alreadyInserted { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| log.Printf("[DEBUG]: pair %s-%s already exists, not trying to insert again\n", pair.Role, pair.Entity) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -293,7 +321,6 @@ func resourceStorageBucketAclUpdate(d *schema.ResourceData, meta interface{}) er | |||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| old_re_map[res.Entity] = res.Role | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, v := range new_re { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| pair, err := GetRoleEntityPair(v.(string)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -315,7 +342,6 @@ func resourceStorageBucketAclUpdate(d *schema.ResourceData, meta interface{}) er | |||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("Error updating ACL for bucket %s: %v", bucket, err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| for entity, role := range old_re_map { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if entity == fmt.Sprintf("project-owners-%s", project) && role == "OWNER" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| log.Printf("[WARN]: Skipping %s-%s; not deleting owner ACL.", role, entity) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -388,6 +414,16 @@ func resourceStorageBucketAclDelete(d *schema.ResourceData, meta interface{}) er | |||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if res.Entity == fmt.Sprintf("project-editors-%s", project) && res.Role == "OWNER" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| log.Printf("[WARN]: Skipping %s-%s; not deleting owner ACL.", res.Role, res.Entity) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if res.Entity == fmt.Sprintf("project-viewers-%s", project) && res.Role == "READER" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| log.Printf("[WARN]: Skipping %s-%s; not deleting owner ACL.", res.Role, res.Entity) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+410
to
+418
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The check if (strings.HasPrefix(res.Entity, "project-editors-") && res.Role == "OWNER") ||
(strings.HasPrefix(res.Entity, "project-viewers-") && res.Role == "READER") {
log.Printf("[WARN]: Skipping %s-%s; not deleting default ACL.", res.Role, res.Entity)
continue
}
Comment on lines
+410
to
+418
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The log message "not deleting owner ACL" is misleading when applied to editor and viewer roles. Using a more generic term like "default ACL" would be more accurate and improve clarity when debugging.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| log.Printf("[DEBUG]: removing entity %s", res.Entity) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| err = config.NewStorageClient(userAgent).BucketAccessControls.Delete(bucket, res.Entity).Do() | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type assertions to
[]interface{}foroldDataandnewDatadiscard theokboolean that indicates if the assertion was successful. If the assertion fails,oldListornewListwill benil. The current code handles this by checkinglen() == 0, but it silently treats invalid data as an empty list. It's safer and better practice to explicitly check theokvalue and return an error if the type is not what's expected.