github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/gcp/iam.go (about) 1 // Copyright 2018 The Terraformer Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package gcp 16 17 import ( 18 "context" 19 "log" 20 "regexp" 21 22 admin "cloud.google.com/go/iam/admin/apiv1" 23 "google.golang.org/api/cloudresourcemanager/v1" 24 "google.golang.org/api/iterator" 25 adminpb "google.golang.org/genproto/googleapis/iam/admin/v1" 26 27 "github.com/GoogleCloudPlatform/terraformer/terraformutils" 28 ) 29 30 var IamAllowEmptyValues = []string{"tags."} 31 32 var IamAdditionalFields = map[string]interface{}{} 33 34 type IamGenerator struct { 35 GCPService 36 } 37 38 func (g IamGenerator) createServiceAccountResources(serviceAccountsIterator *admin.ServiceAccountIterator) []terraformutils.Resource { 39 resources := []terraformutils.Resource{} 40 re := regexp.MustCompile(`^[a-z]`) 41 for { 42 serviceAccount, err := serviceAccountsIterator.Next() 43 if err == iterator.Done { 44 break 45 } 46 if err != nil { 47 log.Println("error with service account:", err) 48 continue 49 } 50 if !re.MatchString(serviceAccount.Email) { 51 log.Printf("skipping %s: service account email must start with [a-z]\n", serviceAccount.Name) 52 continue 53 } 54 resources = append(resources, terraformutils.NewSimpleResource( 55 serviceAccount.Name, 56 serviceAccount.UniqueId, 57 "google_service_account", 58 g.ProviderName, 59 IamAllowEmptyValues, 60 )) 61 } 62 return resources 63 } 64 65 func (g *IamGenerator) createIamCustomRoleResources(rolesResponse *adminpb.ListRolesResponse, project string) []terraformutils.Resource { 66 resources := []terraformutils.Resource{} 67 for _, role := range rolesResponse.Roles { 68 if role.Deleted { 69 // Note: no need to log that the resource has been deleted 70 continue 71 } 72 resources = append(resources, terraformutils.NewResource( 73 role.Name, 74 role.Name, 75 "google_project_iam_custom_role", 76 g.ProviderName, 77 map[string]string{ 78 "role_id": role.Name, 79 "project": project, 80 }, 81 IamAllowEmptyValues, 82 map[string]interface{}{ 83 "stage": role.Stage.String(), 84 }, 85 )) 86 } 87 88 return resources 89 } 90 91 func (g *IamGenerator) createIamMemberResources(policy *cloudresourcemanager.Policy, project string) []terraformutils.Resource { 92 resources := []terraformutils.Resource{} 93 for _, b := range policy.Bindings { 94 for _, m := range b.Members { 95 resources = append(resources, terraformutils.NewResource( 96 b.Role+m, 97 b.Role+m, 98 "google_project_iam_member", 99 g.ProviderName, 100 map[string]string{ 101 "role": b.Role, 102 "project": project, 103 "member": m, 104 }, 105 IamAllowEmptyValues, 106 IamAdditionalFields, 107 )) 108 } 109 } 110 111 return resources 112 } 113 114 func (g *IamGenerator) InitResources() error { 115 ctx := context.Background() 116 117 projectID := g.GetArgs()["project"].(string) 118 client, err := admin.NewIamClient(ctx) 119 if err != nil { 120 return err 121 } 122 serviceAccountsIterator := client.ListServiceAccounts(ctx, &adminpb.ListServiceAccountsRequest{Name: "projects/" + projectID}) 123 rolesResponse, err := client.ListRoles(ctx, &adminpb.ListRolesRequest{Parent: "projects/" + projectID}) 124 if err != nil { 125 return err 126 } 127 128 cm, err := cloudresourcemanager.NewService(context.Background()) 129 if err != nil { 130 return err 131 } 132 rb := &cloudresourcemanager.GetIamPolicyRequest{} 133 policyResponse, err := cm.Projects.GetIamPolicy(projectID, rb).Context(context.Background()).Do() 134 if err != nil { 135 return err 136 } 137 138 g.Resources = g.createServiceAccountResources(serviceAccountsIterator) 139 g.Resources = append(g.Resources, g.createIamCustomRoleResources(rolesResponse, projectID)...) 140 g.Resources = append(g.Resources, g.createIamMemberResources(policyResponse, projectID)...) 141 return nil 142 }