使用列表迭代哈希

Iterate over hash with lists

我想为用户设置几个 ssh public 密钥,今天我有一些东西已经可以只设置一个密钥:

users:
  user1:
    comment: "User 1"
    sshkey: "ssh-rsa ******** user1"
    state: present

  user2:
    comment: "User 2"
    sshkey: "ssh-rsa ******** user2"
    state: present

  user3:
    comment: "User 3"
    sshkey: "ssh-rsa ******** user3"
    state: present

我的玩法是:

- name: set authorized_keys
  ansible.posix.authorized_key:
    user:  "{{ item.key }}"
    state: "{{ item.value.state }}"
    key: "{{ item.value.sshkey }}"
  with_dict: "{{ users }}"
  when: item.value.state == "present" and item.value.sshkey is defined

我希望能够在我的 users var 中为一个用户传递多个密钥,例如:

users:
  user1:
    comment: "User 1"
    sshkeys:
      - ssh-rsa ******** user1.key
    state: present

  user2:
    comment: "User 2"
    sshkeys:
      - ssh-rsa ******** user2.key-a
      - ssh-rsa ******** user2.key-b
    state: present

  user3:
    comment: "User 3"
    sshkeys:
      - ssh-rsa ******** user2.key-a
      - ssh-rsa ******** user2.key-b
      - ssh-rsa ******** user3.key-c
    state: present

但我不知道应该如何遍历这个 sshkeys 列表

在示例中,您测试 sshkeys 属性是否存在。我认为这是因为字典中可能缺少此属性。让我们从 user3 中删除此属性以进行测试

    users:
      user1:
        comment: User 1
        sshkeys:
          - ssh-rsa ******** user1.key
        state: present
      user2:
        comment: User 2
        sshkeys:
          - ssh-rsa ******** user2.key-a
          - ssh-rsa ******** user2.key-b
        state: present
      user3:
        comment: User 3
        state: present

问:“我应该如何遍历这个 sshkeys 列表?

A1: 没有必要迭代 sshkeys 列表。可以一步配置它们。引用自 exclusive:

Multiple keys can be specified in a single key string value by separating them by newlines.

例如

    - debug:
        msg: |-
          user: {{ item.key }}
          state: {{ item.value.state }}
          key: {{ item.value.sshkeys|join('\n') }}
      loop: "{{ users|dict2items }}"
      when:
        - item.value.state == 'present'
        - item.value.sshkeys|d([])|length > 0

给出(删节)

  msg: |-
    user: user1
    state: present
    key: ssh-rsa ******** user1.key
  msg: |-
    user: user2
    state: present
    key: ssh-rsa ******** user2.key-a\nssh-rsa ******** user2.key-b

如果要迭代键,请继续下一个选项。


A2: 第一步添加属性 sshkeys if missing

    - set_fact:
        users: "{{ dict(_keys|zip(_vals_update)) }}"
      vars:
        _keys: "{{ users.keys()|list }}"
        _vals: "{{ users.values()|list }}"
        _vals_update: "{{ [{'sshkeys': []}]|
                          product(_vals)|
                          map('combine')|list }}"

给予

  users:
    user1:
      comment: User 1
      sshkeys:
      - ssh-rsa ******** user1.key
      state: present
    user2:
      comment: User 2
      sshkeys:
      - ssh-rsa ******** user2.key-a
      - ssh-rsa ******** user2.key-b
      state: present
    user3:
      comment: User 3
      sshkeys: []
      state: present

现在,用子元素迭代字典

    - debug:
        msg: >-
          user: {{ item.0.key }}
          state: {{ item.0.value.state }}
          key: {{ item.1 }}
      with_subelements:
        - "{{ users|dict2items }}"
        - value.sshkeys
      when: item.0.value.state == 'present'

给出(删节)

  msg: 'user: user1 state: present key: ssh-rsa ******** user1.key'
  msg: 'user: user2 state: present key: ssh-rsa ******** user2.key-a'
  msg: 'user: user2 state: present key: ssh-rsa ******** user2.key-b'