python - Ansible + Jinja2 Loop - Dict 对象没有属性
问题描述
我在这里失去了理智,但我似乎看不出我的问题出在哪里!我试图让 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 模板可能出了什么问题,因为我做了很多事情,但无处可去!
提前谢谢了 :)
克里斯
解决方案
这个循环...
{% 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
与 writing 相同if users
,因为表达式if 'sshkey' is defined
总是true
--'sshkey'
是文字字符串,而不是变量。
由于循环为所有用户运行,因此当您到达时它会失败harry
,因为harry
没有sshkey
属性。
您需要过滤具有sshkey
属性的用户,例如使用文档中描述的循环过滤:
{% 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
推荐阅读
- validation - 需要帮助从应用程序脚本中的“范围列表”获取数据验证标准,以便我可以循环浏览这些值
- angular - 在Angular 9中重新签名时从组件B中的组件A获取变量
- java - 调整图形大小以适应java中的内部框架
- statistics - 试图理解线性回归代码(GLM 包)中的 Julia 语法
- android - Android房间@Relation left join
- java - 没有状态码检查的 java DataOutputStream POST 不发布(POST 不工作)
- sql - 将结果从 SQL 复制到 Excel 作为文本而不进行格式化
- sql - 获取SQL中连续两行的时间差
- java - 阅读在 JTextField 的生命周期中输入的内容,同时 JLabel 刷新
- node.js - mongoose 更新中的单个数组(如果不存在)