in internal/google/iam.go [29:89]
func SetRequiredOrgIAMRoles(org *Organization, g string, r []string) error {
ctx := context.Background()
c, err := resourcemanager.NewOrganizationsClient(ctx)
if err != nil {
return err
}
defer c.Close()
group := g + "@" + org.Domain
// Retrieve the current IAM policy
getPolicyReq := &iampb.GetIamPolicyRequest{
Resource: fmt.Sprintf("organizations/%s", strconv.Itoa(org.Id)),
}
currentPolicy, err := c.GetIamPolicy(ctx, getPolicyReq)
if err != nil {
return err
}
// Merge the new roles with the existing ones
// TODO: rather than merge, is there a 'member' operation
// that is gracefully additive?
for _, role := range r {
found := false
for _, binding := range currentPolicy.Bindings {
if binding.Role == role {
// If the role already exists, append the new member
binding.Members = append(
binding.Members,
fmt.Sprintf("group:%s", group),
)
found = true
break
}
}
if !found {
// If the role doesn't exist, create a new binding
currentPolicy.Bindings = append(
currentPolicy.Bindings,
&iampb.Binding{
Role: role,
Members: []string{fmt.Sprintf("group:%s", group)},
},
)
}
}
// Set the updated IAM policy
setPolicyReq := &iampb.SetIamPolicyRequest{
Resource: fmt.Sprintf("organizations/%s", strconv.Itoa(org.Id)),
Policy: currentPolicy,
}
_, err = c.SetIamPolicy(ctx, setPolicyReq)
if err != nil {
return err
}
return nil
}