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

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

173 statements  

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 

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

181class DeleteFirewall(MethodAction): 

182 """Delete filtered Firewall Rules 

183 

184 :example: Delete firewall rule 

185 

186 .. yaml: 

187 

188 policies: 

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

190 resource: gcp.firewall 

191 filters: 

192 - type: value 

193 key: sourceRanges 

194 value: "0.0.0.0/0" 

195 op: in 

196 value_type: swap 

197 actions: 

198 - delete 

199 """ 

200 

201 schema = type_schema('delete') 

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

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

204 

205 def get_resource_params(self, m, r): 

206 project, resource_name = self.path_param_re.match( 

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

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

209 

210 

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

212class ModifyFirewall(MethodAction): 

213 """Modify filtered Firewall Rules 

214 

215 :example: Enable logging on filtered firewalls 

216 

217 .. yaml: 

218 

219 policies: 

220 - name: enable-firewall-logging 

221 resource: gcp.firewall 

222 filters: 

223 - type: value 

224 key: name 

225 value: no-logging 

226 actions: 

227 - type: modify 

228 logConfig: 

229 enabled: true 

230 """ 

231 

232 schema = type_schema( 

233 'modify', 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

251 

252 def get_resource_params(self, m, r): 

253 project, resource_name = self.path_param_re.match( 

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

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

256 

257 

258@resources.register('router') 

259class Router(QueryResourceManager): 

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

261 """ 

262 class resource_type(TypeInfo): 

263 service = 'compute' 

264 version = 'v1' 

265 component = 'routers' 

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

267 name = id = 'name' 

268 default_report_fields = [ 

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

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

271 urn_component = "router" 

272 

273 @staticmethod 

274 def get(client, resource_info): 

275 return client.execute_command( 

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

277 'region': resource_info['region'], 

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

279 

280 

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

282class DeleteRouter(MethodAction): 

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

284 

285 :Example: 

286 

287 .. code-block:: yaml 

288 

289 policies: 

290 - name: gcp-network-unattached-routers 

291 description: Deletes unattached Cloud Routers 

292 resource: gcp.router 

293 filters: 

294 - type: value 

295 key: interfaces 

296 value: absent 

297 actions: 

298 - delete 

299 """ 

300 

301 schema = type_schema('delete') 

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

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

304 

305 def get_resource_params(self, m, r): 

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

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

308 

309 

310@resources.register('route') 

311class Route(QueryResourceManager): 

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

313 """ 

314 class resource_type(TypeInfo): 

315 service = 'compute' 

316 version = 'v1' 

317 component = 'routes' 

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

319 name = id = 'name' 

320 default_report_fields = [ 

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

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

323 urn_component = "route" 

324 

325 @staticmethod 

326 def get(client, resource_info): 

327 return client.execute_command( 

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

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

330 

331 

332@resources.register('interconnect') 

333class Interconnect(QueryResourceManager): 

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

335 """ 

336 class resource_type(TypeInfo): 

337 service = 'compute' 

338 version = 'v1' 

339 component = 'interconnects' 

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

341 name = id = 'name' 

342 default_report_fields = [ 

343 "name", "description", "creationTimestamp", "operationalStatus", 

344 "linkType", "location"] 

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

346 

347 @staticmethod 

348 def get(client, resource_info): 

349 return client.execute_command( 

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

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

352 

353 

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

355class InterconnectAttachment(QueryResourceManager): 

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

357 """ 

358 class resource_type(TypeInfo): 

359 service = 'compute' 

360 version = 'v1' 

361 component = 'interconnectAttachments' 

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

363 name = id = 'name' 

364 default_report_fields = [ 

365 "name", "description", "creationTimestamp", "interconnect", 

366 "router", "region", "operationalStatus"] 

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

368 

369 @staticmethod 

370 def get(client, resource_info): 

371 project, region, name = re.match( 

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

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

374 

375 return client.execute_command( 

376 'get', {'project': project, 

377 'interconnectAttachment': name, 

378 'region': region})