英文:
Separating a list of dicts
问题
以下是您要翻译的内容:
"I've been trying to find a way to take a data collection that contains three fields where two of the fields can contain multiple items and convert/expand that data to a list where a row is added for every item in one of the fields.
The data is about kubernetes pods and the containers and images inside them. I can get the raw data just fine I just can't transform it.
the json data is this:
  - name: condense the raw data
    set_fact:
      pod_data: "{{ pod_data|default([]) + [{'pod_name':item.pod_name,'container_name':item.container_name,'image_path':item.image_path }] }}"
    with_items: "{{ podinfo | json_query('resources[*].{pod_name: metadata.name, container_name: spec.containers[*].name, image_path: spec.containers[*].image }') }}"
  - debug: var=pod_data
"pod_data": [
        {
            "container_name": [
                "container1",
                "container2"
            ],
            "image_path": [
                "path1",
                "path2"
            ],
            "pod_name": "pod1"
        },
        {
            "container_name": [
                "container3",
                "container4"
            ],
            "image_path": [
                "path3",
                "path4"]
            ],
            "pod_name": "pod2"
        }
I want to output the data in a 1:1 format like this:
"pod_data": [
        {
            "container_name":  "container1"
            ,
            "image_path": "path1"
            ,
            "pod_name": "pod1"
        },
        {
            "container_name": "container2"
            ,
            "image_path": "path2"
            ],
            "pod_name": "pod1"
        },
        {
            "container_name": "container3"
            ,
            "image_path": "path3"
            ,
            "pod_name": "pod2"
        }
```"
I'm not good enough with loops to know how to do a nested style loop when there are multiple sub elements in ansible. I could do it in powershell but that doesn't help me here.
Is my only choice some sort of include_tasks loop while passing each item and container/image count so I can split it that many times?"
希望这可以帮助您。如果您有任何其他疑问,请随时提出。
<details>
<summary>英文:</summary>
I've been trying to find a way to take a data collection that contains three fields where two of the fields can contain multiple items and convert/expand that data to a list where a row is added for every item in one of the fields.
The data is about kubernetes pods and the containers and images inside them.  I can get the raw data just fine I just can't transform it.
the json data is this:
- 
name: condense the raw data
set_fact:
pod_data: "{{ pod_data|default([]) + [{'pod_name':item.pod_name,'container_name':item.container_name,'image_path':item.image_path }] }}"
with_items: "{{ podinfo | json_query('resources[].{pod_name: metadata.name, container_name: spec.containers[].name, image_path: spec.containers[*].image }') }}" - 
debug: var=pod_data
 
"pod_data": [
{
"container_name": [
"container1",
"container2"
],
"image_path": [
"path1",
"path2"
],
"pod_name": "pod1"
},
{
"container_name": [
"container3",
"container4"
],
"image_path": [
"path3",
"path4"
],
"pod_name": "pod2"
}
I want to output the data in a 1:1 format like this:
"pod_data": [
{
"container_name":  "container1"
,
"image_path": "path1"
,
"pod_name": "pod1"
},
{
"container_name": "container2"
,
"image_path": "path2"
],
"pod_name": "pod1"
},
{
"container_name": "container3"
,
"image_path": "path3"
,
"pod_name": "pod2"
}
I'm not good enough with loops to know how to do a nested style loop when there are multiple sub elements in ansible.  I could do it in powershell but that doesn't help me here.
Is my only choice some sort of include_tasks loop while passing each item and container/image count so I can split it that many times?
</details>
# 答案1
**得分**: 3
创建结构
```yaml
  pod_data_update: |
    [{% for i in pod_data %}
    {% for n,p in i.container_name|zip(i.image_path) %}
    {container_name: {{ n }}, image_path: {{ p }}, pod_name: {{ i.pod_name }}},
    {% endfor %}
    {% endfor %}]
, 将其转换为 YAML,并更新 pod_data
    - set_fact:
        pod_data: "{{ pod_data_update|from_yaml }}"
获得所需结果
  pod_data:
    - {container_name: container1, image_path: path1, pod_name: pod1}
    - {container_name: container2, image_path: path2, pod_name: pod1}
    - {container_name: container3, image_path: path3, pod_name: pod2}
    - {container_name: container4, image_path: path4, pod_name: pod2}
<hr>
<sup>
测试的完整 playbook 示例
- hosts: localhost
  vars:
    pod_data:
    - container_name:
      - container1
      - container2
      image_path:
      - path1
      - path2
      pod_name: pod1
    - container_name:
      - container3
      - container4
      image_path:
      - path3
      - path4
      pod_name: pod2
    pod_data_update: |
      [{% for i in pod_data %}
      {% for n,p in i.container_name|zip(i.image_path) %}
      {container_name: {{ n }}, image_path: {{ p }}, pod_name: {{ i.pod_name }}},
      {% endfor %}
      {% endfor %}]      
  tasks:
    - set_fact:
        pod_data: "{{ pod_data_update|from_yaml }}"
    - debug:
        var: pod_data|to_yaml
</sup>
英文:
Create the structure
  pod_data_update: |
    [{% for i in pod_data %}
    {% for n,p in i.container_name|zip(i.image_path) %}
    {container_name: {{ n }}, image_path: {{ p }}, pod_name: {{ i.pod_name }}},
    {% endfor %}
    {% endfor %}]    
, convert it from YAML, and update pod_data
    - set_fact:
        pod_data: "{{ pod_data_update|from_yaml }}"
gives what you want
  pod_data:
    - {container_name: container1, image_path: path1, pod_name: pod1}
    - {container_name: container2, image_path: path2, pod_name: pod1}
    - {container_name: container3, image_path: path3, pod_name: pod2}
    - {container_name: container4, image_path: path4, pod_name: pod2}
<hr>
<sup>
Example of a complete playbook for testing
- hosts: localhost
  vars:
    pod_data:
    - container_name:
      - container1
      - container2
      image_path:
      - path1
      - path2
      pod_name: pod1
    - container_name:
      - container3
      - container4
      image_path:
      - path3
      - path4
      pod_name: pod2
    pod_data_update: |
      [{% for i in pod_data %}
      {% for n,p in i.container_name|zip(i.image_path) %}
      {container_name: {{ n }}, image_path: {{ p }}, pod_name: {{ i.pod_name }}},
      {% endfor %}
      {% endfor %}]      
  tasks:
    - set_fact:
        pod_data: "{{ pod_data_update|from_yaml }}"
    - debug:
        var: pod_data|to_yaml
</sup>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论