Skip to content

Commit

Permalink
Merge pull request #8092 from evandbrown/google-iam-resource
Browse files Browse the repository at this point in the history
providers/google: Support IAM permissions for GCP projects
  • Loading branch information
evandbrown authored Sep 7, 2016
2 parents f257895 + 262661a commit 926acfd
Show file tree
Hide file tree
Showing 12 changed files with 6,259 additions and 6 deletions.
21 changes: 15 additions & 6 deletions builtin/providers/google/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"golang.org/x/oauth2/jwt"
"google.golang.org/api/cloudresourcemanager/v1"
"google.golang.org/api/compute/v1"
"google.golang.org/api/container/v1"
"google.golang.org/api/dns/v1"
Expand All @@ -28,12 +29,13 @@ type Config struct {
Project string
Region string

clientCompute *compute.Service
clientContainer *container.Service
clientDns *dns.Service
clientStorage *storage.Service
clientSqlAdmin *sqladmin.Service
clientPubsub *pubsub.Service
clientCompute *compute.Service
clientContainer *container.Service
clientDns *dns.Service
clientPubsub *pubsub.Service
clientResourceManager *cloudresourcemanager.Service
clientStorage *storage.Service
clientSqlAdmin *sqladmin.Service
}

func (c *Config) loadAndValidate() error {
Expand Down Expand Up @@ -133,6 +135,13 @@ func (c *Config) loadAndValidate() error {
}
c.clientPubsub.UserAgent = userAgent

log.Printf("[INFO] Instatiating Google CloudResourceManager Client...")
c.clientResourceManager, err = cloudresourcemanager.New(client)
if err != nil {
return err
}
c.clientPubsub.UserAgent = userAgent

return nil
}

Expand Down
103 changes: 103 additions & 0 deletions builtin/providers/google/data_source_google_iam_policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package google

import (
"encoding/json"
"strconv"

"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/cloudresourcemanager/v1"
)

var iamBinding *schema.Schema = &schema.Schema{
Type: schema.TypeSet,
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"role": {
Type: schema.TypeString,
Required: true,
},
"members": {
Type: schema.TypeSet,
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
},
},
}

// dataSourceGoogleIamPolicy returns a *schema.Resource that allows a customer
// to express a Google Cloud IAM policy in a data resource. This is an example
// of how the schema would be used in a config:
//
// data "google_iam_policy" "admin" {
// binding {
// role = "roles/storage.objectViewer"
// members = [
// "user:evanbrown@google.com",
// ]
// }
// }
func dataSourceGoogleIamPolicy() *schema.Resource {
return &schema.Resource{
Read: dataSourceGoogleIamPolicyRead,
Schema: map[string]*schema.Schema{
"binding": iamBinding,
"policy_data": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

// dataSourceGoogleIamPolicyRead reads a data source from config and writes it
// to state.
func dataSourceGoogleIamPolicyRead(d *schema.ResourceData, meta interface{}) error {
var policy cloudresourcemanager.Policy
var bindings []*cloudresourcemanager.Binding

// The schema supports multiple binding{} blocks
bset := d.Get("binding").(*schema.Set)

// All binding{} blocks will be converted and stored in an array
bindings = make([]*cloudresourcemanager.Binding, bset.Len())
policy.Bindings = bindings

// Convert each config binding into a cloudresourcemanager.Binding
for i, v := range bset.List() {
binding := v.(map[string]interface{})
policy.Bindings[i] = &cloudresourcemanager.Binding{
Role: binding["role"].(string),
Members: dataSourceGoogleIamPolicyMembers(binding["members"].(*schema.Set)),
}
}

// Marshal cloudresourcemanager.Policy to JSON suitable for storing in state
pjson, err := json.Marshal(&policy)
if err != nil {
// should never happen if the above code is correct
return err
}
pstring := string(pjson)

d.Set("policy_data", pstring)
d.SetId(strconv.Itoa(hashcode.String(pstring)))

return nil
}

// dataSourceGoogleIamPolicyMembers converts a set of members in a binding
// (a member is a principal, usually an e-mail address) into an array of
// string.
func dataSourceGoogleIamPolicyMembers(d *schema.Set) []string {
var members []string
members = make([]string, d.Len())

for i, v := range d.List() {
members[i] = v.(string)
}
return members
}
5 changes: 5 additions & 0 deletions builtin/providers/google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ func Provider() terraform.ResourceProvider {
},
},

DataSourcesMap: map[string]*schema.Resource{
"google_iam_policy": dataSourceGoogleIamPolicy(),
},

ResourcesMap: map[string]*schema.Resource{
"google_compute_autoscaler": resourceComputeAutoscaler(),
"google_compute_address": resourceComputeAddress(),
Expand Down Expand Up @@ -89,6 +93,7 @@ func Provider() terraform.ResourceProvider {
"google_sql_database": resourceSqlDatabase(),
"google_sql_database_instance": resourceSqlDatabaseInstance(),
"google_sql_user": resourceSqlUser(),
"google_project": resourceGoogleProject(),
"google_pubsub_topic": resourcePubsubTopic(),
"google_pubsub_subscription": resourcePubsubSubscription(),
"google_storage_bucket": resourceStorageBucket(),
Expand Down
Loading

0 comments on commit 926acfd

Please sign in to comment.