constellation/cli/gcp/client/project.go
Leonard Cohnen 2d8fcd9bf4 monorepo
Co-authored-by: Malte Poll <mp@edgeless.systems>
Co-authored-by: katexochen <katexochen@users.noreply.github.com>
Co-authored-by: Daniel Weiße <dw@edgeless.systems>
Co-authored-by: Thomas Tendyck <tt@edgeless.systems>
Co-authored-by: Benedict Schlueter <bs@edgeless.systems>
Co-authored-by: leongross <leon.gross@rub.de>
Co-authored-by: Moritz Eckert <m1gh7ym0@gmail.com>
2022-03-22 16:09:39 +01:00

72 lines
1.9 KiB
Go

package client
import (
"context"
"fmt"
iampb "google.golang.org/genproto/googleapis/iam/v1"
)
// addIAMPolicyBindings adds a GCP service account to roles specified in the input.
func (c *Client) addIAMPolicyBindings(ctx context.Context, input AddIAMPolicyBindingInput) error {
getReq := &iampb.GetIamPolicyRequest{
Resource: "projects/" + c.project,
}
policy, err := c.projectsAPI.GetIamPolicy(ctx, getReq)
if err != nil {
return fmt.Errorf("retrieving current iam policy failed: %w", err)
}
for _, binding := range input.Bindings {
addIAMPolicy(policy, binding)
}
setReq := &iampb.SetIamPolicyRequest{
Resource: "projects/" + c.project,
Policy: policy,
}
if _, err := c.projectsAPI.SetIamPolicy(ctx, setReq); err != nil {
return fmt.Errorf("setting new iam policy failed: %w", err)
}
return nil
}
// PolicyBinding is a GCP IAM policy binding.
type PolicyBinding struct {
ServiceAccount string
Role string
}
// addIAMPolicy inserts policy binding for service account and role to an existing iam policy.
func addIAMPolicy(policy *iampb.Policy, policyBinding PolicyBinding) {
var binding *iampb.Binding
for _, existingBinding := range policy.Bindings {
if existingBinding.Role == policyBinding.Role && existingBinding.Condition == nil {
binding = existingBinding
break
}
}
if binding == nil {
binding = &iampb.Binding{
Role: policyBinding.Role,
}
policy.Bindings = append(policy.Bindings, binding)
}
// add service account to role, if not already a member
member := "serviceAccount:" + policyBinding.ServiceAccount
var alreadyMember bool
for _, existingMember := range binding.Members {
if member == existingMember {
alreadyMember = true
break
}
}
if !alreadyMember {
binding.Members = append(binding.Members, member)
}
}
// AddIAMPolicyBindingInput is the input for an AddIAMPolicyBinding operation.
type AddIAMPolicyBindingInput struct {
Bindings []PolicyBinding
}