У меня есть данные, которые выглядят так:
nova_flavors:
- disk: 10
name: m1.tiny
properties:
disk_read_bytes_sec: 12500000
disk_read_iops_sec: 1000
disk_write_bytes_sec: 3125000
disk_write_iops_sec: 250
vif_inbound_average: 2500
vif_inbound_burst: 3750000
vif_inbound_peak: 12500
vif_outbound_average: 2500
vif_outbound_burst: 3750000
vif_outbound_peak: 12500
ram: 1
- disk: 10
name: m1.small
properties:
disk_read_bytes_sec: 25000000
disk_read_iops_sec: 2000
disk_write_bytes_sec: 6250000
disk_write_iops_sec: 500
vif_inbound_average: 5000
vif_inbound_burst: 7500000
vif_inbound_peak: 25000
vif_outbound_average: 5000
vif_outbound_burst: 7500000
vif_outbound_peak: 25000
ram: 2
Мне нужен Ansible-эквивалент следующего цикла Python:
for flavor in nova_flavors:
for propname, propval in flavor['properties'].items():
# do something with (flavor['name'], propname, propval)
Я надеялся, что смогу это сделать:
- debug:
msg: "{{ item }}"
with_subelements:
- "{{ nova_flavors }}"
- "properties"
Но это не удается, потому что properties
это словарь, а не список. И вы тоже не можете этого сделать:
- debug:
msg: "{{ item }}"
with_subelements:
- "{{ nova_flavors }}"
- "properties.items()"
Есть указатели?
Что ж, я могу предложить полу-хакерское решение, в котором вы пару раз используете set_fact для создания списка dicts, который вы, вероятно, можете использовать?
- hosts: localhost
vars:
nova_flavors:
- disk: 10
name: m1.tiny
properties:
disk_read_bytes_sec: 12500000
disk_read_iops_sec: 1000
disk_write_bytes_sec: 3125000
ram: 1
- disk: 10
name: m1.small
properties:
vif_outbound_burst: 7500000
vif_outbound_peak: 25000
ram: 2
tasks:
- set_fact:
aslist: |
[
{% for item in nova_flavors %}
{% for prop in item.properties.keys() %}
{{ '{' }} 'name':'{{ item.name }}','propname':'{{ prop }}','propvalue':{{item.properties[prop]}} {{ '}' }},
{% endfor %}
{% endfor %}
]
- debug:
var: aslist
Полученные результаты.
TASK [debug] *******************************************************************
ok: [localhost] => {
"aslist": [
{
"name": "m1.tiny",
"propname": "disk_write_bytes_sec",
"propvalue": 3125000
},
{
"name": "m1.tiny",
"propname": "disk_read_iops_sec",
"propvalue": 1000
},
{
"name": "m1.tiny",
"propname": "disk_read_bytes_sec",
"propvalue": 12500000
},
{
"name": "m1.small",
"propname": "vif_outbound_peak",
"propvalue": 25000
},
{
"name": "m1.small",
"propname": "vif_outbound_burst",
"propvalue": 7500000
}
]
}
PLAY RECAP *********************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0
Я считаю, что это легко позволит вам перебирать построенные списки, устанавливая каждое свойство.
Если я проигнорирую часть «Я хочу сначала проверить значение», я мог бы решить эту проблему с помощью шаблонов, например:
- name: set flavor properties:
command: >-
openstack flavor set
{%for prop in item.properties.items()%}--property
{{prop.0}}={{prop.1}} {%endfor %} {{ item.name }}
loop: "{{ nova_flavors }}"
Это работает, но это некрасиво, и в результате все будет changed
каждый запуск playbook. Я мог бы изменить данные перед передачей их в анзибль, чтобы properties
keys - это список списков, а не список dicts, например:
- disk: 10
name: m1.tiny
properties:
- [disk_read_bytes_sec, 12500000]
- [disk_read_iops_sec, 1000]
- [disk_write_bytes_sec, 3125000]
- [disk_write_iops_sec, 250]
- [vif_inbound_average, 2500]
- [vif_inbound_burst, 3750000]
- [vif_inbound_peak, 12500]
- [vif_outbound_average, 2500]
- [vif_outbound_burst, 3750000]
- [vif_outbound_peak, 12500]
ram: 1
vcpus: 1
- disk: 10
name: m1.small
properties:
- [disk_read_bytes_sec: 25000000]
- [disk_read_iops_sec: 2000]
- [disk_write_bytes_sec: 6250000]
- [disk_write_iops_sec: 500]
- [vif_inbound_average: 5000]
- [vif_inbound_burst: 7500000]
- [vif_inbound_peak: 25000]
- [vif_outbound_average: 5000]
- [vif_outbound_burst: 7500000]
- [vif_outbound_peak: 25000]
ram: 2
vcpus: 1
Но это несколько менее интуитивно понятно для чтения и записи ... и эффективно повторно реализует .items()
метод вручную.