defaults.update
        Allows to set defaults for group of data set e.g. group for nodes.

        This function is a combination of defaults.merge
        and defaults.deepcopy to avoid redundant in jinja.

        Example:

        .. code-block:: yaml

            group01:
              defaults:
                enabled: True
                extra:
                  - test
                  - stage
              nodes:
                host01:
                  index: foo
                  upstream: bar
                host02:
                  index: foo2
                  upstream: bar2

        .. code-block:: jinja

            {% do salt['defaults.update'](group01.nodes, group01.defaults) %}

        Each node will look like the following:

        .. code-block:: yaml

            host01:
              enabled: True
              index: foo
              upstream: bar
              extra:
                - test
                - stage

    merge_lists : True
        If True, it will also merge lists instead of replace their items.

    in_place : True
        If True, it will merge into dest dict.
        if not it will make a new copy from that dict and return it.

    It is more typical to use this in a templating language in formulas,
    instead of directly on the command-line.

def update(dest, defaults, merge_lists=True, in_place=True):
    '''
    defaults.update
        Allows to set defaults for group of data set e.g. group for nodes.

        This function is a combination of defaults.merge
        and defaults.deepcopy to avoid redundant in jinja.

        Example:

        .. code-block:: yaml

            group01:
              defaults:
                enabled: True
                extra:
                  - test
                  - stage
              nodes:
                host01:
                  index: foo
                  upstream: bar
                host02:
                  index: foo2
                  upstream: bar2

        .. code-block:: jinja

            {% do salt['defaults.update'](group01.nodes, group01.defaults) %}

        Each node will look like the following:

        .. code-block:: yaml

            host01:
              enabled: True
              index: foo
              upstream: bar
              extra:
                - test
                - stage

    merge_lists : True
        If True, it will also merge lists instead of replace their items.

    in_place : True
        If True, it will merge into dest dict.
        if not it will make a new copy from that dict and return it.

    It is more typical to use this in a templating language in formulas,
    instead of directly on the command-line.
    '''

    if in_place:
        nodes = dest
    else:
        nodes = deepcopy(dest)

    for node_name, node_vars in nodes.items():
        defaults_vars = deepcopy(defaults)
        node_vars = merge(defaults_vars, node_vars, merge_lists=merge_lists)
        nodes[node_name] = node_vars

    return nodes