सूची में शामिल करने या Ansible में शब्दकोशों में कुंजियाँ जोड़ने के लिए


34

( कॉलबैक या हुक से संबंधित और कार्यों की पुन: प्रयोज्य श्रृंखला, उत्तर देने योग्य भूमिकाओं में ):

वहाँ एक सूची में संलग्न करने के लिए या jina2 टेम्पलेट अभिव्यक्ति का उपयोग करके (ab) से Ansible में एक शब्दकोश में एक कुंजी जोड़ने के लिए कोई बेहतर तरीका है?

मुझे पता है आप कुछ ऐसा कर सकते हैं:

- name: this is a hack
  shell: echo "{% originalvar.append('x') %}New value of originalvar is {{originalvar}}"

लेकिन क्या वास्तव में ऐसा करने के लिए मेटा कार्य या सहायक का कोई प्रकार नहीं है?

यह नाजुक लगता है, अनिर्दिष्ट लगता है, और यह अंसबल में चर कैसे काम करता है, इसके बारे में बहुत सारी धारणाओं पर निर्भर करता है।

मेरा उपयोग मामला कई भूमिकाओं (डेटाबेस सर्वर एक्सटेंशन) है जो प्रत्येक को आधार भूमिका (डेटाबेस सर्वर) के लिए कुछ कॉन्फ़िगरेशन की आपूर्ति करने की आवश्यकता है। यह db सर्वर कॉन्‍फ़िगर फ़ाइल की एक पंक्ति को जोड़ने जैसा सरल नहीं है; प्रत्येक परिवर्तन एक ही पंक्ति पर लागू होता है , उदाहरण के लिए एक्सटेंशन bdrऔर pg_stat_statementsलक्ष्य रेखा पर दोनों प्रदर्शित होने चाहिए:

shared_preload_libaries = 'bdr, pg_stat_statements'

क्या ऐसा करने का तरीका सिर्फ एक बार फिर से रेक्सक्स के साथ कई बार फाइल को संसाधित करने के लिए है, जो वर्तमान मूल्य को निकालता है, इसे पार्स करता है, और फिर इसे फिर से लिखता है? यदि ऐसा है, तो आप कई रनों के पार कैसे बना सकते हैं?

यदि पार्स करने के लिए यह विन्यास कठिन है तो क्या होगा और यह किसी अन्य अल्पविराम से अलग मूल्य के रूप में सरल नहीं है? XML config फ़ाइलों के बारे में सोचो।


Y'know क्या? मुझे आपके साइड-इफ़ेक्ट-
फ़ुल

जवाबों:


13

आप एक चर में दो सूचियों को मिला सकते हैं +। कहो कि आपके पास group_varsइस सामग्री के साथ एक फ़ाइल है:

---
# group_vars/all
pgsql_extensions:
  - ext1
  - ext2
  - ext3

और इसका उपयोग टेम्पलेट में किया जाता है pgsql.conf.j2जैसे:

# {{ ansible_managed }}
pgsql_extensions={% for item in pgsql_extensions %}{{ item }}, {% endfor %}

आप इस तरह परीक्षण डेटाबेस सर्वर के लिए एक्सटेंशन संलग्न कर सकते हैं:

---
# group_vars/testing_db
append_exts:
  - ext4
  - ext5
pgsql_extensions: "{{ pgsql_extensions + append_exts }}"

जब परीक्षण के किसी भी सर्वर में भूमिका निभाई जाती है, तो सशर्त एक्सटेंशन जोड़ दिए जाएंगे।

मुझे यकीन नहीं है कि यह शब्दकोशों के लिए भी काम करता है, और रिक्त स्थान के साथ भी सावधान रहना चाहिए और लाइन के अंत में एक झूलता हुआ अल्पविराम छोड़ना चाहिए।


आप कर सकते हैं, लेकिन आपको यह सब करना होगा group_vars, भूमिकाएं स्वयं एक्सटेंशन स्थापित करने के विवरण का ध्यान नहीं रख सकती हैं। यह उन भूमिकाओं से भिन्न है, जिन्हें मैं विशेष रूप से ढूंढ रहा हूं, इसलिए एक भूमिका किसी अन्य भूमिका द्वारा उजागर किए गए संस्करण में संलग्न हो सकती है।
क्रेग रिंगर

क्या आपकी आधार भूमिका प्रत्येक विस्तार भूमिका के बारे में जानती है? मेरे पास एक ऐसा ही मामला है जहां मैं with_itemsसजा को एक वाक्य तक छोड़ने में सक्षम था ।
GnP

नहीं, और यह वास्तव में मुद्दा है। एक तैनाती में आधार की भूमिका अल
क्रेग रिंगर

4
ऐसा लगता है कि यदि आप दो सूचियों को संक्षिप्त करने के लिए ऐसा करने की कोशिश करते हैं, तो यह सोचता है कि यह एक असीम रूप से पुनरावर्ती टेम्पलेट है क्योंकि बाएं हाथ की तरफ भी दाहिने हाथ की तरफ है। क्या मैं गलत समझ रहा हूं कि इसका उपयोग कैसे किया जाए?
इब्राहिम

2
@spectras कम से कम Ansible 2.7 के रूप में यह काम नहीं करता है। जैसा कि इब्राहिम ने सुझाव दिया था, यह एक त्रुटि का कारण बनता है: "टेम्पलेट स्ट्रिंग में पाया गया पुनरावर्ती लूप"।
rluba

35

चूंकि Ansible v2.x आप ये कर सकते हैं:

# use case I: appending to LIST variable:

      - name: my appender
        set_fact:
          my_list_var: '{{my_list_myvar + new_items_list}}'

# use case II: appending to LIST variable one by one:

      - name: my appender
        set_fact:
          my_list_var: '{{my_list_var + [item]}}'
        with_items: '{{my_new_items|list}}'

# use case III: appending more keys DICT variable in a "batch":

      - name: my appender
        set_fact:
          my_dict_var: '{{my_dict_var|combine(my_new_keys_in_a_dict)}}'

# use case IV: appending keys DICT variable one by one from tuples
      - name: setup list of tuples (for 2.4.x and up
        set_fact:
          lot: >
            [('key1', 'value1',), ('key2', 'value2',), ..., ('keyN', 'valueN',)],
      - name: my appender
        set_fact:
          my_dict_var: '{{my_dict_var|combine({item[0]: item[1]})}}'
        with_items: '{{lot}}'
# use case V: appending keys DICT variable one by one from list of dicts (thanks to @ssc)

  - name: add new key / value pairs to dict
    set_fact:
      my_dict_var: "{{ my_dict_var | combine({item.key: item.value}) }}"
    with_items:
    - { key: 'key01', value: 'value 01' }
    - { key: 'key02', value: 'value 03' }
    - { key: 'key03', value: 'value 04' }

उपरोक्त सभी में प्रलेखित है: http://docs.ansible.com/ansible/playbooks_filters.html


1
केस IV का उपयोग करेंu'(': u\"'\"}"
ssc

1
धन्यवाद, @ssc। मैंने देखा कि यह ansible 2.4.x(FIXED) के साथ काम नहीं कर रहा है
मैक्स कोगन

usecase # 4 के अनुसार, मैंने अपने परिदृश्य में अपरिभाषित त्रुटि को संभालने के लिए डिफ़ॉल्ट मान जोड़ा है set_fact: my_dict_var: '{{my_dict_var|default({})|combine({item[0]: item[1]})}}':। अपरिभाषित त्रुटि तब आती है जब कुछ फ़िल्टरिंग का उपयोग किया जाता है या कोई परिणाम पंजीकृत नहीं होता है।
एसके वेंकट

श्री एसके वेंकट, यहां का नमूना कोड केवल बहुत विशिष्ट बात (टुपल्स से शब्दकोश आइटम जोड़ना) को प्रदर्शित करता है। यदि आपको कुछ और करने की आवश्यकता है, तो यह कोड आपकी कॉपी-पेस्ट नहीं है।
मैक्स कोगन

3

आपको लूप को 2 में विभाजित करने की आवश्यकता है

--- 
- मेजबान: लोकलहोस्ट
  कार्य: 
    - शामिल_वार: ढेर
    - set_facts: रोल्स = {{stacks.Roles | विभाजित करें(' ')}}
    - शामिल करें: addhost.yml
      with_items: "{{भूमिकाएँ}}"

और addhost.yml

- set_facts: groupname = {{आइटम}}
- set_facts: ips = {{ढेर [आइटम] | विभाजन ('')}
- local_action: add_host hostname = {{item}} groupname = {{groupname}}
  with_items: {{ips}}

1

यकीन नहीं है कि जब उन्होंने इसे जोड़ा था, लेकिन कम से कम शब्दकोशों / हैश (सूचियों / सरणियों के लिए नहीं) में, आप चर hash_behaviour सेट कर सकते हैं , जैसे: hash_behaviour = mergeआपके में ansible.cfg

मुझे इस सेटिंग पर गलती से ठोकर खाने में कुछ घंटे लग गए: एस


यह बहुत आसान है, लेकिन मौजूदा कोडबेस पर इसे e2e सक्षम करने के लिए सावधान रहें। कुछ अंडे तोड़ सकते हैं।
मैक्स कोगन

0

यहां लगभग सभी उत्तरों को कार्यों में बदलाव की आवश्यकता होती है, लेकिन मुझे वार्निश परिभाषा में गतिशील रूप से मर्ज करने की आवश्यकता थी, रन के दौरान नहीं।

उदाहरण के लिए मैं में कुछ साझा वार्स परिभाषित करना चाहते हैं all group_varsऔर फिर मैं उन्हें कुछ अन्य में विस्तार करना चाहते groupया host_vars। भूमिकाओं के लिए काम करते समय बहुत उपयोगी।

यदि आप var फ़ाइलों में मूल चर को अधिलेखित करने के लिए combineया unionफ़िल्टर का उपयोग करने का प्रयास करते हैं , तो आप templating के दौरान अनंत लूप में समाप्त हो जाएंगे, इसलिए मैंने यह वर्कअराउंड (इसका समाधान नहीं है) बनाया।

आप कुछ नाम पैटर्न के आधार पर कई चर को परिभाषित कर सकते हैं और फिर स्वचालित रूप से उन्हें भूमिका में लोड कर सकते हैं।

group_vars/all.yml

dictionary_of_bla:
  - name: blabla
    value1 : blabla
    value2 : blabla

group_vars/group1.yml

dictionary_of_bla_group1:
  - name: blabla2
    value1 : blabla2
    value2 : blabla2

भूमिका कोड स्निपेट

tasks:
  - name: Run for all dictionary_of_bla.* variations
    include_tasks: do_some_stuff.yml
    with_items: "{{ lookup('varnames','dictionary_of_bla.*').split(',') }}"
    loop_control:
      loop_var: _dictionary_of_bla

do_some_stuff.yml

- name: do magic
  magic:
    trick_name: item.name
    trick_value1: item.value1
    trick_value2: item.value2
  with_items: "{{ vars[_dictionary_of_bla] }}"

यह सिर्फ एक स्निपेट है, लेकिन आपको यह विचार करना चाहिए कि यह कैसे काम करता है। नोट: लुकअप ('वर्णनाम', '') ansible 2.8 के बाद से उपलब्ध है

मुझे लगता है dictionary_of_bla.*कि रनवे के दौरान सभी वेरिएबल्स को एक ही शब्दकोष में मर्ज करना भी संभव होगा ।

इस दृष्टिकोण का लाभ यह है कि आपको चर नामों की सटीक सूची सेट करने की आवश्यकता नहीं है, लेकिन केवल पैटर्न और उपयोगकर्ता इसे गतिशील रूप से सेट कर सकते हैं।


-4

Ansibleएक स्वचालन प्रणाली है, और, कॉन्फ़िगरेशन फ़ाइल प्रबंधन के विषय में, यह बहुत अलग नहीं है apt। अधिक से अधिक सॉफ्टवेयर एक conf.dनिर्देशिका से कॉन्फ़िगरेशन स्निपेट पढ़ने की सुविधा प्रदान करता है, इस तरह के स्वचालन सिस्टम को विभिन्न पैकेजों / भूमिकाओं को जोड़ने के लिए सक्षम बनाता है सॉफ्टवेयर में कॉन्फ़िगरेशन। मेरा मानना ​​है कि यह Ansibleआपके मन में जो कुछ भी है, उसे करने के लिए नहीं बल्कि conf.dचाल का उपयोग करने का दर्शन है । यदि कॉन्फ़िगर किया जा रहा सॉफ़्टवेयर इस कार्यक्षमता की पेशकश नहीं करता है, तो आप मुश्किल में पड़ सकते हैं।

चूँकि आप XML विन्यास फाइल का उल्लेख करते हैं, इसलिए मैं कुछ आवभगत करने का अवसर लेता हूँ। सादे पाठ कॉन्फ़िगरेशन फ़ाइलों का उपयोग करने की यूनिक्स परंपरा का एक कारण है। बाइनरी कॉन्फ़िगरेशन फाइलें स्वयं को सिस्टम स्वचालन के लिए अच्छी तरह से उधार नहीं देती हैं, इसलिए किसी भी प्रकार के द्विआधारी प्रारूप आपको परेशानी देगा और संभवतः आपको कॉन्फ़िगरेशन को संभालने के लिए एक कार्यक्रम बनाने की आवश्यकता होगी। (यदि किसी को लगता है कि XML एक सादा पाठ प्रारूप है, तो उन्हें अपने दिमाग की जांच करानी चाहिए।)

अब, अपनी विशिष्ट PostgreSQLसमस्या पर। चाल का PostgreSQLसमर्थन करता है conf.d। सबसे पहले, मैं जाँच करूँगा कि क्या shared_preload_librariesकई बार निर्दिष्ट किया जा सकता है। मुझे दस्तावेज़ीकरण में ऐसा कोई संकेत नहीं मिला जो यह कर सकता हो, लेकिन मैं फिर भी इसे आज़माऊंगा। यदि यह कई बार निर्दिष्ट नहीं किया जा सकता है, तो मैं अपनी समस्या PostgreSQLलोगों को समझाऊंगा यदि उनके पास विचार हैं; यह एक PostgreSQLमुद्दा है और एक मुद्दा नहीं है Ansible। अगर कोई समाधान नहीं है और मैं वास्तव में विभिन्न भूमिकाओं को एक में नहीं मिला सकता हूं, तो मैं प्रबंधित होस्ट पर कॉन्फ़िगरेशन को संकलित करने के लिए एक प्रणाली लागू करूंगा। इस मामले में, मैं शायद एक स्क्रिप्ट बना सकते हैं /usr/local/sbin/update_postgresql_configजो संकलन होगा /etc/postgresql/postgresql.conf.jinjaमें /etc/postgresql/9.x/main/postgresql.conf। स्क्रिप्ट साझा प्रीलोड पुस्तकालयों से /etc/postgresql/shared_preload_libraries.txt, प्रति पंक्ति एक पुस्तकालय, और उन्हें जिन्जा प्रदान करेगी।

स्वचालन प्रणालियों के लिए ऐसा करना असामान्य नहीं है। एक उदाहरण डेबियन exim4पैकेज है।


PostgreSQL एक conf.dशामिल तंत्र का समर्थन करता है और शुक्र है कि सादा फ़ाइलों का उपयोग करता है। हालांकि, कुछ कॉन्फ़िगरेशन विकल्प हैं जहां कई एक्सटेंशन के बारे में राय हो सकती है - जैसे "इससे पहले कि जो कुछ भी था, उससे max_wal_senders 10 बढ़ाएं"।
क्रेग रिंगर

4
ऐसा लगता है कि आप कह रहे हैं कि कॉन्फ़िगरेशन प्रबंधन प्रणाली में सीमाओं के आसपास काम करने के लिए एप्लिकेशन को बदल दिया जाना चाहिए, या मुझे पुन: प्रयोज्य भूमिका निभाने पर छोड़ देना चाहिए।
क्रेग रिंगर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.