0

is there any way to simplify the below json_query? here you can see that i am trying to extract three values using three setup of queries. Since i have three items in the list the value will be generated three times corresponding to the item list. is there any way to separate the value for each item ?

ClusterName: xxxx for dv-cn-c1
DomainName: xxxx for dv-cn-c1

ClusterName: xxxx for dv-cn-c2
DomainName: xxxx for dv-cn-c2

Please see my idea

   - name: "set fact for policy pkg for list of devices"
        set_fact:
          ClusterName: "{{ fullinvt  | json_query(query1) }}"
          DomainName: "{{ fullinvt  | json_query(query2) }}"
          PolicyName: "{{ fullinvt  | json_query(query3) }}"
        vars:
    #w       query: "ansible_facts.checkpoint_servers_gateways.objects[*].policy[].\"cluster-members-access-policy-revision\"[?name == 'dev-cn-c2'].name"
          query1: "ansible_facts.checkpoint_servers_gateways.objects[?\"cluster-member-names\"[?contains(@ `{{ item }}`)]].name | [0]"
          query2: "ansible_facts.checkpoint_servers_gateways.objects[?\"cluster-member-names\"[?contains(@ `{{ item }}`)]].domain.name | [0]"
          query3: "ansible_facts.checkpoint_servers_gateways.objects[?\"cluster-member-names\"[?contains(@ `{{ item }}`)]].policy.\"access-policy-name\" | [0]"
        with_items:
          - dv-cn-c1
          - dv-cn-c2
          - dv-cn-4
        tags: ADDLAG
mikeraj2019
  • 39
  • 2
  • 10
  • 1
    as far as I know you can set facts only once. But because of iterating `with_items` you'll set the same fact multiple times. So your task will not work as you expect. – Tomáš Pospíšek Aug 16 '19 at 20:59

1 Answers1

1

What you could do is build a dictionary of dictionaries, where the first level keys are the items on your loop; and the second level keys their corresponding ClusterName, DomainName and PolicyName values.

I have created a sample playbook to explain myself better:

---
- name: Multiple json_queries
  hosts: local
  connection: local
  gather_facts: no
  vars_files:
    - ./secret.yml
  vars:
    fullinvt:
      dv-cn-c1:
        ClusterName: dv-cn-c1-cluster-name
        DomainName: dv-cn-c1-domain-name
        PolicyName: dv-cn-c1-policy-name
      dv-cn-c2:
        ClusterName: dv-cn-c2-cluster-name
        DomainName: dv-cn-c2-domain-name
        PolicyName: dv-cn-c2-policy-name
      dv-cn-4:
        ClusterName: dv-cn-4-cluster-name
        DomainName: dv-cn-4-domain-name
        PolicyName: dv-cn-4-policy-name
  tasks:
    - name: Create `json_query` object
      set_fact:
        # Multiline filter application
        result: >
          {{ 
            (result | default({})) | 
            combine({item: {
              "ClusterName": fullinvt | json_query('"' + item + '"' + ".ClusterName"),
              "DomainName": fullinvt | json_query('"' + item + '"' + ".DomainName"),
              "PolicyName": fullinvt | json_query('"' + item + '"' + ".PolicyName")
            }}) 
          }}
      loop:
        - dv-cn-c1
        - dv-cn-c2
        - dv-cn-4

    - debug:
        var: item
      loop: "{{ result | dict2items }}"

Instead of creating global facts, I create one called result. The data for each element of the loop, is inside a key with the same name.

If you need to loop over this dictionary further along, you can use the dict2items filter, as shown on the debug task.

I hope it helps.

guzmonne
  • 2,490
  • 1
  • 16
  • 22