Skip to content

Commit 73654de

Browse files
committed
Add ability to delete key pairs
Functionality is not included in main cleanup workflow but added as Django command which needs to be executed manually
1 parent 2ada4ff commit 73654de

3 files changed

Lines changed: 40 additions & 0 deletions

File tree

ocw/lib/ec2.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,15 @@ def cleanup_images(self, valid_period_days: float) -> None:
369369
else:
370370
self.log_info(f"Delete image '{img['Name']}' (ami:{img['ImageId']})")
371371
self.ec2_client(region).deregister_image(ImageId=img['ImageId'], DryRun=False)
372+
373+
def cleanup_keypairs(self):
374+
self.log_dbg('Call cleanup_images')
375+
for region in self.all_regions:
376+
response = self.ec2_client(region).describe_key_pairs()
377+
self.log_dbg(f"Found {len(response['KeyPairs'])} images in {region}")
378+
for keypair in response['KeyPairs']:
379+
if self.dry_run:
380+
self.log_info(f"KeyPair deletion {keypair['KeyName']} skipped due to dry run mode")
381+
else:
382+
self.log_info(f"Delete KeyPair '{keypair['KeyName']}'")
383+
self.ec2_client(region).delete_key_pair(KeyName=keypair['KeyName'])
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from django.core.management.base import BaseCommand
2+
from webui.PCWConfig import PCWConfig
3+
from ocw.lib.ec2 import EC2
4+
5+
6+
class Command(BaseCommand):
7+
help = 'Delete all leftovers in all providers (according to pcw.ini)'
8+
9+
def handle(self, *args, **options):
10+
for namespace in PCWConfig.get_namespaces_for('cleanup'):
11+
EC2(namespace).cleanup_keypairs()

tests/test_ec2.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class MockedEC2Client():
8989
response = {}
9090
deleted_images = list()
9191
deleted_volumes = list()
92+
deleted_keys = list()
9293
snapshotid_to_delete = 'delete_me'
9394
volumeid_to_delete = 'delete_me'
9495
snapshotid_i_have_ami = 'you_can_not_delete_me'
@@ -139,6 +140,9 @@ def describe_snapshots(self, *args, **kwargs):
139140
def deregister_image(self, *args, **kwargs):
140141
MockedEC2Client.deleted_images.append(kwargs['ImageId'])
141142

143+
def delete_key_pair(self, *args, **kwargs):
144+
MockedEC2Client.deleted_keys.append(kwargs['KeyName'])
145+
142146
def delete_snapshot(self, SnapshotId):
143147
if MockedEC2Client.delete_snapshot_raise_error:
144148
error_response = {'Error': {'Code': 'InvalidSnapshot.InUse', 'Message': 'Message'}}
@@ -155,6 +159,9 @@ def describe_volumes(self, *args, **kwargs):
155159
def describe_vpcs(self, Filters):
156160
return MockedEC2Client.response
157161

162+
def describe_key_pairs(self):
163+
return MockedEC2Client.response
164+
158165
def describe_vpc_endpoints(self, Filters):
159166
return MockedEC2Client.response
160167

@@ -301,6 +308,16 @@ def test_cleanup_snapshots_cleanup_all_new(ec2_patch):
301308
assert len(MockedEC2Client.ec2_snapshots) == 2
302309

303310

311+
def test_cleanup_keypairs(ec2_patch):
312+
MockedEC2Client.response = {'KeyPairs': [{'KeyName': 'key1'}]}
313+
ec2_patch.dry_run = True
314+
ec2_patch.cleanup_keypairs()
315+
assert len(MockedEC2Client.deleted_keys) == 0
316+
ec2_patch.dry_run = False
317+
ec2_patch.cleanup_keypairs()
318+
assert len(MockedEC2Client.deleted_keys) == 1
319+
320+
304321
def test_cleanup_snapshots_cleanup_one_old(ec2_patch):
305322
MockedEC2Client.response = {
306323
'Snapshots': [{'SnapshotId': MockedEC2Client.snapshotid_to_delete, 'StartTime': older_than_max_age_date}]

0 commit comments

Comments
 (0)