func SetRequiredOrgIAMRoles()

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
}