diff --git a/README.md b/README.md index 6fbf8cae..09e5c3ef 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ PCW has two main flows : b. Snapshots in all region defined c. Volumes in all regions defined d. VPC's ( deletion of VPC means deletion of all assigned to VPC entities first ( security groups , networks etc. )) - - For GCE deleting only images (check details in [ocw/lib/gce.py](ocw/lib/gce.py)) + - For GCE deleting disks, images & network resources (check details in [ocw/lib/gce.py](ocw/lib/gce.py)) - For Openstack deleting instances, images & keypairs (check details in [ocw/lib/openstack.py](ocw/lib/openstack.py) diff --git a/ocw/lib/gce.py b/ocw/lib/gce.py index a03c67ac..4e2cdd5d 100644 --- a/ocw/lib/gce.py +++ b/ocw/lib/gce.py @@ -39,6 +39,7 @@ def _delete_resource(self, api_call, resource_name, *_, **kwargs) -> None: resource_type = { self.compute_client().disks: "disk", self.compute_client().firewalls: "firewall", + self.compute_client().forwardingRules: "forwardingRule", self.compute_client().images: "image", self.compute_client().instances: "instance", self.compute_client().networks: "network", @@ -118,6 +119,7 @@ def cleanup_all(self) -> None: self.cleanup_disks() self.cleanup_images() self.cleanup_firewalls() + self.cleanup_forwarding_rules() self.cleanup_routes() self.cleanup_subnetworks() self.cleanup_networks() @@ -158,6 +160,21 @@ def cleanup_firewalls(self) -> None: self.compute_client().firewalls, firewall["name"], project=self.project, firewall=firewall["name"] ) + def cleanup_forwarding_rules(self) -> None: + self.log_dbg("Forwarding rules cleanup") + for region in self.list_regions(): + rules = [ + rule for rule in self._paginated(self.compute_client().forwardingRules, project=self.project, region=region) + if basename(rule["network"]) not in self.__skip_networks + ] + self.log_dbg(f"{len(rules)} forwarding_rules found") + for rule in rules: + if self.is_outdated(parse(rule["creationTimestamp"]).astimezone(timezone.utc)): + self._delete_resource( + self.compute_client().forwardingRules, rule["name"], + project=self.project, region=region, forwardingRule=rule["name"] + ) + def cleanup_routes(self) -> None: self.log_dbg("Routes cleanup") routes = [ diff --git a/tests/test_gce.py b/tests/test_gce.py index 53488e2c..abc0c2ce 100644 --- a/tests/test_gce.py +++ b/tests/test_gce.py @@ -32,7 +32,7 @@ def list_next(self, *args, **kwargs): return self.responses.pop(0) def delete(self, *args, **kwargs): - for resource in ('image', 'disk', 'instance', 'firewall', 'route', 'network', 'subnetwork'): + for resource in ('image', 'disk', 'instance', 'firewall', 'forwardingRule', 'route', 'network', 'subnetwork'): if resource in kwargs: self.deleted_resources.append(kwargs[resource]) if len(self.responses) > 0: @@ -50,6 +50,7 @@ def something(): class MockClient: def disks(self): pass def firewalls(self): pass + def forwardingRules(self): pass def images(self): pass def instances(self): pass def networks(self): pass @@ -148,6 +149,10 @@ def test_cleanup_firewalls(gce): _test_cleanup(gce, "firewalls", gce.cleanup_firewalls) +def test_cleanup_forwarding_rules(gce): + _test_cleanup(gce, "forwardingRules", gce.cleanup_forwarding_rules) + + def test_cleanup_routes(gce): _test_cleanup(gce, "routes", gce.cleanup_routes) @@ -164,6 +169,7 @@ def test_cleanup_all(gce): gce.cleanup_disks = MagicMock() gce.cleanup_images = MagicMock() gce.cleanup_firewalls = MagicMock() + gce.cleanup_forwarding_rules = MagicMock() gce.cleanup_routes = MagicMock() gce.cleanup_subnetworks = MagicMock() gce.cleanup_networks = MagicMock() @@ -171,6 +177,7 @@ def test_cleanup_all(gce): gce.cleanup_disks.assert_called_once() gce.cleanup_images.assert_called_once() gce.cleanup_firewalls.assert_called_once() + gce.cleanup_forwarding_rules.assert_called_once() gce.cleanup_routes.assert_called_once() gce.cleanup_networks.assert_called_once() gce.cleanup_subnetworks.assert_called_once()