Skip to content

Commit

Permalink
Add validation for IAM members.
Browse files Browse the repository at this point in the history
  • Loading branch information
trodge committed Nov 30, 2022
1 parent 2a41da6 commit 222ef12
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
4 changes: 1 addition & 3 deletions mmv1/third_party/terraform/resources/resource_iam_binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ import (
"errors"
"fmt"
"log"
"regexp"
"strings"

"github.com/davecgh/go-spew/spew"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"google.golang.org/api/cloudresourcemanager/v1"
)

Expand All @@ -25,7 +23,7 @@ var iamBindingSchema = map[string]*schema.Schema{
Elem: &schema.Schema{
Type: schema.TypeString,
DiffSuppressFunc: caseDiffSuppress,
ValidateFunc: validation.StringDoesNotMatch(regexp.MustCompile("^deleted:"), "Terraform does not support IAM bindings for deleted principals"),
ValidateFunc: validateIAMMember,
},
Set: func(v interface{}) int {
return schema.HashString(strings.ToLower(v.(string)))
Expand Down
23 changes: 21 additions & 2 deletions mmv1/third_party/terraform/resources/resource_iam_member.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/davecgh/go-spew/spew"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"google.golang.org/api/cloudresourcemanager/v1"
)

Expand All @@ -21,6 +20,26 @@ func iamMemberCaseDiffSuppress(k, old, new string, d *schema.ResourceData) bool
return caseDiffSuppress(k, old, new, d)
}

func validateIAMMember(i interface{}, k string) ([]string, []error) {
v, ok := i.(string)
if !ok {
return nil, []error{fmt.Errorf("expected type of %s to be string", k)}
}

if matched, err := regexp.MatchString("^deleted", v); err != nil {
return nil, []error{fmt.Errorf("error validating %s: %v", k, err)}
} else if matched {
return nil, []error{fmt.Errorf("invalid value for %s (Terraform does not support IAM members for deleted principals)", k)}
}

if matched, err := regexp.MatchString("(.+:.+|allUsers|allAuthenticatedUsers)", v); err != nil {
return nil, []error{fmt.Errorf("error validating %s: %v", k, err)}
} else if !matched {
return nil, []error{fmt.Errorf("invalid value for %s (IAM members must have one of the values outlined here: https://cloud.google.com/billing/docs/reference/rest/v1/Policy#Binding)", k)}
}
return nil, nil
}

var IamMemberBaseSchema = map[string]*schema.Schema{
"role": {
Type: schema.TypeString,
Expand All @@ -32,7 +51,7 @@ var IamMemberBaseSchema = map[string]*schema.Schema{
Required: true,
ForceNew: true,
DiffSuppressFunc: iamMemberCaseDiffSuppress,
ValidateFunc: validation.StringDoesNotMatch(regexp.MustCompile("^deleted:"), "Terraform does not support IAM members for deleted principals"),
ValidateFunc: validateIAMMember,
},
"condition": {
Type: schema.TypeList,
Expand Down
10 changes: 8 additions & 2 deletions mmv1/third_party/terraform/resources/resource_iam_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,15 @@ func unmarshalIamPolicy(policyData string) (*cloudresourcemanager.Policy, error)
}

func validateIamPolicy(i interface{}, k string) (s []string, es []error) {
_, err := unmarshalIamPolicy(i.(string))
if err != nil {
if policy, err := unmarshalIamPolicy(i.(string)); err != nil {
es = append(es, err)
} else {
for i, binding := range policy.Bindings {
for j, member := range binding.Members {
_, memberErrors := validateIAMMember(member, fmt.Sprintf("bindings.%d.members.%d", i, j))
es = append(es, memberErrors...)
}
}
}
return
}

0 comments on commit 222ef12

Please sign in to comment.