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

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 

10 

11 

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 

30 

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])}) 

38 

39 

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

41class ServiceAccount(QueryResourceManager): 

42 

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' 

58 

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'])}) 

66 

67 @staticmethod 

68 def get_metric_resource_name(resource): 

69 return resource["uniqueId"] 

70 

71 

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

73class DeleteServiceAccount(MethodAction): 

74 schema = type_schema('delete') 

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

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

77 

78 def get_resource_params(self, m, r): 

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

80 

81 

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

83class EnableServiceAccount(MethodAction): 

84 schema = type_schema('enable') 

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

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

87 

88 def get_resource_params(self, m, r): 

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

90 

91 

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

93class DisableServiceAccount(MethodAction): 

94 schema = type_schema('disable') 

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

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

97 

98 def get_resource_params(self, m, r): 

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

100 

101 

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',) 

108 

109 

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} 

121 

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 

126 

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) 

150 

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)}) 

160 

161 @staticmethod 

162 def get_metric_resource_name(resource): 

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

164 

165 

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

167class DeleteServiceAccountKey(MethodAction): 

168 

169 schema = type_schema('delete') 

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

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

172 

173 def get_resource_params(self, m, r): 

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

175 

176 

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 

195 

196 @staticmethod 

197 def get(client, resource_info): 

198 return client.execute_command( 

199 'get', { 

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

201 resource_info['name'])}) 

202 

203 

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"