1515import argparse
1616import os
1717import re
18-
1918import boto3
20- try :
21- import requests
22- except ImportError :
23- from botocore .vendored import requests
2419
2520REGION = None
2621DRYRUN = None
@@ -46,12 +41,10 @@ def initialize():
4641def handler (event , context ):
4742 initialize ()
4843 if REGION == "None" :
49- partitions = requests .get ("https://raw.githubusercontent.com/boto/botocore/develop/botocore/data/endpoints.json" ).json ()[
50- 'partitions' ]
51- for partition in partitions :
52- if partition ['partition' ] == "aws" :
53- for endpoint in partition ['services' ]['ecs' ]['endpoints' ]:
54- discover_delete_images (endpoint )
44+ ec2_client = boto3 .client ('ec2' )
45+ available_regions = ec2_client .describe_regions ()['Regions' ]
46+ for region in available_regions :
47+ discover_delete_images (region ['RegionName' ])
5548 else :
5649 discover_delete_images (REGION )
5750
@@ -66,8 +59,6 @@ def discover_delete_images(regionname):
6659 for repo in response_listrepopaginator ['repositories' ]:
6760 repositories .append (repo )
6861
69- # print(repositories)
70-
7162 ecs_client = boto3 .client ('ecs' , region_name = regionname )
7263
7364 listclusters_paginator = ecs_client .get_paginator ('list_clusters' )
@@ -129,15 +120,15 @@ def discover_delete_images(regionname):
129120 running_sha .append (image ['imageDigest' ])
130121
131122 print ("Number of running images found {}" .format (len (running_sha )))
132-
123+ ignore_tags_regex = re . compile ( IGNORE_TAGS_REGEX )
133124 for image in tagged_images :
134125 if tagged_images .index (image ) >= IMAGES_TO_KEEP :
135126 for tag in image ['imageTags' ]:
136- if "latest" not in tag and re . compile ( IGNORE_TAGS_REGEX ) .search (tag ) is None :
127+ if "latest" not in tag and ignore_tags_regex .search (tag ) is None :
137128 if not running_sha or image ['imageDigest' ] not in running_sha :
138129 append_to_list (deletesha , image ['imageDigest' ])
139130 append_to_tag_list (deletetag , {"imageUrl" : repository ['repositoryUri' ] + ":" + tag ,
140- "pushedAt" : image ["imagePushedAt" ]})
131+ "pushedAt" : image ["imagePushedAt" ]})
141132 if deletesha :
142133 print ("Number of images to be deleted: {}" .format (len (deletesha )))
143134 delete_images (
@@ -151,23 +142,23 @@ def discover_delete_images(regionname):
151142 print ("Nothing to delete in repository : " + repository ['repositoryName' ])
152143
153144
154- def append_to_list (list , id ):
155- if not {'imageDigest' : id } in list :
156- list .append ({'imageDigest' : id })
145+ def append_to_list (image_digest_list , repo_id ):
146+ if not {'imageDigest' : repo_id } in image_digest_list :
147+ image_digest_list .append ({'imageDigest' : repo_id })
157148
158149
159- def append_to_tag_list (list , id ):
160- if not id in list :
161- list .append (id )
150+ def append_to_tag_list (tag_list , tag_id ):
151+ if not tag_id in tag_list :
152+ tag_list .append (tag_id )
162153
163154
164- def chunks (l , n ):
155+ def chunks (repo_list , chunk_size ):
165156 """Yield successive n-sized chunks from l."""
166- for i in range (0 , len (l ), n ):
167- yield l [i :i + n ]
157+ for i in range (0 , len (repo_list ), chunk_size ):
158+ yield repo_list [i :i + chunk_size ]
168159
169160
170- def delete_images (ecr_client , deletesha , deletetag , id , name ):
161+ def delete_images (ecr_client , deletesha , deletetag , repo_id , name ):
171162 if len (deletesha ) >= 1 :
172163 ## spliting list of images to delete on chunks with 100 images each
173164 ## http://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_BatchDeleteImage.html#API_BatchDeleteImage_RequestSyntax
@@ -176,13 +167,13 @@ def delete_images(ecr_client, deletesha, deletetag, id, name):
176167 i += 1
177168 if not DRYRUN :
178169 delete_response = ecr_client .batch_delete_image (
179- registryId = id ,
170+ registryId = repo_id ,
180171 repositoryName = name ,
181172 imageIds = deletesha_chunk
182173 )
183174 print (delete_response )
184175 else :
185- print ("registryId:" + id )
176+ print ("registryId:" + repo_id )
186177 print ("repositoryName:" + name )
187178 print ("Deleting {} chank of images" .format (i ))
188179 print ("imageIds:" , end = '' )
@@ -195,21 +186,21 @@ def delete_images(ecr_client, deletesha, deletetag, id, name):
195186
196187# Below is the test harness
197188if __name__ == '__main__' :
198- request = {"None" : "None" }
199- parser = argparse .ArgumentParser (description = 'Deletes stale ECR images' )
200- parser .add_argument ('-dryrun' , help = 'Prints the repository to be deleted without deleting them' , default = 'true' ,
189+ REQUEST = {"None" : "None" }
190+ PARSER = argparse .ArgumentParser (description = 'Deletes stale ECR images' )
191+ PARSER .add_argument ('-dryrun' , help = 'Prints the repository to be deleted without deleting them' , default = 'true' ,
201192 action = 'store' , dest = 'dryrun' )
202- parser .add_argument ('-imagestokeep' , help = 'Number of image tags to keep' , default = '100' , action = 'store' ,
193+ PARSER .add_argument ('-imagestokeep' , help = 'Number of image tags to keep' , default = '100' , action = 'store' ,
203194 dest = 'imagestokeep' )
204- parser .add_argument ('-region' , help = 'ECR/ECS region' , default = None , action = 'store' , dest = 'region' )
205- parser .add_argument ('-ignoretagsregex' , help = 'Regex of tag names to ignore' , default = "^$" , action = 'store' , dest = 'ignoretagsregex' )
195+ PARSER .add_argument ('-region' , help = 'ECR/ECS region' , default = None , action = 'store' , dest = 'region' )
196+ PARSER .add_argument ('-ignoretagsregex' , help = 'Regex of tag names to ignore' , default = "^$" , action = 'store' , dest = 'ignoretagsregex' )
206197
207- args = parser .parse_args ()
208- if args .region :
209- os .environ ["REGION" ] = args .region
198+ ARGS = PARSER .parse_args ()
199+ if ARGS .region :
200+ os .environ ["REGION" ] = ARGS .region
210201 else :
211202 os .environ ["REGION" ] = "None"
212- os .environ ["DRYRUN" ] = args .dryrun .lower ()
213- os .environ ["IMAGES_TO_KEEP" ] = args .imagestokeep
214- os .environ ["IGNORE_TAGS_REGEX" ] = args .ignoretagsregex
215- handler (request , None )
203+ os .environ ["DRYRUN" ] = ARGS .dryrun .lower ()
204+ os .environ ["IMAGES_TO_KEEP" ] = ARGS .imagestokeep
205+ os .environ ["IGNORE_TAGS_REGEX" ] = ARGS .ignoretagsregex
206+ handler (REQUEST , None )
0 commit comments