1616
1717def is_interpolation (value ):
1818 return isinstance (value , string_types ) and '{{' in value and '}}' in value \
19- and '{{`' not in value and '`}}' not in value
19+ and not is_escaped_interpolation (value )
20+
21+
22+ def is_escaped_interpolation (value ):
23+ return isinstance (value , string_types ) and value .startswith ('{{`' ) and value .endswith ('`}}' )
2024
2125
2226def is_full_interpolation (value ):
@@ -48,6 +52,19 @@ def resolve_interpolations(self, data):
4852 return data
4953
5054
55+ class EscapingResolver (object ):
56+
57+ def resolve_escaping (self , data ):
58+ """
59+ Should do one last check through all values to ensure the ones that were escaped are cleaned of the escape
60+ sequence
61+ """
62+ from_dict_injector = DictEscapingResolver (data , FromDictInjector ())
63+ from_dict_injector .clean_escapes (data )
64+
65+ return data
66+
67+
5168class SecretResolver (object ):
5269
5370 def resolve_secrets (self , data , default_aws_profile ):
@@ -82,6 +99,21 @@ def loop_all_items(self, data, process_func):
8299 return data
83100
84101
102+ class AbstractEscapingResolver (DictIterator ):
103+
104+ def clean_escapes (self , data ):
105+ return self .loop_all_items (data , self .clean_escape )
106+
107+ def clean_escape (self , line ):
108+ # Check if line is escaped
109+ if not is_escaped_interpolation (line ):
110+ return line
111+ return self .do_clean_escapes (line )
112+
113+ def do_clean_escapes (self , line ):
114+ pass
115+
116+
85117class AbstractInterpolationResolver (DictIterator ):
86118
87119 def resolve_interpolations (self , data ):
@@ -98,6 +130,18 @@ def do_resolve_interpolation(self, line):
98130 pass
99131
100132
133+ class DictEscapingResolver (AbstractEscapingResolver ):
134+ def __init__ (self , data , from_dict_injector ):
135+ AbstractEscapingResolver .__init__ (self )
136+ self .data = data
137+ self .from_dict_injector = from_dict_injector
138+ self .full_blob_injector = FullBlobInjector ()
139+
140+ def do_clean_escapes (self , line ):
141+ updated_line = self .from_dict_injector .resolve (line , self .data )
142+ return self .full_blob_injector .clean (updated_line )
143+
144+
101145class DictInterpolationResolver (AbstractInterpolationResolver ):
102146 def __init__ (self , data , from_dict_injector ):
103147 AbstractInterpolationResolver .__init__ (self )
@@ -179,6 +223,15 @@ def resolve(self, line, data):
179223
180224 return resolved_value if is_valid_value else line
181225
226+ def clean (self , line ):
227+ if not is_escaped_interpolation (line ):
228+ return line
229+
230+ resolved_value = self .get_value_from_escaping (line )
231+ is_valid_value = resolved_value is not None
232+
233+ return resolved_value if is_valid_value else line
234+
182235 @staticmethod
183236 def get_inner_value (keys , data ):
184237 for key in keys :
@@ -195,3 +248,10 @@ def get_keys_from_interpolation(line):
195248 line = line [2 :- 2 ]
196249
197250 return line .split ('.' )
251+
252+ @staticmethod
253+ def get_value_from_escaping (line ):
254+ # remove {{` and `}}
255+ line = line [3 :- 3 ]
256+
257+ return line
0 commit comments