2

I am trying to work out how to iterate over some JSON that has repeated structures but have not used a list.

I am using the ansible.posix.firewalld_info module and it returns a dictionary for each zone:

{
"active_zones": true,
    "changed": false,
    "collected_zones": [
        "public",
        "work"
    ],
    "firewalld_info": {
        "default_zone": "public",
        "version": "0.9.3",
        "zones": {
            "public": {
                "forward": false,
                "forward_ports": [],
                "icmp_block_inversion": false,
                "icmp_blocks": [],
                "interfaces": [
                    "ens22",
                    "ens20",
                    "ens19",
                    "ens18"
                ],
                "masquerade": true,
                "ports": [
                    [
                        "9090",
                        "tcp"
                    ]
                ],
                "protocols": [],
                "rich_rules": [],
                "services": [
                    "ssh",
                    "cockpit",
                    "MyCustomService"
                ],
                "source_ports": [],
                "sources": [],
                "target": "DROP"
            },
            "work": {
                "forward": false,
                "forward_ports": [],
                "icmp_block_inversion": false,
                "icmp_blocks": [],
                "interfaces": [
                    "ens21"
                ],
                "masquerade": false,
                "ports": [],
                "protocols": [],
                "rich_rules": [],
                "services": [
                    "ssh",
                    "dhcpv6-client",
                    "cockpit"
                ],
                "source_ports": [],
                "sources": [],
                "target": "default"
            }
        }
    },
    "invocation": {
        "module_args": {
            "active_zones": true,
            "zones": null
        }
    },
    "undefined_zones": []
}

public and work are dictionaries. How can I iterate over each zone under firewalld_info in this JSON?

2 Answers 2

4

Q: "How can I iterate over each zone?"

A: Convert the dictionary to a list, .e.g. given the data in the variable result

    - debug:
        var: item
      loop: "{{ result.firewalld_info.zones.public|dict2items }}"

gives (abridged)

  item:
    key: forward
    value: false

  item:
    key: forward_ports
    value: []

  item:
    key: icmp_block_inversion
    value: false

  ...

See with_dict

1
  • Thanks. Great answer
    – Bryon
    Dec 4, 2021 at 21:00
1

Since Vladimir answered this in the ansible context I'm going to give you a way to process this in the shell.

As a one liner:

for zone in public work; do echo "another iteration"; cat fw.json | jq ".firewalld_info.zones.$zone"; done

Or as prettier code:

for zone in public work
do 
        echo "another iteration"
        cat fw.json | jq ".firewalld_info.zones.$zone"
        # save it in a variable or pass it through another round of jq to extract details into variables
done

You're using jq to extract the subsections you want. The biggest limitation of these examples is that the zones are hard-coded. You can pull the keys out with jq to make this more flexible.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.