Skip to content

Commit ce05082

Browse files
Move bootstrap utility functons to the acctest package (#8244) (#5841)
* Move bootstrap utility functons to the acctest package * Remove unrelated changes. Signed-off-by: Modular Magician <[email protected]>
1 parent 22f7c08 commit ce05082

File tree

70 files changed

+1367
-1195
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1367
-1195
lines changed

.changelog/8244.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:none
2+
3+
```
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
package acctest
4+
5+
import (
6+
"fmt"
7+
"log"
8+
"testing"
9+
10+
"github.com/hashicorp/terraform-provider-google-beta/google-beta/envvar"
11+
"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgiamresource"
12+
cloudresourcemanager "google.golang.org/api/cloudresourcemanager/v1"
13+
)
14+
15+
// BootstrapAllPSARoles ensures that the given project's IAM
16+
// policy grants the given service agents the given roles.
17+
// prefix is usually "service-" and indicates the service agent should have the
18+
// given prefix before the project number.
19+
// This is important to bootstrap because using iam policy resources means that
20+
// deleting them removes permissions for concurrent tests.
21+
// Return whether the bindings changed.
22+
func BootstrapAllPSARoles(t *testing.T, prefix string, agentNames, roles []string) bool {
23+
config := BootstrapConfig(t)
24+
if config == nil {
25+
t.Fatal("Could not bootstrap a config for BootstrapAllPSARoles.")
26+
}
27+
client := config.NewResourceManagerClient(config.UserAgent)
28+
29+
// Get the project since we need its number, id, and policy.
30+
project, err := client.Projects.Get(envvar.GetTestProjectFromEnv()).Do()
31+
if err != nil {
32+
t.Fatalf("Error getting project with id %q: %s", project.ProjectId, err)
33+
}
34+
35+
getPolicyRequest := &cloudresourcemanager.GetIamPolicyRequest{}
36+
policy, err := client.Projects.GetIamPolicy(project.ProjectId, getPolicyRequest).Do()
37+
if err != nil {
38+
t.Fatalf("Error getting project iam policy: %v", err)
39+
}
40+
41+
members := make([]string, len(agentNames))
42+
for i, agentName := range agentNames {
43+
members[i] = fmt.Sprintf("serviceAccount:%s%d@%s.iam.gserviceaccount.com", prefix, project.ProjectNumber, agentName)
44+
}
45+
46+
// Create the bindings we need to add to the policy.
47+
var newBindings []*cloudresourcemanager.Binding
48+
for _, role := range roles {
49+
newBindings = append(newBindings, &cloudresourcemanager.Binding{
50+
Role: role,
51+
Members: members,
52+
})
53+
}
54+
55+
mergedBindings := tpgiamresource.MergeBindings(append(policy.Bindings, newBindings...))
56+
57+
if !tpgiamresource.CompareBindings(policy.Bindings, mergedBindings) {
58+
addedBindings := tpgiamresource.MissingBindings(policy.Bindings, mergedBindings)
59+
for _, missingBinding := range addedBindings {
60+
log.Printf("[DEBUG] Adding binding: %+v", missingBinding)
61+
}
62+
// The policy must change.
63+
policy.Bindings = mergedBindings
64+
setPolicyRequest := &cloudresourcemanager.SetIamPolicyRequest{Policy: policy}
65+
policy, err = client.Projects.SetIamPolicy(project.ProjectId, setPolicyRequest).Do()
66+
if err != nil {
67+
t.Fatalf("Error setting project iam policy: %v", err)
68+
}
69+
msg := "Added the following bindings to the test project's IAM policy:\n"
70+
for _, binding := range addedBindings {
71+
msg += fmt.Sprintf("Members: %q, Role: %q\n", binding.Members, binding.Role)
72+
}
73+
msg += "Retry the test in a few minutes."
74+
t.Error(msg)
75+
return true
76+
}
77+
return false
78+
}
79+
80+
// BootstrapAllPSARole is a version of BootstrapAllPSARoles for granting a
81+
// single role to multiple service agents.
82+
func BootstrapAllPSARole(t *testing.T, prefix string, agentNames []string, role string) bool {
83+
return BootstrapAllPSARoles(t, prefix, agentNames, []string{role})
84+
}
85+
86+
// BootstrapPSARoles is a version of BootstrapAllPSARoles for granting roles to
87+
// a single service agent.
88+
func BootstrapPSARoles(t *testing.T, prefix, agentName string, roles []string) bool {
89+
return BootstrapAllPSARoles(t, prefix, []string{agentName}, roles)
90+
}
91+
92+
// BootstrapPSARole is a simplified version of BootstrapPSARoles for granting a
93+
// single role to a single service agent.
94+
func BootstrapPSARole(t *testing.T, prefix, agentName, role string) bool {
95+
return BootstrapPSARoles(t, prefix, agentName, []string{role})
96+
}
97+
98+
// Returns the bindings that are in the first set of bindings but not the second.
99+
//
100+
// Deprecated: For backward compatibility missingBindings is still working,
101+
// but all new code should use MissingBindings in the tpgiamresource package instead.
102+
func missingBindings(a, b []*cloudresourcemanager.Binding) []*cloudresourcemanager.Binding {
103+
return tpgiamresource.MissingBindings(a, b)
104+
}

0 commit comments

Comments
 (0)