Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/c7n_gcp/resources/iam.py: 90%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

144 statements  

1# Copyright The Cloud Custodian Authors. 

2# SPDX-License-Identifier: Apache-2.0 

3import re 

4 

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 

10from c7n_gcp.filters.timerange import TimeRangeFilter 

11 

12 

13@resources.register('project-role') 

14class ProjectRole(QueryResourceManager): 

15 """GCP Project Role 

16 https://cloud.google.com/iam/docs/reference/rest/v1/organizations.roles#Role 

17 """ 

18 class resource_type(TypeInfo): 

19 service = 'iam' 

20 version = 'v1' 

21 component = 'projects.roles' 

22 enum_spec = ('list', 'roles[]', None) 

23 scope = 'project' 

24 scope_key = 'parent' 

25 scope_template = 'projects/{}' 

26 name = id = "name" 

27 default_report_fields = ['name', 'title', 'description', 'stage', 'deleted'] 

28 asset_type = "iam.googleapis.com/Role" 

29 urn_component = "project-role" 

30 urn_id_segments = (-1,) # Just use the last segment of the id in the URN 

31 

32 @staticmethod 

33 def get(client, resource_info): 

34 return client.execute_query( 

35 'get', verb_arguments={ 

36 'name': 'projects/{}/roles/{}'.format( 

37 resource_info['project_id'], 

38 resource_info['role_name'].rsplit('/', 1)[-1])}) 

39 

40 

41@resources.register('service-account') 

42class ServiceAccount(QueryResourceManager): 

43 

44 class resource_type(TypeInfo): 

45 service = 'iam' 

46 version = 'v1' 

47 component = 'projects.serviceAccounts' 

48 enum_spec = ('list', 'accounts[]', []) 

49 scope = 'project' 

50 scope_key = 'name' 

51 scope_template = 'projects/{}' 

52 id = "name" 

53 name = 'email' 

54 default_report_fields = ['name', 'displayName', 'email', 'description', 'disabled'] 

55 asset_type = "iam.googleapis.com/ServiceAccount" 

56 metric_key = 'resource.labels.unique_id' 

57 urn_component = 'service-account' 

58 urn_id_path = 'email' 

59 

60 @staticmethod 

61 def get(client, resource_info): 

62 return client.execute_query( 

63 'get', verb_arguments={ 

64 'name': 'projects/{}/serviceAccounts/{}'.format( 

65 resource_info['project_id'], 

66 resource_info['email_id'])}) 

67 

68 @staticmethod 

69 def get_metric_resource_name(resource): 

70 return resource["uniqueId"] 

71 

72 

73@ServiceAccount.action_registry.register('delete') 

74class DeleteServiceAccount(MethodAction): 

75 schema = type_schema('delete') 

76 method_spec = {'op': 'delete'} 

77 permissions = ("iam.serviceAccounts.delete",) 

78 

79 def get_resource_params(self, m, r): 

80 return {'name': r['name']} 

81 

82 

83@ServiceAccount.action_registry.register('enable') 

84class EnableServiceAccount(MethodAction): 

85 schema = type_schema('enable') 

86 method_spec = {'op': 'enable'} 

87 permissions = ("iam.serviceAccounts.enable",) 

88 

89 def get_resource_params(self, m, r): 

90 return {'name': r['name']} 

91 

92 

93@ServiceAccount.action_registry.register('disable') 

94class DisableServiceAccount(MethodAction): 

95 schema = type_schema('disable') 

96 method_spec = {'op': 'disable'} 

97 permissions = ("iam.serviceAccounts.disable",) 

98 

99 def get_resource_params(self, m, r): 

100 return {'name': r['name']} 

101 

102 

103@ServiceAccount.filter_registry.register('iam-policy') 

104class ServiceAccountIamPolicyFilter(IamPolicyFilter): 

105 """ 

106 Overrides the base implementation to process service account resources correctly. 

107 """ 

108 permissions = ('resourcemanager.projects.getIamPolicy',) 

109 

110 

111@resources.register('service-account-key') 

112class ServiceAccountKey(ChildResourceManager): 

113 """GCP Resource 

114 https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys 

115 """ 

116 def _get_parent_resource_info(self, child_instance): 

117 project_id, sa = re.match( 

118 'projects/(.*?)/serviceAccounts/(.*?)/keys/.*', 

119 child_instance['name']).groups() 

120 return {'project_id': project_id, 

121 'email_id': sa} 

122 

123 def get_resource_query(self): 

124 """Does nothing as self does not need query values unlike its parent 

125 which receives them with the use_child_query flag.""" 

126 pass 

127 

128 class resource_type(ChildTypeInfo): 

129 service = 'iam' 

130 version = 'v1' 

131 component = 'projects.serviceAccounts.keys' 

132 enum_spec = ('list', 'keys[]', []) 

133 scope = None 

134 scope_key = 'name' 

135 name = id = 'name' 

136 default_report_fields = ['name', 'privateKeyType', 'keyAlgorithm', 

137 'validAfterTime', 'validBeforeTime', 'keyOrigin', 'keyType'] 

138 parent_spec = { 

139 'resource': 'service-account', 

140 'child_enum_params': [ 

141 ('name', 'name') 

142 ], 

143 'use_child_query': True 

144 } 

145 asset_type = "iam.googleapis.com/ServiceAccountKey" 

146 scc_type = "google.iam.ServiceAccountKey" 

147 permissions = ("iam.serviceAccounts.list",) 

148 metric_key = 'metric.labels.key_id' 

149 urn_component = "service-account-key" 

150 urn_id_segments = (3, 5) 

151 

152 @staticmethod 

153 def get(client, resource_info): 

154 project, sa, key = re.match( 

155 '.*?/projects/(.*?)/serviceAccounts/(.*?)/keys/(.*)', 

156 resource_info['resourceName']).groups() 

157 return client.execute_query( 

158 'get', { 

159 'name': 'projects/{}/serviceAccounts/{}/keys/{}'.format( 

160 project, sa, key)}) 

161 

162 @staticmethod 

163 def get_metric_resource_name(resource): 

164 return resource["name"].split('/')[-1] 

165 

166 

167@ServiceAccountKey.action_registry.register('delete') 

168class DeleteServiceAccountKey(MethodAction): 

169 

170 schema = type_schema('delete') 

171 method_spec = {'op': 'delete'} 

172 permissions = ("iam.serviceAccountKeys.delete",) 

173 

174 def get_resource_params(self, m, r): 

175 return {'name': r['name']} 

176 

177 

178@resources.register('iam-role') 

179class Role(QueryResourceManager): 

180 """GCP Organization Role 

181 https://cloud.google.com/iam/docs/reference/rest/v1/organizations.roles#Role 

182 """ 

183 class resource_type(TypeInfo): 

184 service = 'iam' 

185 version = 'v1' 

186 component = 'roles' 

187 enum_spec = ('list', 'roles[]', None) 

188 scope = "global" 

189 name = id = "name" 

190 default_report_fields = ['name', 'title', 'description', 'stage', 'deleted'] 

191 asset_type = "iam.googleapis.com/Role" 

192 urn_component = "role" 

193 # Don't show the project ID in the URN. 

194 urn_has_project = False 

195 urn_id_segments = (-1,) # Just use the last segment of the id in the URN 

196 

197 @staticmethod 

198 def get(client, resource_info): 

199 return client.execute_command( 

200 'get', { 

201 'name': 'roles/{}'.format( 

202 resource_info['name'])}) 

203 

204 

205@resources.register('api-key') 

206class ApiKey(QueryResourceManager): 

207 """GCP API Key 

208 https://cloud.google.com/api-keys/docs/reference/rest/v2/projects.locations.keys#Key 

209 """ 

210 class resource_type(TypeInfo): 

211 service = 'apikeys' 

212 version = 'v2' 

213 component = 'projects.locations.keys' 

214 enum_spec = ('list', 'keys[]', None) 

215 scope = 'project' 

216 scope_key = 'parent' 

217 scope_template = 'projects/{}/locations/global' 

218 name = id = "name" 

219 default_report_fields = ['name', 'displayName', 'createTime', 'updateTime'] 

220 asset_type = "apikeys.googleapis.com/projects.locations.keys" 

221 

222 

223@ApiKey.filter_registry.register('time-range') 

224class ApiKeyTimeRangeFilter(TimeRangeFilter): 

225 """Filters api keys that have been changed during a specific time range. 

226 

227 .. code-block:: yaml 

228 

229 policies: 

230 - name: api_keys_not_rotated_more_than_90_days 

231 resource: gcp.api-key 

232 filters: 

233 - not: 

234 - type: time-range 

235 value: 90 

236 """ 

237 create_time_field_name = 'createTime' 

238 expire_time_field_name = 'updateTime' 

239 permissions = ('apikeys.keys.list', )