11from __future__ import annotations
2+ from ast import For
23
34from typing import TYPE_CHECKING , Any
45if TYPE_CHECKING :
@@ -235,6 +236,15 @@ def parse_value(self, value):
235236 parsed_value = value
236237 return str (parsed_value ).strip ()
237238
239+ def cleanup_secrets (self ):
240+ local_secret_keys = self .local_secrets .keys ()
241+ remote_secret_keys = self .remote_secret_records .keys ()
242+ orphaned_secrets = [item for item in remote_secret_keys if item not in local_secret_keys ]
243+ for secret in orphaned_secrets :
244+ secret_record = self .remote_secrets [secret ]
245+ self .secrets_client .delete_secret (SecretId = secret_record ["ARN" ], ForceDeleteWithoutRecovery = True )
246+ logger .info (f"Deleted orphaned secret { secret_record ['ARN' ]} " )
247+
238248 @property
239249 def local_secrets (self ) -> typing .Dict [str , Any ]:
240250 if not hasattr (self , "_secrets" ):
@@ -266,6 +276,13 @@ def remote_secrets(self) -> typing.Dict[str, Any]:
266276
267277 return self ._remote_secrets
268278
279+ @property
280+ def remote_secret_records (self ) -> typing .Dict [str , Any ]:
281+ if not hasattr (self , "_remote_secrets" ):
282+ self ._remote_secrets = self .get_remote_secret_records ()
283+
284+ return self ._remote_secrets
285+
269286 @property
270287 def remote_values (self ) -> typing .Dict [str , Any ]:
271288 if not hasattr (self , "_remote_values" ):
@@ -333,11 +350,9 @@ def fetch_secret_value(self, secret):
333350 return ""
334351 return response ["SecretString" ]
335352
336- def get_remote_secrets (self ) -> typing .Dict [str , str ]:
337- paginator = self .secrets_client .get_paginator ('list_secrets' )
338- secrets = {}
339- response = paginator .paginate (
340- Filters = [
353+ @property
354+ def remote_secret_filters (self ):
355+ return [
341356 {
342357 'Key' : 'tag-key' ,
343358 'Values' : [
@@ -362,7 +377,13 @@ def get_remote_secrets(self) -> typing.Dict[str, str]:
362377 self .name
363378 ]
364379 },
365- ],
380+ ]
381+
382+ def get_remote_secrets (self ) -> typing .Dict [str , str ]:
383+ paginator = self .secrets_client .get_paginator ('list_secrets' )
384+ secrets = {}
385+ response = paginator .paginate (
386+ Filters = self .remote_secret_filters ,
366387 )
367388 for page in response :
368389 for secret in page ["SecretList" ]:
@@ -371,6 +392,19 @@ def get_remote_secrets(self) -> typing.Dict[str, str]:
371392
372393 return secrets
373394
395+ def get_remote_secret_records (self ):
396+ paginator = self .secrets_client .get_paginator ('list_secrets' )
397+ secrets = {}
398+ response = paginator .paginate (
399+ Filters = self .remote_secret_filters ,
400+ )
401+ for page in response :
402+ for secret in page ["SecretList" ]:
403+ secret_key = os .path .split (secret ["Name" ])[- 1 ]
404+ secrets [secret_key ] = secret
405+
406+ return secrets
407+
374408 def convert_flatten (self , d , parent_key = "" , sep = "_" ):
375409 items = []
376410 if isinstance (d , dict ):
@@ -481,12 +515,18 @@ def initBootstrap(self):
481515
482516 def put_config (self , delete_first ):
483517 self .cleanup_values ()
518+ self .cleanup_secrets ()
484519 for environment_name , environment in self .environments .items ():
485520 for app_name , app in environment .apps .items ():
486521 # pass
487522 app .upload_to_s3 ()
488523 app .push_secrets ()
489524
525+ def cleanup_secrets (self ):
526+ for environment_name , environment in self .environments .items ():
527+ for app_name , app in environment .apps .items ():
528+ app .cleanup_secrets ()
529+
490530 @property
491531 def environments (self ) -> typing .Dict [str , BootstrapEnvironment ]:
492532 if not hasattr (self , '_environments' ):
0 commit comments