我正在嘗試使用帶有變數的循環(而不是硬編碼值)從 json 資料(如下)獲取資料。在 json 資料(如下)中,「叢集」可以更改,因此我不能簡單地使用:loop:「{{ drs_rule_jsondata.drs_rule_info.cluster }}」——它按我的預期工作並產生預期的結果。
但是,當我使用下面的播放時(在循環中使用變數並且當{{ cluster_info.name }} = cluster 時),我得到“msg”:“'dict object'沒有屬性'drs_rule_jsondata.drs_rule_info.cluster'” 。令人困惑的部分是,它產生的語法與有效的語法相同......在循環中以這種方式使用變數應該不起作用嗎?鑑於「集群」可以改變,是否有另一種方法可以獲得預期結果?
玩:
- name: Set drs rule info
set_fact:
drs_rule: "{{ drs_rule|default([]) + [ {
'rule_name': item | json_query('rule_name'),
'rule_affinity': item | json_query('rule_affinity'),
'rule_vms': item | json_query('rule_vms[*]')
} ] }}"
vars:
path: drs_rule_jsondata.drs_rule_info
cluster_name: "{{ cluster_info.name }}"
loop: "{{ vars[path + '.' + cluster_name] }}"
json數據:
{
"ansible_facts": {
"drs_rule_jsondata": {
"changed": false,
"drs_rule_info": {
"cluster": [
{
"rule_affinity": true,
"rule_enabled": true,
"rule_key": 1,
"rule_mandatory": null,
"rule_name": "DEMO_REP_DRS_1",
"rule_type": "vm_vm_rule",
"rule_uuid": "522d41eb-4acb-afbf-9f37-15a1651ccf45",
"rule_vms": [
"VM1",
"VM2",
"VM3",
"VM4"
]
]
},
"failed": false
}
},
"_ansible_no_log": false,
"changed": false
}
預期成績:
{
"drs_rule": [
{
"rule_name": "DEMO_REP_DRS_1",
"rule_affinity": true,
"rule_vms": [
"VM1",
"VM2",
"VM3",
"VM4"
]
}
]
}
答案1
這個表達式沒有意義:
vars[path + '.' + cluster_name]
在這裡,您要求一個具有文字名稱的變量drs_rule_jsondata.drs_rule_info.<value of cluster_name>
,但沒有這樣的變數——這甚至不是一個有效的變數名稱。
vars
無論如何你都不需要在這裡使用;您可以直接引用頂級dns_rule_jsondata
變數。
也不清楚您為什麼json_query
在劇本中使用,因為您只需要單獨的靜態密鑰。
我認為你想要做的是:
- hosts: localhost
gather_facts: false
vars:
cluster_info:
name: cluster
drs_rule_jsondata:
changed: false
drs_rule_info:
cluster:
- rule_affinity: true
rule_enabled: true
rule_key: 1
rule_mandatory: null
rule_name: DEMO_REP_DRS_1
rule_type: vm_vm_rule
rule_uuid: 522d41eb-4acb-afbf-9f37-15a1651ccf45
rule_vms:
- VM1
- VM2
- VM3
- VM4
tasks:
- name: Set drs rule info
set_fact:
drs_rule: >-
{{
drs_rule + [
{
'rule_name': item.rule_name,
'rule_affinity': item.rule_affinity,
'rule_vms': item.rule_vms
}
]
}}
vars:
drs_rule: []
cluster_name: "{{ cluster_info.name }}"
loop: "{{ drs_rule_jsondata.drs_rule_info[cluster_name] }}"
- debug:
var: drs_rule
運行上面的劇本會產生輸出:
PLAY [localhost] ***************************************************************
TASK [Set drs rule info] *******************************************************
ok: [localhost] => (item={'rule_affinity': True, 'rule_enabled': True, 'rule_key': 1, 'rule_mandatory': None, 'rule_name': 'DEMO_REP_DRS_1', 'rule_type': 'vm_vm_rule', 'rule_uuid': '522d41eb-4acb-afbf-9f37-15a1651ccf45', 'rule_vms': ['VM1', 'VM2', 'VM3', 'VM4']})
TASK [debug] *******************************************************************
ok: [localhost] => {
"drs_rule": [
{
"rule_affinity": true,
"rule_name": "DEMO_REP_DRS_1",
"rule_vms": [
"VM1",
"VM2",
"VM3",
"VM4"
]
}
]
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
答案2
這是最終有效的方法(我想我已經嘗試過了):
set_fact:
drs_rule: "{{ drs_rule|default([]) + [ {
'rule_name': item | json_query('rule_name'),
'rule_affinity': item | json_query('rule_affinity'),
'rule_vms': item | json_query('rule_vms[*]')
} ] }}"
vars:
cluster_name: "{{ cluster_info.name }}"
loop: "{{ drs_rule_jsondata.drs_rule_info[cluster_name] }}"