【问题标题】:Ansible + Jinja2 Loop - Dict object has no attributeAnsible + Jinja2 Loop - Dict 对象没有属性
【发布时间】:2021-08-06 17:17:59
【问题描述】:

我在这里疯了,但我似乎看不出我的问题出在哪里!我试图让 ansible 在 Cisco ASA 上创建我的用户,并且我正在使用 Jinja 2 模板。

我有一个主机 vars 文件,我在其中指定用户(敏感数据):

users:
  tom:
    sshkey: "xxxx"
    privilegelevel: 15
  dick:
    sshkey: "xxxx"
    privilegelevel: 15
  harry:
    password: "yyyy"
    privilegelevel: 15

我用于创建用户的模板 (users.j2):

{% if users is defined %}
{% for user, value in users.items() %}
username {{ value }} privilege {{ value.privilegelevel }}
{% endfor %}
{% endif %}

如果他们有 ssh 密钥(users-ssh.j2):

{% if users and 'sshkey' is defined %}
{% for user, value in users.items() %}
username {{ value }} privilege {{ value.privilegelevel }}
username {{ value }} attributes
  ssh authentication publickey {{ value.sshkey }}
{% endfor %}
{% endif %}

最后但并非最不重要的是剧本:

- name: create users
  asa_config:
    src: templates/users.j2
    provider: "{{ cli }}"
    save: yes
  tags: users

- name: create ssh pubkey auth
  asa_config:
    src: templates/users-ssh.j2
    provider: "{{ cli }}"
    save: yes
  tags: users

运行 playbook 时,user.j2 工作正常,但 user-ssh.j2 失败:

fatal: [HOSTNAME_HERE]: FAILED! => {"changed": false, "msg": "'dict object' has no attribute 'sshkey'"}

当调用 dict 值时:

- name: Output dict
  debug:
    msg: "User is {{ item.key }} and the ssh key is {{ item.value.sshkey }}"
  loop: "{{ lookup('dict', users) }}"
  tags: users

它给了我正确的值:

ok: [fw01.prd.sc1] => (item={'key': 'tom', 'value': {'sshkey': 'xxxx', 'privilegelevel': 15}}) => {
    "msg": "User is tom and the ssh key is xxxx"
}
ok: [fw01.prd.sc1] => (item={'key': 'dick', 'value': {'sshkey': 'xxxx', 'privilegelevel': 15}}) => {
    "msg": "User is dick and the ssh key is xxxx"
}

任何人都可以看到我的 J2 模板可能出了什么问题,因为我做了很多事情但一无所获!

提前非常感谢:)

克里斯

【问题讨论】:

    标签: python ansible jinja2 cisco asa


    【解决方案1】:

    这个循环...

    {% if users and 'sshkey' is defined %}
    {% for user, value in users.items() %}
    username {{ value }} privilege {{ value.privilegelevel }}
    username {{ value }} attributes
      ssh authentication publickey {{ value.sshkey }}
    {% endfor %}
    {% endif %}
    

    ...不检查用户是否具有sshkey 属性。表达式if users and 'sshkey' is defined 与写作if users 相同,因为表达式if 'sshkey' is defined 将始终为true -- 'sshkey' 是文字字符串,而不是变量。

    由于循环为所有用户运行,当您到达harry 时它会失败,因为harry 没有sshkey 属性。

    您需要过滤具有sshkey 属性的用户,例如使用in the documentation 所述的循环过滤:

    {% for user, value in users.items() if value.sshkey is defined %}
    username {{ user }} privilege {{ value.privilegelevel }}
    username {{ user }} attributes
      ssh authentication publickey {{ value.sshkey }}
    {% endfor %}
    

    请注意,我还将 username {{ value }} 替换为 username {{ user }},因为我有理由确定前者不是您的意思。


    例如,这个剧本:

    - hosts: localhost
      gather_facts: false
      vars:
        users:
          tom:
            sshkey: "xxxx"
            privilegelevel: 15
          dick:
            sshkey: "xxxx"
            privilegelevel: 15
          harry:
            password: "yyyy"
            privilegelevel: 15
    
      tasks:
        - copy:
            dest: users.txt
            content: |
              {% for user, value in users.items() if value.sshkey is defined %}
              username {{ user }} privilege {{ value.privilegelevel }}
              username {{ user }} attributes
                ssh authentication publickey {{ value.sshkey }}
              {% endfor %}
    

    users.txt 中作为输出生成:

    username tom privilege 15
    username tom attributes
      ssh authentication publickey xxxx
    username dick privilege 15
    username dick attributes
      ssh authentication publickey xxxx
    

    【讨论】:

    • 这确实是我输入 {{ value }} 时的意思!好吧,你会不会看一下,这现在更有意义了。还帮助了其他一些剧本:D 非常感谢这个 larsks!
    猜你喜欢
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 2012-01-12
    • 2021-03-08
    • 2017-05-12
    • 2019-03-11
    相关资源
    最近更新 更多