Search code examples
ansiblejinja2ansible-2.xansible-template

Fetch the value based on a particular string in Ansible


I would like to fetch the value based on the keyword mentioned in the rules yaml file. If the keyword in rules.yaml is mentioned as OBJ, it should fetch the value of po_id matching with the same subnet in input & rules yaml file and if the keyword is GRP, then it should fetch the value of pog_id matchign with the same subnet in input & rules yaml file. Expected result as shown below.

Input.yml

[
    {
        
        "po_id": "11155588779966",
        "pog_id": "1115558871321649",
        "subnetname": "DNS",
        "netname": "Test1"
    },
    {  
        "po_id": "99996688778855",
        "pog_id": "1115558812345",
        "subnetname": "NTP",
        "netname": "Test2"
    },
    {
        "po_id": "123456789101112",
        "pog_id": "111555880321624",
        "subnetname": "NET",
        "netname": "Test3"  
    }
]

rules.yml

rules:
         -    rule number: "1" 
              destCidr: "OBJ({{DNS}}) , 10.22.22.0/24"
                  

         -    rule number: "2"
              destCidr: "OBJ({{ NTP }}) , 10.33.33.0/24"
              

         -    rule number: "3"
              destCidr: "OBJ({{ NET }}), GRP({{ NTP }}) , 10.33.33.0/24"

Expected Output

[
    {
        "rule number": "1",
        "destCidr": "OBJ(11155588779966), 10.22.22.0/24 "
    },
    {
        "rule number": "2",
        "destCidr": "OBJ(99996688778855), 10.33.33.0/24"
    },
    {    
        "rule number": "3",
        "destCidr": "OBJ(123456789101112), GRP(1115558812345), 10.33.33.0/24 "
    }
]

Solution

  • with the same logic: you indicate if you want po_id or pog_id item

    - name: "make this working"
      hosts: localhost
      vars:
        input: "{{ lookup('file', './input.yml') | from_json }}"
        rules:
          - rule number: "1" 
            destCidr: "OBJ({{po_id.DNS}}) , 10.22.22.0/24"
          - rule number: "2"
            destCidr: "OBJ({{ po_id.NTP }}) , 10.33.33.0/24"
          - rule number: "3"
            destCidr: "OBJ({{ po_id.NET }}), GRP({{ pog_id.NTP }}) , 10.33.33.0/24"
      tasks:
        - set_fact:
            po_id: >- 
               {{
                 input |items2dict(key_name='subnetname',
                                                  value_name='po_id')
               }}
    
        - set_fact:
            pog_id: >- 
                {{
                  input |items2dict(key_name='subnetname',
                                                  value_name='pog_id')
                }}  
        - set_fact:
            ruleoutpout: "{{ rules }}"
    
        - debug:
            var: ruleoutpout
    

    result:

    ok: [localhost] => {
        "ruleoutpout": [
            {
                "destCidr": "OBJ(11155588779966) , 10.22.22.0/24",
                "rule number": "1"
            },
            {
                "destCidr": "OBJ(99996688778855) , 10.33.33.0/24",
                "rule number": "2"
            },
            {
                "destCidr": "OBJ(123456789101112), GRP(1115558812345) , 10.33.33.0/24",
                "rule number": "3"
            }
        ]
    }
    

    here you have to indicate if you are using po_id or pog_id..if you dont want to precise that, you have to use a customfilter...if you want this, i suggest you to open a new question by asking the creation of customfilter .. in this case nothing to precise, just keep DNS, NET, NTP and its the customfilter which does the job following we have OBJ, GRP or other..