From 476d1f818e4ec0402568946b3c7514179a29b7d7 Mon Sep 17 00:00:00 2001 From: Matt Martz Date: Wed, 25 Apr 2018 12:55:34 -0500 Subject: [PATCH] Documentation for query/q. Fixes #38275 (#38558) --- docs/docsite/rst/plugins/lookup.rst | 24 ++++++++++++++++++ .../rst/user_guide/playbooks_conditionals.rst | 4 +-- .../rst/user_guide/playbooks_loops.rst | 25 ++++++++++++++++--- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/docs/docsite/rst/plugins/lookup.rst b/docs/docsite/rst/plugins/lookup.rst index 5c61d203323..240a6bc9c03 100644 --- a/docs/docsite/rst/plugins/lookup.rst +++ b/docs/docsite/rst/plugins/lookup.rst @@ -65,6 +65,30 @@ You can combine lookups with :ref:`playbooks_filters`, :ref:`playbooks_tests` an - "{{lookup('sequence', 'end=42 start=2 step=2')|map('log', 4)|list)}}" - ['a', 'c', 'd', 'c'] +.. _query: + +query ++++++ + +.. versionadded:: 2.5 + +In Ansible 2.5, a new jinja2 function called ``query`` was added for invoking lookup plugins. The difference between ``lookup`` and ``query`` is largely that ``query`` will always return a list. +The default behavior of ``lookup`` is to return a string of comma separated values. ``lookup`` can be explicitly configured to return a list using ``wantlist=True``. + +This was done primarily to provide an easier and more consistent interface for interacting with the new ``loop`` keyword, while maintaining backwards compatibiltiy with other uses of ``lookup``. + +The following examples are equivalent:: + + lookup('dict', dict_variable, wantlist=True) + + query('dict', dict_variable) + +As demonstrated above the behavior of ``wantlist=True`` is implicit when using ``query``. + +Additionally, ``q`` was introduced as a shortform of ``query``:: + + q('dict', dict_variable) + .. _lookup_plugins_list: diff --git a/docs/docsite/rst/user_guide/playbooks_conditionals.rst b/docs/docsite/rst/user_guide/playbooks_conditionals.rst index 49fb6597144..97e738be31d 100644 --- a/docs/docsite/rst/user_guide/playbooks_conditionals.rst +++ b/docs/docsite/rst/user_guide/playbooks_conditionals.rst @@ -134,7 +134,7 @@ If you need to skip the whole task depending on the loop variable being defined, If using a dict in a loop:: - command: echo {{ item.key }} - loop: "{{ lookup('dict', mydict|default({})) }}" + loop: "{{ query('dict', mydict|default({})) }}" when: item.value > 5 .. _loading_in_custom_facts: @@ -251,7 +251,7 @@ The following example shows how to template out a configuration file that was ve template: src: "{{ item }}" dest: /etc/myapp/foo.conf - loop: "{{lookup('first_found', { 'files': myfiles, 'paths': mypaths})}}" + loop: "{{ query('first_found', { 'files': myfiles, 'paths': mypaths}) }}" vars: myfiles: - "{{ansible_distribution}}.conf" diff --git a/docs/docsite/rst/user_guide/playbooks_loops.rst b/docs/docsite/rst/user_guide/playbooks_loops.rst index a9d5f72b80c..b1e7f8271d5 100644 --- a/docs/docsite/rst/user_guide/playbooks_loops.rst +++ b/docs/docsite/rst/user_guide/playbooks_loops.rst @@ -80,7 +80,7 @@ To loop over a dict, use the ``dict2items`` :ref:`dict_filter`:: - name: create a tag dictionary of non-empty tags set_fact: tags_dict: "{{ (tags_dict|default({}))|combine({item.key: item.value}) }}" - with_items: "{{ tags|dict2items }}" + loop: "{{ tags|dict2items }}" vars: tags: Environment: dev @@ -105,10 +105,27 @@ For example, using the 'nested' lookup, you can combine lists:: priv: "{{ item[1] }}.*:ALL" append_privs: yes password: "foo" - loop: "{{ lookup('nested', [ 'alice', 'bob' ], [ 'clientdb', 'employeedb', 'providerdb' ]) }}" + loop: "{{ query('nested', [ 'alice', 'bob' ], [ 'clientdb', 'employeedb', 'providerdb' ]) }}" .. note:: ``with_`` loops are actually a combination of things ``with_`` + ``lookup()``, even ``items`` is a lookup. ``loop`` can be used in the same way as shown above. + +Using lookup vs query with loop +``````````````````````````````` + +In Ansible 2.5 a new jinja2 function was introduced named :ref:`query`, that offers several benefits over ``lookup`` when using the new ``loop`` keyword. + +This is described more in the lookup documentation, however, ``query`` provides a more simple interface and a more predictable output from lookup plugins, ensuring better compatibility with ``loop``. + +In certain situations the ``lookup`` function may not return a list which ``loop`` requires. + +The following invocations are equivalent, using ``wantlist=True`` with ``lookup`` to ensure a return type of a list:: + + loop: "{{ query('nested', ['alice', 'bob'], ['clientdb', 'employeedb', 'providerdb']) }}" + + loop: "{{ lookup('nested', ['alice', 'bob'], ['clientdb', 'employeedb', 'providerdb'], wantlist=True) }}" + + .. _do_until_loops: Do-Until Loops @@ -224,12 +241,12 @@ There is also a specific lookup plugin ``inventory_hostnames`` that can be used # show all the hosts in the inventory - debug: msg: "{{ item }}" - loop: "{{ lookup('inventory_hostnames', 'all') }}" + loop: "{{ query('inventory_hostnames', 'all') }}" # show all the hosts matching the pattern, ie all but the group www - debug: msg: "{{ item }}" - loop: "{{ lookup('inventory_hostnames', 'all!www') }}" + loop: "{{ query('inventory_hostnames', 'all!www') }}" More information on the patterns can be found on :doc:`intro_patterns`