Exemple #1
0
def _is_template(template_str):
    template_str = to_unicode(template_str)
    template = Template(template_str)
    try:
        return template_str != template.render({})
    except exceptions.UndefinedError:
        return True
Exemple #2
0
def _process(G, name, value):
    '''
    Determines whether parameter is a template or a value. Adds graph nodes and edges accordingly.
    '''
    # Jinja defaults to ascii parser in python 2.x unless you set utf-8 support on per module level
    # Instead we're just assuming every string to be a unicode string
    if isinstance(value, str):
        value = to_unicode(value)

    complex_value_str = None
    if isinstance(value, list) or isinstance(value, dict):
        complex_value_str = str(value)

    is_jinja_expr = (jinja_utils.is_jinja_expression(value)
                     or jinja_utils.is_jinja_expression(complex_value_str))

    if is_jinja_expr:
        G.add_node(name, template=value)

        template_ast = ENV.parse(value)
        LOG.debug('Template ast: %s', template_ast)
        # Dependencies of the node represent jinja variables used in the template
        # We're connecting nodes with an edge for every depencency to traverse them
        # in the right order and also make sure that we don't have missing or cyclic
        # dependencies upfront.
        dependencies = meta.find_undeclared_variables(template_ast)
        LOG.debug('Dependencies: %s', dependencies)
        if dependencies:
            for dependency in dependencies:
                G.add_edge(dependency, name)
    else:
        G.add_node(name, value=value)
Exemple #3
0
def render_values(mapping=None, context=None, allow_undefined=False):
    """
    Render an incoming mapping using context provided in context using Jinja2. Returns a dict
    containing rendered mapping.

    :param mapping: Input as a dictionary of key value pairs.
    :type mapping: ``dict``

    :param context: Context to be used for dictionary.
    :type context: ``dict``

    :rtype: ``dict``
    """

    if not context or not mapping:
        return mapping

    # Add in special __context variable that provides an easy way to get access to entire context.
    # This mean __context is a reserve key word although backwards compat is preserved by making
    # sure that real context is updated later and therefore will override the __context value.
    super_context = {}
    super_context['__context'] = context
    super_context.update(context)

    env = get_jinja_environment(allow_undefined=allow_undefined)
    rendered_mapping = {}
    for k, v in six.iteritems(mapping):
        # jinja2 works with string so transform list and dict to strings.
        reverse_json_dumps = False
        if isinstance(v, dict) or isinstance(v, list):
            v = json.dumps(v)
            reverse_json_dumps = True
        else:
            # Special case for text type to handle unicode
            if isinstance(v, six.string_types):
                v = to_unicode(v)
            else:
                # Other types (e.g. boolean, etc.)
                v = str(v)

        try:
            LOG.info('Rendering string %s. Super context=%s', v, super_context)
            rendered_v = env.from_string(v).render(super_context)
        except Exception as e:
            # Attach key and value which failed the rendering
            e.key = k
            e.value = v
            raise e

        # no change therefore no templatization so pick params from original to retain
        # original type
        if rendered_v == v:
            rendered_mapping[k] = mapping[k]
            continue
        if reverse_json_dumps:
            rendered_v = json.loads(rendered_v)
        rendered_mapping[k] = rendered_v
    LOG.info('Mapping: %s, rendered_mapping: %s, context: %s', mapping,
             rendered_mapping, context)
    return rendered_mapping
Exemple #4
0
def _process(G, name, value):
    '''
    Determines whether parameter is a template or a value. Adds graph nodes and edges accordingly.
    '''
    # Jinja defaults to ascii parser in python 2.x unless you set utf-8 support on per module level
    # Instead we're just assuming every string to be a unicode string
    if isinstance(value, str):
        value = to_unicode(value)

    complex_value_str = None
    if isinstance(value, list) or isinstance(value, dict):
        complex_value_str = str(value)

    is_jinja_expr = (
        jinja_utils.is_jinja_expression(value) or jinja_utils.is_jinja_expression(
            complex_value_str
        )
    )

    if is_jinja_expr:
        G.add_node(name, template=value)

        template_ast = ENV.parse(value)
        LOG.debug('Template ast: %s', template_ast)
        # Dependencies of the node represent jinja variables used in the template
        # We're connecting nodes with an edge for every depencency to traverse them
        # in the right order and also make sure that we don't have missing or cyclic
        # dependencies upfront.
        dependencies = meta.find_undeclared_variables(template_ast)
        LOG.debug('Dependencies: %s', dependencies)
        if dependencies:
            for dependency in dependencies:
                G.add_edge(dependency, name)
    else:
        G.add_node(name, value=value)
Exemple #5
0
def _is_template(template_str):
    template_str = to_unicode(template_str)
    template = Template(template_str)
    try:
        return template_str != template.render({})
    except exceptions.UndefinedError:
        return True
Exemple #6
0
def render_values(mapping=None, context=None, allow_undefined=False):
    """
    Render an incoming mapping using context provided in context using Jinja2. Returns a dict
    containing rendered mapping.

    :param mapping: Input as a dictionary of key value pairs.
    :type mapping: ``dict``

    :param context: Context to be used for dictionary.
    :type context: ``dict``

    :rtype: ``dict``
    """

    if not context or not mapping:
        return mapping

    # Add in special __context variable that provides an easy way to get access to entire context.
    # This mean __context is a reserve key word although backwards compat is preserved by making
    # sure that real context is updated later and therefore will override the __context value.
    super_context = {}
    super_context['__context'] = context
    super_context.update(context)

    env = get_jinja_environment(allow_undefined=allow_undefined)
    rendered_mapping = {}
    for k, v in six.iteritems(mapping):
        # jinja2 works with string so transform list and dict to strings.
        reverse_json_dumps = False
        if isinstance(v, dict) or isinstance(v, list):
            v = json.dumps(v)
            reverse_json_dumps = True
        else:
            # Special case for text type to handle unicode
            if isinstance(v, six.string_types):
                v = to_unicode(v)
            else:
                # Other types (e.g. boolean, etc.)
                v = str(v)

        try:
            LOG.info('Rendering string %s. Super context=%s', v, super_context)
            rendered_v = env.from_string(v).render(super_context)
        except Exception as e:
            # Attach key and value which failed the rendering
            e.key = k
            e.value = v
            raise e

        # no change therefore no templatization so pick params from original to retain
        # original type
        if rendered_v == v:
            rendered_mapping[k] = mapping[k]
            continue
        if reverse_json_dumps:
            rendered_v = json.loads(rendered_v)
        rendered_mapping[k] = rendered_v
    LOG.info('Mapping: %s, rendered_mapping: %s, context: %s', mapping, rendered_mapping, context)
    return rendered_mapping
Exemple #7
0
def _cast_string(x):
    if x is None:
        # Preserve None as-is
        return x

    if not isinstance(x, six.string_types):
        value_type = type(x).__name__
        msg = 'Value "%s" must either be a string or None. Got "%s".' % (x, value_type)
        raise ValueError(msg)

    x = to_unicode(x)
    x = _cast_none(x)
    return x
Exemple #8
0
def _cast_string(x):
    if x is None:
        # Preserve None as-is
        return x

    if not isinstance(x, six.string_types):
        value_type = type(x).__name__
        msg = 'Value "%s" must either be a string or None. Got "%s".' % (x, value_type)
        raise ValueError(msg)

    x = to_unicode(x)
    x = _cast_none(x)
    return x
Exemple #9
0
def _process(G, name, value):
    '''
    Determines whether parameter is a template or a value. Adds graph nodes and edges accordingly.
    '''
    # Jinja defaults to ascii parser in python 2.x unless you set utf-8 support on per module level
    # Instead we're just assuming every string to be a unicode string
    if isinstance(value, str):
        value = to_unicode(value)
    template_ast = ENV.parse(value)
    # Dependencies of the node represent jinja variables used in the template
    # We're connecting nodes with an edge for every depencency to traverse them in the right order
    # and also make sure that we don't have missing or cyclic dependencies upfront.
    dependencies = meta.find_undeclared_variables(template_ast)
    if dependencies:
        G.add_node(name, template=value)
        for dependency in dependencies:
            G.add_edge(dependency, name)
    else:
        G.add_node(name, value=value)
Exemple #10
0
def _process(G, name, value):
    '''
    Determines whether parameter is a template or a value. Adds graph nodes and edges accordingly.
    '''
    # Jinja defaults to ascii parser in python 2.x unless you set utf-8 support on per module level
    # Instead we're just assuming every string to be a unicode string
    if isinstance(value, str):
        value = to_unicode(value)
    template_ast = ENV.parse(value)
    # Dependencies of the node represent jinja variables used in the template
    # We're connecting nodes with an edge for every depencency to traverse them in the right order
    # and also make sure that we don't have missing or cyclic dependencies upfront.
    dependencies = meta.find_undeclared_variables(template_ast)
    if dependencies:
        G.add_node(name, template=value)
        for dependency in dependencies:
            G.add_edge(dependency, name)
    else:
        G.add_node(name, value=value)
Exemple #11
0
def _cast_string(x):
    x = to_unicode(x)
    x = _cast_none(x)
    return x