-
Notifications
You must be signed in to change notification settings - Fork 167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Self parse user data #306
Self parse user data #306
Changes from 5 commits
795ebfd
3a19de3
46bc428
bc5676d
b3ffba5
9f0f668
0496068
e7ea56c
08f93bd
e04cf9e
63ab875
7c9143f
5cffa64
8f52dd2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,13 @@ | ||
import copy | ||
import hashlib | ||
import logging | ||
import re | ||
import base64 | ||
|
||
from troposphere import ( | ||
Parameter, | ||
Ref, | ||
Template, | ||
Template | ||
) | ||
|
||
from ..exceptions import ( | ||
|
@@ -221,6 +223,7 @@ def resolve_variable(var_name, var_def, provided_variable, blueprint_name): | |
|
||
|
||
class Blueprint(object): | ||
|
||
"""Base implementation for rendering a troposphere template. | ||
|
||
Args: | ||
|
@@ -402,6 +405,46 @@ def render_template(self): | |
version = hashlib.md5(rendered).hexdigest()[:8] | ||
return (version, rendered) | ||
|
||
def parse_user_data(self, raw_user_data): | ||
"""Translate a userdata file to into the file contents. | ||
|
||
It supports referencing template variables to create userdata | ||
that's supplemented with information from the data, as commonly | ||
required when creating EC2 userdata files. Automatically, encodes | ||
the data file to base64 after it is processed. | ||
|
||
Args: | ||
raw_user_data (str): the user data with the cloud-init info | ||
|
||
Returns: | ||
str: The parsed user data, with all the variables values and | ||
refs replaced with their resolved values. | ||
|
||
""" | ||
pattern = re.compile(r'{{([::|\w]+)}}') | ||
res = "" | ||
start_index = 0 | ||
variables = self.get_variables() | ||
|
||
for match in pattern.finditer(raw_user_data): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets go with the standard python Also, please double check that the parameters aren't availabe in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
res += raw_user_data[start_index:match.start()] | ||
|
||
key = match.group(1) | ||
|
||
if key in variables: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldn't usually check for the existence of a key - instead you should use try/except:
Then work with v for the rest of the logic, outside of the block. |
||
if type(variables[key]) is CFNParameter: | ||
res += variables[key].to_parameter_value() | ||
else: | ||
res += variables[key] | ||
else: | ||
raise MissingVariable(self.name, key) | ||
|
||
start_index = match.end() | ||
|
||
res += raw_user_data[start_index:] | ||
|
||
return base64.b64encode(res) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be better to not encode this at all, letting the user choose whether to encode it either using base64 or the Base64 troposphere method. what do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that's fair. They could extend the script if they wanted to. |
||
|
||
@property | ||
def rendered(self): | ||
if not self._rendered: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One issue w/ building your own templating engine is that there's no way to escape this with the current implementation, right? Python actually has a second string formatting/templating system that you can use perhaps? https://docs.python.org/3/library/string.html#format-string-syntax