带有列表和字典的嵌套循环 [英] Nested loop with a list and a dictionary

查看:257
本文介绍了带有列表和字典的嵌套循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我在一个问题上陷入困境.本质上,我想同时运行一个列表和一个字典的嵌套循环,而我似乎不知道该怎么做.

So I'm sort of stuck on an issue. Essentially, I would like to run a nested loop with both a list and a dictionary, and I can't seem to figure out how.

我的用例正在运行一个剧本,该剧本将通过使用主体列表签名公共密钥来生成SSH证书.

My use case is running a playbook that will generate SSH certificates by signing public keys with a list of principals.

我有一个充当跳转主机的主机(称为bastionHosts的组)列表.这些主机上有最终用户及其SSH密钥对.

I have a list of hosts (group called bastionHosts) that act as jump-hosts. These hosts have end-users and their SSH keypair on them.

[bastionHosts]
10.100.0.10
10.100.0.11

我也有一个有关用户及其SSH主体的词典.字典看起来像这样:

I also have a dictionary of users and their SSH principals. The dictionary looks like this:

users:
   webuser01: "webservers-principal"
   dbuser01: "dbservers-principal"
   webadmin01: "webservers-principal"

我使用提取模块为每个用户下载公共密钥("id_ecdsa.pub".这将创建一个目录结构,如下所示:"/tmp/public_keys/<>/home/<< username> >/.ssh/id_ecdsa.pub

I use the fetch module to download the public keys ("id_ecdsa.pub" for each user. This creates a directory structure that looks like: "/tmp/public_keys/<>/home/<< username>>/.ssh/id_ecdsa.pub

例如,在堡垒10.100.0.10上获取webuser01的公钥会将其放置在ansible主机上的/tmp/public_keys/10.100.0.10/home/webuser01/.ssh/id_ecdsa.pub中.

For example, fetching the public key for webuser01 on bastion 10.100.0.10 would place the key into /tmp/public_keys/10.100.0.10/home/webuser01/.ssh/id_ecdsa.pub on the ansible host.

我的目标是递归到此目录结构中,并使用适当的主体对每个公钥进行签名,但是我不知道该怎么做.

My goal is to recurse down into this directory structure and sign each public key with the appropriate principals, but I can't figure out how to do that.

如果我仅获取一组文件并且是一次扁平获取(即未使用每个主机的目录结构),则下面的代码将起作用. item.key是用户名,item.value是主体集.

The code below would work if I was only fetching one set of files and it was a flat fetch (i.e. the directory structure for each host wasn't used). item.key is the username, and item.value is the set of principals.

 - name: create signed certificates with appropriate principals
   command: ssh-keygen -s /etc/ssh/CA/CA -I {{ item.key }} -n {{ item.value }} -V +1d /tmp/public_keys/{{ item.key }}.pub
   with_dict:
   "{{ users }}"

我还需要一种从内置的 groups.bastionHosts 中指定主机的方法,以便遍历目录结构.以下代码是我要查找的内容的粗略概念可以,但是我找不到找到 with_nested 处理列表和字典的方法.

I need a way to also specify the host from the build-in groups.bastionHosts so that I can traverse the directory structure.The below code is a rough idea of what I'm looking to do, but I can't find a way to get with_nested to work with a list and a dictionary.

- name: create signed certificates with appropriate principals
  command: ssh-keygen -s /etc/ssh/CA/CA -I {{ item.key }} -n {{ item[1].value }} -V +1d /tmp/public_keys/{{ item[0] }}/home/{{ item[1].key }}/.ssh/id_ecdsa.pub
  with_nested:
  - "{{ groups.bastionHosts }}
   - "{{ users }}"

从本质上讲,如果上述方法可行,它将进入每个堡垒主机(item0)和用户(item [1] .key)的每个目录,并使用适当的主体(item [1] .value)对该密钥进行签名. .但是,这不起作用.我收到错误,指出item [1]没有元素值".我想这是因为with_nested应该用于列表,而不是字典.

Essentially, if the above worked, it would walk down into each directory for each bastion host (item0) and user (item[1].key) and sign the key with the appropriate principals (item[1].value). However, this doesn't work. I get errors that item[1] doesn't have an element "value." I imagine this is because with_nested is supposed to work with lists, and not dictionaries.

所以基本上:有没有一种方法可以使with_nested与字典和列表一起使用,这样我既可以引用列表中的元素,又可以引用字典中的项目?如果不是,我是否可能使这一过程变得过于复杂,并且有一种更简单的方法?预先感谢!

So basically: is there a way to get with_nested to work with dictionaries and lists such that I can reference elements of a list while also referencing items within a dictionary? If not, am I perhaps making this too complicated and there's an easier way? Thanks in advance!

推荐答案

有一个hack:您可以使用dictsort过滤器从字典中列出一个列表:

There is a hack out there: you can make a list from dict with dictsort filter:

- hosts: localhost
  gather_facts: no
  vars:
    bastionHosts:
      - 10.100.0.10
      - 10.100.0.11
    users:
       webuser01: "webservers-principal"
       dbuser01: "dbservers-principal"
       webadmin01: "webservers-principal"
  tasks:
    - debug: msg="Host={{item.0}} User.Key={{item.1}} User.Value={{item.2}}"
      with_nested:
        - "{{ bastionHosts }}"
        - "{{ users | dictsort }}"

这篇关于带有列表和字典的嵌套循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆