Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/c7n_gcp/resources/iam.py: 90%
138 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
1# Copyright The Cloud Custodian Authors.
2# SPDX-License-Identifier: Apache-2.0
3import re
5from c7n.utils import type_schema
6from c7n_gcp.filters.iampolicy import IamPolicyFilter
7from c7n_gcp.provider import resources
8from c7n_gcp.query import QueryResourceManager, TypeInfo, ChildResourceManager, ChildTypeInfo
9from c7n_gcp.actions import MethodAction
12@resources.register('project-role')
13class ProjectRole(QueryResourceManager):
14 """GCP Project Role
15 https://cloud.google.com/iam/docs/reference/rest/v1/organizations.roles#Role
16 """
17 class resource_type(TypeInfo):
18 service = 'iam'
19 version = 'v1'
20 component = 'projects.roles'
21 enum_spec = ('list', 'roles[]', None)
22 scope = 'project'
23 scope_key = 'parent'
24 scope_template = 'projects/{}'
25 name = id = "name"
26 default_report_fields = ['name', 'title', 'description', 'stage', 'deleted']
27 asset_type = "iam.googleapis.com/Role"
28 urn_component = "project-role"
29 urn_id_segments = (-1,) # Just use the last segment of the id in the URN
31 @staticmethod
32 def get(client, resource_info):
33 return client.execute_query(
34 'get', verb_arguments={
35 'name': 'projects/{}/roles/{}'.format(
36 resource_info['project_id'],
37 resource_info['role_name'].rsplit('/', 1)[-1])})
40@resources.register('service-account')
41class ServiceAccount(QueryResourceManager):
43 class resource_type(TypeInfo):
44 service = 'iam'
45 version = 'v1'
46 component = 'projects.serviceAccounts'
47 enum_spec = ('list', 'accounts[]', [])
48 scope = 'project'
49 scope_key = 'name'
50 scope_template = 'projects/{}'
51 id = "name"
52 name = 'email'
53 default_report_fields = ['name', 'displayName', 'email', 'description', 'disabled']
54 asset_type = "iam.googleapis.com/ServiceAccount"
55 metric_key = 'resource.labels.unique_id'
56 urn_component = 'service-account'
57 urn_id_path = 'email'
59 @staticmethod
60 def get(client, resource_info):
61 return client.execute_query(
62 'get', verb_arguments={
63 'name': 'projects/{}/serviceAccounts/{}'.format(
64 resource_info['project_id'],
65 resource_info['email_id'])})
67 @staticmethod
68 def get_metric_resource_name(resource):
69 return resource["uniqueId"]
72@ServiceAccount.action_registry.register('delete')
73class DeleteServiceAccount(MethodAction):
74 schema = type_schema('delete')
75 method_spec = {'op': 'delete'}
76 permissions = ("iam.serviceAccounts.delete",)
78 def get_resource_params(self, m, r):
79 return {'name': r['name']}
82@ServiceAccount.action_registry.register('enable')
83class EnableServiceAccount(MethodAction):
84 schema = type_schema('enable')
85 method_spec = {'op': 'enable'}
86 permissions = ("iam.serviceAccounts.enable",)
88 def get_resource_params(self, m, r):
89 return {'name': r['name']}
92@ServiceAccount.action_registry.register('disable')
93class DisableServiceAccount(MethodAction):
94 schema = type_schema('disable')
95 method_spec = {'op': 'disable'}
96 permissions = ("iam.serviceAccounts.disable",)
98 def get_resource_params(self, m, r):
99 return {'name': r['name']}
102@ServiceAccount.filter_registry.register('iam-policy')
103class ServiceAccountIamPolicyFilter(IamPolicyFilter):
104 """
105 Overrides the base implementation to process service account resources correctly.
106 """
107 permissions = ('resourcemanager.projects.getIamPolicy',)
110@resources.register('service-account-key')
111class ServiceAccountKey(ChildResourceManager):
112 """GCP Resource
113 https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys
114 """
115 def _get_parent_resource_info(self, child_instance):
116 project_id, sa = re.match(
117 'projects/(.*?)/serviceAccounts/(.*?)/keys/.*',
118 child_instance['name']).groups()
119 return {'project_id': project_id,
120 'email_id': sa}
122 def get_resource_query(self):
123 """Does nothing as self does not need query values unlike its parent
124 which receives them with the use_child_query flag."""
125 pass
127 class resource_type(ChildTypeInfo):
128 service = 'iam'
129 version = 'v1'
130 component = 'projects.serviceAccounts.keys'
131 enum_spec = ('list', 'keys[]', [])
132 scope = None
133 scope_key = 'name'
134 name = id = 'name'
135 default_report_fields = ['name', 'privateKeyType', 'keyAlgorithm',
136 'validAfterTime', 'validBeforeTime', 'keyOrigin', 'keyType']
137 parent_spec = {
138 'resource': 'service-account',
139 'child_enum_params': [
140 ('name', 'name')
141 ],
142 'use_child_query': True
143 }
144 asset_type = "iam.googleapis.com/ServiceAccountKey"
145 scc_type = "google.iam.ServiceAccountKey"
146 permissions = ("iam.serviceAccounts.list",)
147 metric_key = 'metric.labels.key_id'
148 urn_component = "service-account-key"
149 urn_id_segments = (3, 5)
151 @staticmethod
152 def get(client, resource_info):
153 project, sa, key = re.match(
154 '.*?/projects/(.*?)/serviceAccounts/(.*?)/keys/(.*)',
155 resource_info['resourceName']).groups()
156 return client.execute_query(
157 'get', {
158 'name': 'projects/{}/serviceAccounts/{}/keys/{}'.format(
159 project, sa, key)})
161 @staticmethod
162 def get_metric_resource_name(resource):
163 return resource["name"].split('/')[-1]
166@ServiceAccountKey.action_registry.register('delete')
167class DeleteServiceAccountKey(MethodAction):
169 schema = type_schema('delete')
170 method_spec = {'op': 'delete'}
171 permissions = ("iam.serviceAccountKeys.delete",)
173 def get_resource_params(self, m, r):
174 return {'name': r['name']}
177@resources.register('iam-role')
178class Role(QueryResourceManager):
179 """GCP Organization Role
180 https://cloud.google.com/iam/docs/reference/rest/v1/organizations.roles#Role
181 """
182 class resource_type(TypeInfo):
183 service = 'iam'
184 version = 'v1'
185 component = 'roles'
186 enum_spec = ('list', 'roles[]', None)
187 scope = "global"
188 name = id = "name"
189 default_report_fields = ['name', 'title', 'description', 'stage', 'deleted']
190 asset_type = "iam.googleapis.com/Role"
191 urn_component = "role"
192 # Don't show the project ID in the URN.
193 urn_has_project = False
194 urn_id_segments = (-1,) # Just use the last segment of the id in the URN
196 @staticmethod
197 def get(client, resource_info):
198 return client.execute_command(
199 'get', {
200 'name': 'roles/{}'.format(
201 resource_info['name'])})
204@resources.register('api-key')
205class ApiKey(QueryResourceManager):
206 """GCP API Key
207 https://cloud.google.com/api-keys/docs/reference/rest/v2/projects.locations.keys#Key
208 """
209 class resource_type(TypeInfo):
210 service = 'apikeys'
211 version = 'v2'
212 component = 'projects.locations.keys'
213 enum_spec = ('list', 'keys[]', None)
214 scope = 'project'
215 scope_key = 'parent'
216 scope_template = 'projects/{}/locations/global'
217 name = id = "name"
218 default_report_fields = ['name', 'displayName', 'createTime', 'updateTime']
219 asset_type = "apikeys.googleapis.com/projects.locations.keys"