В Ansible / Jinja есть способ regex_replace строки с целыми числами, используя словарь из k: v пар? - PullRequest
1 голос
/ 13 марта 2020

ПРИМЕЧАНИЕ. Оригинальный вопрос расширен здесь: Есть ли способ в Ansible заменить значение словаря на основе поиска k: v в другом словаре?

У меня есть 3 словаря первые 2 - это k: v со значениями типа string: integer; Мой 3-й словарь - это ak: v строки: строка, которую я хочу l oop через сначала с помощью dict # 1 и заменить k на k: v, а затем то же самое на dict # 2, но заменив v на k: v .

"dict_1": {
    "office-core01": 85,
    "office-core02": 86,
    "office-fw01": 87,
    "office-fw02": 88,
    "office-server-sw01": 91,
    "office-vpn01": 92,
    "office-vpn02": 93
}
"dict_2": {
    "con1": 129,
    "con2": 130,
    "con3": 131,
    "con4": 132,
    "con5": 133,
    "con6": 134,
    "con7": 135,
    "con8": 136,
    "con9": 137
}
"dict_3": {
    "office-core01": "con1", 
    "office-core02": "con2", 
    "office-fw01": "con3", 
    "office-fw02": "con4", 
    "office-server-sw01": "con7", 
    "office-vpn01": "con5", 
    "office-vpn02": "con6"
}

В конце мне нужен словарь из k: v пар целых чисел; Например, в первой итерации мне нужно, чтобы имена хостов / ключи ( office-core01 ) в dict_3 были заменены значением из dict_1 ( 85 ), а затем во 2-й запуск для замены портов / значений. ( con1 ) заменен ключом из dict_2 ( 129 ), однако при использовании кода, предоставленного Владимиром в исходном вопросе, жалуется на object of type 'int' has no len().

Включить задание ( console-portid.yml ):

---
  - name: Replace Console Hostname ID
    set_fact:
      port_mapping: "{{ port_mapping | difference([item]) +
                        [dict(my_value | zip(my_keys))] }}"
    vars:
      my_key: "{{ item.keys() | list }}"
      my_value: "{{ item.values() | list }}"
      my_keys: "{{ my_key | map('regex_replace', port_id.key, port_id.value) | list }}"
    loop: "{{ dict_3 | dict2items }}"

Вызов:

- name: Replace Device Console Ports ID
  include_tasks: console-portid.yml
  loop: "{{ dict_1 | dict2items }}"
  loop_control:
    loop_var: port_id

Ответы [ 2 ]

1 голос
/ 13 марта 2020
---
- hosts: localhost
  gather_facts: no
  tasks:
  - name: Loop over dict_3
    debug:
      msg: "{{ item.key }}: {{ item.value }}"
    with_items: "{{ lookup('dict', dict_3) }}"

  - name: Loop over dict_3 with replacements
    debug:
      msg: "{{ dict_1[item.key] }}: {{ dict_2[item.value] }}"
    with_items: "{{ lookup('dict', dict_3) }}"

  - name: Create new dictionary
    set_fact:
      dict_4: "{{ dict_4|default({}) | combine( {dict_1[item.key]: dict_2[item.value]} ) }}"
    with_items: "{{ lookup('dict', dict_3) }}"

  - name: Show dict_4
    debug:
      var: dict_4
1 голос
/ 13 марта 2020

Q: "Я хочу превратить office-core01: con1 в 85: 129"

A: Приведенная ниже задача выполняет работу

    - set_fact:
        dict_3a: "{{ dict_3a|default({})|
                     combine({dict_1[item.key]: dict_2[item.value]}) }}"
      loop: "{{ dict_3|dict2items }}"
    - debug:
        var: dict_3a

give

    "dict_3a": {
        "85": 129, 
        "86": 130, 
        "87": 131, 
        "88": 132, 
        "91": 135, 
        "92": 133, 
        "93": 134
    }

Q: "Есть ли причина, по которой ключ является строкой, а значение все еще целое?"

A: Внутренний тип переменной сохраняется. Переменные оцениваются как строки, если не настроено DEFAULT_JINJA2_NATIVE . Цитирование "Эта опция сохраняет типы переменных во время операций с шаблоном. Для этого требуется Jinja2> = 2.10."


Q: "Есть причина, по которой ключ является строкой и значение все еще целое число? Ключ всегда должен быть строкой? "

A: На ключи нет ограничений. Цитата из 3.2.1.1. Узлы

"Узел YAML представляет собой одну собственную структуру данных. Такие узлы имеют содержимое одного из трех типов: скаляр, последовательность или отображение. Кроме того, каждый узел имеет тег, который служит для ограничения набора возможных значений, которые может иметь содержимое. "

" Отображение: содержимое узла отображения представляет собой неупорядоченный набор пар узлов ключ: значение, с ограничение, что каждый из ключей является уникальным. YAML не накладывает никаких дополнительных ограничений на узлы. В частности, ключи могут быть произвольными узлами, один и тот же узел может использоваться в качестве значения нескольких пар ключ: значение, и отображение может даже содержать себя в качестве ключа или значения (прямо или косвенно). "

...