@@ -15,6 +15,38 @@ def is_interpolation(input):
1515 return '{{' in input and '}}' in input
1616
1717
18+ class InterpolationResolver (object ):
19+
20+ def resolve_interpolations (self , data ):
21+ # Resolve from dictionary. Do one iteration before secret resolving, in order to resolve interpolations such as
22+ # the aws.profile
23+ # Example:
24+ # my_profile: test
25+ # aws:
26+ # profile: "{{my_profile}}"
27+ from_dict_injector = DictInterpolationResolver (data , FromDictInjector ())
28+ from_dict_injector .resolve_interpolations (data )
29+
30+ # Resolve interpolations representing secrets
31+ # Example:
32+ # value1: "{{ssm.path(mysecret)}}"
33+ secrets_injector = SecretsInterpolationResolver (self .get_secret_injector (data ))
34+ secrets_injector .resolve_interpolations (data )
35+
36+ # Perform another resolving, in case some secrets are used as interpolations.
37+ # Example:
38+ # value1: "{{ssm.mysecret}}"
39+ # value2: "something-{{value1}} <--- this will be resolved at this step
40+ from_dict_injector = DictInterpolationResolver (data , FromDictInjector ())
41+ from_dict_injector .resolve_interpolations (data )
42+
43+ return data
44+
45+ def get_secret_injector (self , data ):
46+ default_aws_profile = data ['aws' ]['profile' ] if 'aws' in data and 'profile' in data ['aws' ] else None
47+ return SecretInjector (default_aws_profile )
48+
49+
1850class DictIterator ():
1951
2052 def loop_all_items (self , data , process_func ):
@@ -33,23 +65,39 @@ def loop_all_items(self, data, process_func):
3365 return data
3466
3567
36- class InterpolationResolver (DictIterator ):
37-
38- def __init__ (self , data , secrets_injector = SecretInjector ()):
39- self .generated_data = data
40- self .secrets_injector = secrets_injector
41- self .from_dict_injector = FromDictInjector ()
68+ class AbstractInterpolationResolver (DictIterator ):
69+ def __init__ (self ):
70+ pass
4271
4372 def resolve_interpolations (self , data ):
4473 return self .loop_all_items (data , self .resolve_interpolation )
4574
4675 def resolve_interpolation (self , line ):
4776 if not is_interpolation (line ):
4877 return line
78+ return self .do_resolve_interpolation (line )
79+
80+ def do_resolve_interpolation (self , line ):
81+ pass
82+
83+
84+ class DictInterpolationResolver (AbstractInterpolationResolver ):
85+ def __init__ (self , data , from_dict_injector ):
86+ AbstractInterpolationResolver .__init__ (self )
87+ self .data = data
88+ self .from_dict_injector = from_dict_injector
89+
90+ def do_resolve_interpolation (self , line ):
91+ return self .from_dict_injector .resolve (line , self .data )
92+
93+
94+ class SecretsInterpolationResolver (AbstractInterpolationResolver ):
95+ def __init__ (self , secrets_injector ):
96+ AbstractInterpolationResolver .__init__ (self )
97+ self .secrets_injector = secrets_injector
4998
50- updated_line = self .secrets_injector .inject_secret (line )
51- updated_line = self .from_dict_injector .resolve (updated_line , self .generated_data )
52- return updated_line
99+ def do_resolve_interpolation (self , line ):
100+ return self .secrets_injector .inject_secret (line )
53101
54102
55103class InterpolationValidator (DictIterator ):
@@ -85,7 +133,7 @@ def resolve(self, line, data):
85133 continue
86134 elif isinstance (value , (int , bool )):
87135 return value
88- else :
136+ elif not is_interpolation ( value ) :
89137 line = line .replace (placeholder , value )
90138 return line
91139
0 commit comments