Render a field found under the ``field`` level of the hierarchy in the
    ``dictionary`` object.
    This is useful to render a field in a Jinja template without worrying that
    the hierarchy might not exist. For example if we do the following in Jinja:
    ``{{ interfaces.interface.Ethernet5.config.description }}`` for the
    following object:
    ``{'interfaces': {'interface': {'Ethernet1': {'config': {'enabled': True}}}}}``
    it would error, as the ``Ethernet5`` key does not exist.
    With this helper, we can skip this and avoid existence checks. This must be
    however used with care.

    dictionary
        The dictionary to traverse.

    field
        The key name or part to traverse in the ``dictionary``.

    prepend: ``None``
        The text to prepend in front of the text. Usually, we need to have the
        name of the field too when generating the configuration.

    append: ``None``
        Text to append at the end.

    quotes: ``False``
        Whether should wrap the text around quotes.

    CLI Example:

    .. code-block:: bash

        salt '*' napalm_formula.render_field "{'enabled': True}" enabled
        # This would return the value of the ``enabled`` leaf key
        salt '*' napalm_formula.render_field "{'enabled': True}" description
        # This would not error

    Jinja usage example:

    .. code-block:: jinja

        {%- set config = {'enabled': True, 'description': 'Interface description'} %}
        {{ salt.napalm_formula.render_field(config, 'description', quotes=True) }}

    The example above would be rendered on Arista / Cisco as:

    .. code-block:: text

        description "Interface description"

    While on Junos (the semicolon is important to be added, otherwise the
    configuration won't be accepted by Junos):

    .. code-block:: text

        description "Interface description";

def render_field(dictionary,
                 field,
                 prepend=None,
                 append=None,
                 quotes=False,
                 **opts):
    '''
    Render a field found under the ``field`` level of the hierarchy in the
    ``dictionary`` object.
    This is useful to render a field in a Jinja template without worrying that
    the hierarchy might not exist. For example if we do the following in Jinja:
    ``{{ interfaces.interface.Ethernet5.config.description }}`` for the
    following object:
    ``{'interfaces': {'interface': {'Ethernet1': {'config': {'enabled': True}}}}}``
    it would error, as the ``Ethernet5`` key does not exist.
    With this helper, we can skip this and avoid existence checks. This must be
    however used with care.

    dictionary
        The dictionary to traverse.

    field
        The key name or part to traverse in the ``dictionary``.

    prepend: ``None``
        The text to prepend in front of the text. Usually, we need to have the
        name of the field too when generating the configuration.

    append: ``None``
        Text to append at the end.

    quotes: ``False``
        Whether should wrap the text around quotes.

    CLI Example:

    .. code-block:: bash

        salt '*' napalm_formula.render_field "{'enabled': True}" enabled
        # This would return the value of the ``enabled`` leaf key
        salt '*' napalm_formula.render_field "{'enabled': True}" description
        # This would not error

    Jinja usage example:

    .. code-block:: jinja

        {%- set config = {'enabled': True, 'description': 'Interface description'} %}
        {{ salt.napalm_formula.render_field(config, 'description', quotes=True) }}

    The example above would be rendered on Arista / Cisco as:

    .. code-block:: text

        description "Interface description"

    While on Junos (the semicolon is important to be added, otherwise the
    configuration won't be accepted by Junos):

    .. code-block:: text

        description "Interface description";
    '''
    value = traverse(dictionary, field)
    if value is None:
        return ''
    if prepend is None:
        prepend = field.replace('_', '-')
    if append is None:
        if __grains__['os'] in ('junos',):
            append = ';'
        else:
            append = ''
    if quotes:
        value = '"{value}"'.format(value=value)
    return '{prepend} {value}{append}'.format(prepend=prepend,
                                              value=value,
                                              append=append)