如何将列表映射到具有由ansible中的列表项键控的计算值的字典?

时间:2016-11-02 06:51:47

标签: ansible jinja2 ansible-playbook

为尴尬的标题道歉,但我无法想出一个更好的方法来表达看似非常常见的操作:

我有一个像

这样的清单
repos:
- nrser/x
- nrser/y

并希望将其转换为类似

的字典
repos_dict:
  nrser/x: nrser_x
  nrser/y: nrser_y

这在python中非常简单

repos = ['nrser/x', 'nrser/y']
repos_dict = dict((repo, repo.replace('/', '_')) for repo in repos)
# => {'nrser/x': 'nrser_x', 'nrser/y': 'nrser_y'}

但是我无法弄清楚如何使用Ansible / Jinja2完成它(没有通过模块或插件进入python,但这对于这样一个基本用例来说似乎很荒谬)。

很容易将repos映射到带有下划线名称的新列表(我需要在文件路径中使用它们)

set_fact:
  repo_filename_segments: "{{ repos | map('replace', '/', '_') | list }}"

但是我需要将它们压缩在一起,我也找不到对它的支持(参见ziplist1-list2-in-jinja2how-to-combine-two-lists-together

我试过了:

- set_fact:
      repos:
      - beiarea/www
      - beiarea/relib

  - set_fact:
      repos_dict: {}

  - with_items: "{{ repos }}"
    set_fact:
      "repos_dict[{{ item }}]: "{{ item | replace('/', '_') }}"

但这也不起作用。

也许在Ansible / Jinja中不可能,但它似乎是一个被忽视的基本操作。

感谢任何解决方案或建议。

1 个答案:

答案 0 :(得分:3)

Ansible 2.3增加(以及其他)a zip filter

- set_fact:
    repos:
    - beiarea/www
    - beiarea/relib

- set_fact:
    dirnames: "{{ repos | zip(repos|map('replace', '/', '_')) | list }}"

- debug: var=dirnames

# "dirnames": [
#     [
#         "beiarea/www", 
#         "beiarea_www"
#     ], 
#     [
#         "beiarea/relib", 
#         "beiarea_relib"
#     ]
# ]

- debug:
    msg: "{{ item[0] }} => {{ item[1] }}"
  with_items:
  - "{{ dirnames }}" # with_items flattens the first level

我仍在寻找将其转换为字典的好方法,以便于查找。