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

173 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_gcp.actions import MethodAction 

6from c7n_gcp.query import QueryResourceManager, TypeInfo 

7 

8from c7n_gcp.provider import resources 

9from c7n.filters.core import ListItemFilter 

10from c7n.utils import type_schema, local_session 

11from c7n_gcp.utils import get_firewall_port_ranges 

12 

13 

14@resources.register('vpc') 

15class Network(QueryResourceManager): 

16 """GCP resource: https://cloud.google.com/compute/docs/reference/rest/v1/networks 

17 """ 

18 class resource_type(TypeInfo): 

19 service = 'compute' 

20 version = 'v1' 

21 component = 'networks' 

22 scope_template = "{}" 

23 name = id = "name" 

24 default_report_fields = [ 

25 "name", "description", "creationTimestamp", 

26 "autoCreateSubnetworks", "IPv4Range", "gatewayIPv4"] 

27 asset_type = "compute.googleapis.com/Network" 

28 scc_type = "google.compute.Network" 

29 urn_component = "vpc" 

30 

31 @staticmethod 

32 def get(client, resource_info): 

33 path_param_re = re.compile('.*?/projects/(.*?)/global/networks/(.*)') 

34 project, network = path_param_re.match( 

35 resource_info["resourceName"]).groups() 

36 return client.execute_query( 

37 'get', {'project': project, 'network': network}) 

38 

39 

40@Network.filter_registry.register('firewall') 

41class VPCFirewallFilter(ListItemFilter): 

42 schema = type_schema( 

43 'firewall', 

44 attrs={'$ref': '#/definitions/filters_common/list_item_attrs'} 

45 ) 

46 annotate_items = True 

47 permissions = ("vpcaccess.locations.list",) 

48 

49 def get_item_values(self, resource): 

50 session = local_session(self.manager.session_factory) 

51 client = session.client(service_name='compute', version='v1', 

52 component='networks') 

53 project = session.get_default_project() 

54 firewalls = client.execute_query('getEffectiveFirewalls', { 

55 'project': project, 'network': resource['name']}).get('firewalls') 

56 return firewalls 

57 

58 

59@resources.register('subnet') 

60class Subnet(QueryResourceManager): 

61 """GCP resource: https://cloud.google.com/compute/docs/reference/rest/v1/subnetworks 

62 """ 

63 class resource_type(TypeInfo): 

64 service = 'compute' 

65 version = 'v1' 

66 component = 'subnetworks' 

67 enum_spec = ('aggregatedList', 'items.*.subnetworks[]', None) 

68 name = id = "name" 

69 default_report_fields = [ 

70 "name", "description", "creationTimestamp", "ipCidrRange", 

71 "gatewayAddress", "region", "state"] 

72 asset_type = "compute.googleapis.com/Subnetwork" 

73 scc_type = "google.compute.Subnetwork" 

74 metric_key = "resource.labels.subnetwork_name" 

75 urn_component = "subnet" 

76 

77 @staticmethod 

78 def get(client, resource_info): 

79 

80 path_param_re = re.compile( 

81 '.*?projects/(.*?)/regions/(.*?)/subnetworks/(.*)') 

82 project, region, subnet = path_param_re.match( 

83 resource_info["resourceName"]).groups() 

84 return client.execute_query( 

85 'get', {'project': project, 'region': region, 'subnetwork': subnet}) 

86 

87 

88class SubnetAction(MethodAction): 

89 

90 path_param_re = re.compile( 

91 '.*?/projects/(.*?)/regions/(.*?)/subnetworks/(.*)') 

92 

93 def get_resource_params(self, model, resource): 

94 project, region, subnet = self.path_param_re.match( 

95 resource['selfLink']).groups() 

96 return {'project': project, 'region': region, 'subnetwork': subnet} 

97 

98 

99@Subnet.action_registry.register('set-flow-log') 

100class SetFlowLog(SubnetAction): 

101 """Enable vpc flow logs on a subnet. 

102 

103 :example: Enable flow logs on all subnets 

104 

105 .. yaml: 

106 

107 policies: 

108 - name: flow-active 

109 resource: gcp.subnet 

110 filters: 

111 - enableFlowLogs: empty 

112 actions: 

113 - set-flow-log 

114 

115 """ 

116 

117 schema = type_schema( 

118 'set-flow-log', 

119 state={'type': 'boolean', 'default': True}) 

120 method_spec = {'op': 'patch'} 

121 method_perm = 'update' 

122 

123 def get_resource_params(self, m, r): 

124 params = super(SetFlowLog, self).get_resource_params(m, r) 

125 return { 

126 'project': params['project'], 

127 'region': params['region'], 

128 'subnetwork': params['subnetwork'], 

129 'body': { 

130 'fingerprint': r['fingerprint'], 

131 'enableFlowLogs': self.data.get('state', True)} 

132 } 

133 

134 

135@Subnet.action_registry.register('set-private-api') 

136class SetGcpPrivateAccess(SubnetAction): 

137 """Enable/Disable GCP Private IP Access for a subnet""" 

138 

139 schema = type_schema( 

140 'set-gcp-private', 

141 state={'type': 'boolean', 'default': True}) 

142 method_spec = {'op': 'setPrivateIpGoogleAccess'} 

143 

144 def get_resource_params(self, m, r): 

145 params = super(SetGcpPrivateAccess, self).get_resource_params(m, r) 

146 params['body'] = { 

147 'privateIpGoogleAccess': self.data.get('state', True)} 

148 return params 

149 

150 

151@resources.register('firewall') 

152class Firewall(QueryResourceManager): 

153 """GCP resource: https://cloud.google.com/compute/docs/reference/rest/v1/firewalls 

154 """ 

155 class resource_type(TypeInfo): 

156 service = 'compute' 

157 version = 'v1' 

158 component = 'firewalls' 

159 name = id = "name" 

160 default_report_fields = [ 

161 name, "description", "network", "priority", "creationTimestamp", 

162 "logConfig.enable", "disabled"] 

163 asset_type = "compute.googleapis.com/Firewall" 

164 scc_type = "google.compute.Firewall" 

165 metric_key = 'metric.labels.firewall_name' 

166 urn_component = "firewall" 

167 

168 @staticmethod 

169 def get(client, resource_info): 

170 return client.execute_query( 

171 'get', {'project': resource_info['project_id'], 

172 'firewall': resource_info['resourceName'].rsplit('/', 1)[-1]}) 

173 

174 def augment(self, resources): 

175 if not resources: 

176 return [] 

177 return get_firewall_port_ranges(resources) 

178 

179@Firewall.action_registry.register('delete') 

180class DeleteFirewall(MethodAction): 

181 """Delete filtered Firewall Rules 

182 

183 :example: Delete firewall rule 

184 

185 .. yaml: 

186 

187 policies: 

188 - name: delete-public-access-firewall-rules 

189 resource: gcp.firewall 

190 filters: 

191 - type: value 

192 key: sourceRanges 

193 value: "0.0.0.0/0" 

194 op: in 

195 value_type: swap 

196 actions: 

197 - delete 

198 """ 

199 

200 schema = type_schema('delete') 

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

202 path_param_re = re.compile('.*?/projects/(.*?)/global/firewalls/(.*)') 

203 

204 def get_resource_params(self, m, r): 

205 project, resource_name = self.path_param_re.match( 

206 r['selfLink']).groups() 

207 return {'project': project, 'firewall': resource_name} 

208 

209 

210@Firewall.action_registry.register('modify') 

211class ModifyFirewall(MethodAction): 

212 """Modify filtered Firewall Rules 

213 

214 :example: Enable logging on filtered firewalls 

215 

216 .. yaml: 

217 

218 policies: 

219 - name: enable-firewall-logging 

220 resource: gcp.firewall 

221 filters: 

222 - type: value 

223 key: name 

224 value: no-logging 

225 actions: 

226 - type: modify 

227 logConfig: 

228 enabled: true 

229 """ 

230 

231 schema = type_schema( 

232 'modify', 

233 **{'description': {'type': 'string'}, 

234 'network': {'type': 'string'}, 

235 'priority': {'type': 'number'}, 

236 'sourceRanges': {'type': 'array', 'items': {'type': 'string'}}, 

237 'destinationRanges': {'type': 'array', 'items': {'type': 'string'}}, 

238 'sourceTags': {'type': 'array', 'items': {'type': 'string'}}, 

239 'targetTags': {'type': 'array', 'items': {'type': 'string'}}, 

240 'sourceServiceAccounts': {'type': 'array', 'items': {'type': 'string'}}, 

241 'targetServiceAccounts': {'type': 'array', 'items': {'type': 'string'}}, 

242 'allowed': {'type': 'array', 'items': {'type': 'object'}}, 

243 'denied': {'type': 'array', 'items': {'type': 'object'}}, 

244 'direction': {'enum': ['INGRESS', 'EGRESS']}, 

245 'logConfig': {'type': 'object'}, 

246 'disabled': {'type': 'boolean'}}) 

247 method_spec = {'op': 'patch'} 

248 permissions = ('compute.networks.updatePolicy', 'compute.firewalls.update') 

249 path_param_re = re.compile('.*?/projects/(.*?)/global/firewalls/(.*)') 

250 

251 def get_resource_params(self, m, r): 

252 project, resource_name = self.path_param_re.match( 

253 r['selfLink']).groups() 

254 return {'project': project, 'firewall': resource_name, 'body': self.data} 

255 

256 

257@resources.register('router') 

258class Router(QueryResourceManager): 

259 """GCP resource: https://cloud.google.com/compute/docs/reference/rest/v1/routers 

260 """ 

261 class resource_type(TypeInfo): 

262 service = 'compute' 

263 version = 'v1' 

264 component = 'routers' 

265 enum_spec = ('aggregatedList', 'items.*.routers[]', None) 

266 name = id = 'name' 

267 default_report_fields = [ 

268 "name", "description", "creationTimestamp", "region", "network"] 

269 asset_type = "compute.googleapis.com/Router" 

270 urn_component = "router" 

271 

272 @staticmethod 

273 def get(client, resource_info): 

274 return client.execute_command( 

275 'get', {'project': resource_info['project_id'], 

276 'region': resource_info['region'], 

277 'router': resource_info['resourceName'].rsplit('/', 1)[-1]}) 

278 

279 

280@Router.action_registry.register('delete') 

281class DeleteRouter(MethodAction): 

282 """`Deletes <https://cloud.google.com/compute/docs/reference/rest/v1/routers/delete>`_ a router 

283 

284 :Example: 

285 

286 .. code-block:: yaml 

287 

288 policies: 

289 - name: gcp-network-unattached-routers 

290 description: Deletes unattached Cloud Routers 

291 resource: gcp.router 

292 filters: 

293 - type: value 

294 key: interfaces 

295 value: absent 

296 actions: 

297 - delete 

298 """ 

299 

300 schema = type_schema('delete') 

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

302 path_param_re = re.compile('.*?/projects/(.*?)/regions/(.*?)/routers/(.*)') 

303 

304 def get_resource_params(self, m, r): 

305 project, region, router = self.path_param_re.match(r['selfLink']).groups() 

306 return {'project': project, 'region': region, 'router': router} 

307 

308 

309@resources.register('route') 

310class Route(QueryResourceManager): 

311 """GCP resource: https://cloud.google.com/compute/docs/reference/rest/v1/routes 

312 """ 

313 class resource_type(TypeInfo): 

314 service = 'compute' 

315 version = 'v1' 

316 component = 'routes' 

317 enum_spec = ('list', 'items[]', None) 

318 name = id = 'name' 

319 default_report_fields = [ 

320 "name", "description", "creationTimestamp", "network", "priority", "destRange"] 

321 asset_type = "compute.googleapis.com/Route" 

322 urn_component = "route" 

323 

324 @staticmethod 

325 def get(client, resource_info): 

326 return client.execute_command( 

327 'get', {'project': resource_info['project_id'], 

328 'route': resource_info['resourceName'].rsplit('/', 1)[-1]}) 

329 

330 

331@resources.register('interconnect') 

332class Interconnect(QueryResourceManager): 

333 """GCP resource: https://cloud.google.com/compute/docs/reference/rest/v1/interconnects 

334 """ 

335 class resource_type(TypeInfo): 

336 service = 'compute' 

337 version = 'v1' 

338 component = 'interconnects' 

339 enum_spec = ('list', 'items[]', None) 

340 name = id = 'name' 

341 default_report_fields = [ 

342 "name", "description", "creationTimestamp", "operationalStatus", 

343 "linkType", "location"] 

344 asset_type = "compute.googleapis.com/Interconnect" 

345 

346 @staticmethod 

347 def get(client, resource_info): 

348 return client.execute_command( 

349 'get', {'project': resource_info['project_id'], 

350 'interconnect': resource_info['resourceName'].rsplit('/', 1)[-1]}) 

351 

352 

353@resources.register('interconnect-attachment') 

354class InterconnectAttachment(QueryResourceManager): 

355 """GCP resource: https://cloud.google.com/compute/docs/reference/rest/v1/interconnectAttachments 

356 """ 

357 class resource_type(TypeInfo): 

358 service = 'compute' 

359 version = 'v1' 

360 component = 'interconnectAttachments' 

361 enum_spec = ('aggregatedList', 'items.*.interconnectAttachments[]', None) 

362 name = id = 'name' 

363 default_report_fields = [ 

364 "name", "description", "creationTimestamp", "interconnect", 

365 "router", "region", "operationalStatus"] 

366 asset_type = "compute.googleapis.com/InterconnectAttachment" 

367 

368 @staticmethod 

369 def get(client, resource_info): 

370 project, region, name = re.match( 

371 'projects/(.*?)/regions/(.*?)/interconnectAttachments/(.*?)', 

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

373 

374 return client.execute_command( 

375 'get', {'project': project, 

376 'interconnectAttachment': name, 

377 'region': region})