मेरे पास निम्नलिखित जिन्जा 2 टेम्पलेट है:

[
{% for items in hosts %}
{
    "name":"{{ items.name }}",
    "display_name":"{{ items.display_name }}",
    "services": {{ host_group | from_json | json_query('[*].services[0]') | to_json }},
}
{% endfor %}
]

मुझे सेवाओं[0] को एक चर {{loop.index0 }} से बदलने की जरूरत है, मैंने इस सिंटैक्स की कोशिश की

"services": {{ host_group | from_json | json_query('[*].services[loop.index0]') | to_json }}

लेकिन मुझे एक त्रुटि मिल रही है:

AnsibleFilterError: JMESPathError in json_query filter plugin:
    Expecting: star, got: unquoted_identifier: Parse error at column 13, token "loop" (UNQUOTED_IDENTIFIER), for expression:
    "[*].services[loop.index0]"

मैंने एक और वाक्यविन्यास की कोशिश की:

"services": {{ host_group | from_json | json_query('[*].services[' + {{ loop.index0 }} +']') | to_json }},

और यह भी एक त्रुटि देता है:

AnsibleError: template error while templating string: expected token ':', got '}'. String: [
0
Karim Sad 19 जुलाई 2021, 19:47

2 जवाब

सबसे बढ़िया उत्तर

जिन्जा के साथ काम करते समय दो बातों का ध्यान रखना चाहिए:

  1. आप कभी भी {{...}} टेम्प्लेट मार्करों को नेस्ट नहीं करते हैं।
  2. यदि आप उद्धरणों में कुछ डालते हैं, तो यह एक शाब्दिक स्ट्रिंग है।

तो जब आप लिखते हैं:

json_query('[*].services[loop.index0]')

आप json_query शाब्दिक स्ट्रिंग [*].services[loop.index0] पास कर रहे हैं, जो एक मान्य JMESPath क्वेरी नहीं है। यदि आप एक स्ट्रिंग में एक चर के मान को प्रतिस्थापित करना चाहते हैं, तो आपको या तो स्ट्रिंग को संयोजन के माध्यम से बनाना होगा, या स्ट्रिंग स्वरूपण तर्क का उपयोग करना होगा।

कड़ी

संघनन का उपयोग इस तरह दिख सकता है:

json_query('[*].services[' ~ loop.index0 ` ']')

यहां, ~ स्ट्रिंग कॉन्सटेनेशन ऑपरेटर है - यह + जैसा है, लेकिन यह सब कुछ एक स्ट्रिंग में बदलना सुनिश्चित करता है। इसकी तुलना करें:

ansible localhost -m debug -a 'msg={{ "there are " + 4 + " lights" }}'

इसके लिए:

ansible localhost -m debug -a 'msg={{ "there are " ~ 4 ~ " lights" }}'

स्ट्रिंग स्वरूपण

स्ट्रिंग स्वरूपण का उपयोग इस तरह दिख सकता है:

json_query('[*].services[%s]' % (loop.index0))

या:

json_query('[*].services[{}]'.format(loop.index0))

ये पायथन में उपलब्ध स्ट्रिंग स्वरूपण के दो रूप हैं; अधिक विवरण के लिए, यहां प्रारंभ करें।

1
larsks 19 जुलाई 2021, 22:33

Ansible 2.9.23 का उपयोग करना।

स्ट्रिंग प्लेसहोल्डर्स {} और %s के लिए मुझे बैकटिक्स का उपयोग करना पड़ा, अन्यथा यह काम नहीं करेगा:

json_query('results[?name==`{}`].version'.format(query))
json_query('results[?name==`%s`].version' % (query))

उदाहरण जेसन को देखते हुए:

{
    (...)
    "results": [
        {
            "envra": "0:ntp-4.2.6p5-29.el7_8.2.x86_64",
            "name": "ntp",
            "repo": "installed",
            "epoch": "0",
            "version": "4.2.6p5",
            "release": "29.el7_8.2",
            "yumstate": "installed",
            "arch": "x86_64"
        },
        (...)
    ],
    (...)
}

के द्वारा बनाई गई:

- name: list installed packages
  yum:
    list: installed
  register: installed_list

एक परिभाषित चर query: ntp के साथ, इस चर को json_query में दो तरीकों से पास करें:

- name: pass var to json_query - string formatting (1)
  debug:
    msg: "{{ installed_list|json_query('results[?name==`{}`].version'.format(query))|first }}"

- name: pass var to json_query - string formatting (2)
  debug:
    msg: "{{ installed_list|json_query('results[?name==`%s`].version' % (query))|first }}"

परिणाम:

TASK [pass var to json_query - string formatting (1)] *****************************************************************************************************
ok: [host] => {
    "msg": "4.2.6p5"
}

TASK [pass var to json_query - string formatting (2)] *****************************************************************************************************
ok: [host] => {
    "msg": "4.2.6p5"
}
0
BMC 20 सितंबर 2021, 09:58