Dependency handling refactoring

This commit is contained in:
Stefan Reimer 2019-02-05 17:48:29 +00:00
parent 139cf36d3c
commit 3587451170
2 changed files with 45 additions and 25 deletions

View File

@ -16,17 +16,43 @@ import types
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@jinja2.contextfunction @jinja2.contextfunction
def get_custom_att(context, att=None, ResourceName="FortyTwo", attributes={}, flush=False, dump=False, dependencies=False): def cloudbender_ctx(context, cb_ctx={}, reset=False, command=None, args={}):
# Reset state
if reset:
cb_ctx.clear()
return
if 'dependencies' not in cb_ctx:
cb_ctx['dependencies'] = set()
if command == 'get_dependencies':
_deps = sorted(list(cb_ctx['dependencies']))
if _deps:
logger.debug("Stack depencies: {}".format(','.join(_deps)))
return _deps
elif command == 'add_dependency':
try:
cb_ctx['dependencies'].add(args['dep'])
logger.debug("Adding stack depency to {}".format(args['dep']))
except KeyError:
pass
else:
raise("Unknown command")
@jinja2.contextfunction
def get_custom_att(context, att=None, ResourceName="FortyTwo", attributes={}, reset=False, dump=False):
""" Returns the rendered required fragement and also collects all foreign """ Returns the rendered required fragement and also collects all foreign
attributes for the specified CustomResource to include them later in attributes for the specified CustomResource to include them later in
the actual CustomResource include property """ the actual CustomResource include property """
if ResourceName not in attributes: # Reset state
attributes[ResourceName] = set() if reset:
# If flush is set all we do is empty our state dict
if flush:
attributes.clear() attributes.clear()
return return
@ -34,25 +60,17 @@ def get_custom_att(context, att=None, ResourceName="FortyTwo", attributes={}, fl
if dump: if dump:
return attributes return attributes
# If dependencies, return all Artifacts this stack depends on, which are the attr of FortyTwo # If called with an attribute, return fragement and register dependency
config = context.get_all()['_config']
if dependencies:
deps = set()
try:
for att in attributes['FortyTwo']:
deps.add(att.split('.')[0])
except KeyError:
pass
# Incl. FortyTwo itself if any FortyTwo function is used
if config['cfn']['Mode'] == "FortyTwo" and attributes:
deps.add('FortyTwo')
return list(deps)
# If call with an attribute, return fragement and register
if att: if att:
config = context.get_all()['_config']
if ResourceName not in attributes:
attributes[ResourceName] = set()
attributes[ResourceName].add(att) attributes[ResourceName].add(att)
if ResourceName == 'FortyTwo':
cloudbender_ctx(context, command='add_dependency', args={'dep': att.split('.')[0]})
if config['cfn']['Mode'] == "FortyTwo": if config['cfn']['Mode'] == "FortyTwo":
return('{{ "Fn::GetAtt": ["{0}", "{1}"] }}'.format(ResourceName, att)) return('{{ "Fn::GetAtt": ["{0}", "{1}"] }}'.format(ResourceName, att))
elif config['cfn']['Mode'] == "AWSImport" and ResourceName == "FortyTwo": elif config['cfn']['Mode'] == "AWSImport" and ResourceName == "FortyTwo":
@ -85,7 +103,7 @@ def include_raw_gz(context, files=None, gz=True):
@jinja2.contextfunction @jinja2.contextfunction
def render_once(context, name=None, resources=set(), reset=False): def render_once(context, name=None, resources=set(), reset=False):
""" Utility function to True only once """ """ Utility function returning True only once per name """
if reset: if reset:
resources.clear() resources.clear()
@ -174,6 +192,7 @@ def JinjaEnv(template_locations=[]):
jenv.globals['include_raw'] = include_raw_gz jenv.globals['include_raw'] = include_raw_gz
jenv.globals['get_custom_att'] = get_custom_att jenv.globals['get_custom_att'] = get_custom_att
jenv.globals['cloudbender_ctx'] = cloudbender_ctx
jenv.globals['render_once'] = render_once jenv.globals['render_once'] = render_once
jenv.globals['raise'] = raise_helper jenv.globals['raise'] = raise_helper

View File

@ -125,8 +125,9 @@ class Stack(object):
template_metadata['Template.Hash'] = hashlib.md5(template.render({ 'cfn': self.template_vars, 'Metadata': template_metadata }).encode('utf-8')).hexdigest() template_metadata['Template.Hash'] = hashlib.md5(template.render({ 'cfn': self.template_vars, 'Metadata': template_metadata }).encode('utf-8')).hexdigest()
# Reset and set Metadata for final render pass # Reset and set Metadata for final render pass
jenv.globals['get_custom_att'](context={'_config': self.template_vars}, flush=True) jenv.globals['get_custom_att'](context={'_config': self.template_vars}, reset=True)
jenv.globals['render_once'](context={'_config': self.template_vars}, reset=True) jenv.globals['render_once'](context={'_config': self.template_vars}, reset=True)
jenv.globals['cloudbender_ctx'](context={'_config': self.template_vars}, reset=True)
# try to get local git info # try to get local git info
try: try: