2

Here I have a small question about how to find a value in a structured file using Ansible. I've seen lineinfile but I'm not pretty sure that it will be helpful. If we assume that my file looks like this (in fact it's way way longer but for evident reasons I cannot post it here ^^)

################## junos.conf ##################

system {
    auto-snapshot;
    root-authentication {
        encrypted-password ## SECRET-DATA
    }
    services {
        ssh;
        netconf ssh;
        scp;
    }
    syslog {
        user * {
            any emergency;
        }
        file messages {
            any notice;
            authorization info;
        }
        file interactive-commands {
            interactive-commands any;
        }
    }
    processes {
        dhcp-service {
            traceoptions {
                file dhcp_logfile size 10m;
                level all;
                flag all;
            }
        }
    }
}
interfaces {
    irb {
        unit 0 {
            family inet {
                dhcp {
                    vendor-id Juniper-ex4300-48t;
                }
            }
        }
    }
    vme {
        unit 0 {
            family inet {
                address 172.0.0.1/24
            }
        }
    }
}
forwarding-options {
    storm-control-profiles default {
        all;
    }
}
vlans {
    default {
        vlan-id 1;
        l3-interface irb.0;
    }
}

It's a .conf file but it looks like a structured file. Imagine, I want to find a way to get the value interfaces->vme->unit 0->family inet within an Ansible playbook, how could I do ? Which parser could I use in Ansible ?

I've already read this page but I don't really know which parser to use and how to use it : https://docs.ansible.com/ansible/latest/network/user_guide/cli_parsing.html

Thanks, Max

a-maxime
  • 35
  • 3
  • You can't program in Ansible. Ansible stores all data in a big global variable with all the implications of side effects. Historically this made nested loops problematic (Ansible has nowadays a work-around for this) and of course it makes parsing of anything more than regular grammars impossible. Whenever you need something complicated, which exceeds the capabilities of existing modules or Jinja ([example](https://stackoverflow.com/a/46117814/402322)), you have to write your own module in Python. Or you have to convert your data into a format Ansible understands like JSON. – ceving May 28 '21 at 08:52
  • 1
    Thanks @ceving for your message, I know those things aren't made to be programmable in Ansible but I was expecting something like a Ansible which will convert it to JSON and then I'll be able to get whichever value I want from the JSON output. – a-maxime May 28 '21 at 12:22
  • 1
    Have you seen this: https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html#using-netconf-in-ansible – ceving May 28 '21 at 13:32
  • Would it possible for you to use [Juniper Networks Ansible modules](https://www.juniper.net/documentation/en_US/junos-ansible/topics/topic-map/junos-ansible-configuration-retrieving.html)? – U880D May 30 '21 at 13:06
  • @a-maxime, regarding your comment "_was expecting something like a Ansible which will convert it to JSON _", would it be possible for you [to convert Juniper config to json](https://stackoverflow.com/questions/15229429/) i.e. via `show config | display json` before exporting into a file? – U880D May 30 '21 at 13:12
  • @U880D oh I get it, but in fact, on this particular case once I've set the configuration, I change the management interface ip address (which I'm using with Ansible) so I lost the connection. That's why I wanted a way to parse the ip address I'm loading onto the switch to check if it's online after committing the config. Is it clear ? – a-maxime May 31 '21 at 23:03
  • According the documentation the [CLI parser txtfsm](https://docs.ansible.com/ansible/latest/network/user_guide/cli_parsing.html#parsing-with-textfsm) seems to be a good fit for your use case, unfortunately I do not have experience with that one at all. – U880D Jun 01 '21 at 09:40

1 Answers1

1

Regarding your question

Which parser could I use in Ansible?

If you are not able to export the config in a JSON structured format before (show config | display json), because it is in example not under your control, you may need to deal with the given structure.

It's a .conf file but it looks like a structured file.

Since the structure don't look like one of the available templates in Parsing semi-structured text with Ansible, you may need to look to an other option.

I assume you do not want to read in the whole file via file_lookup module and parse it fully within Ansible.

The Lookup Plugins seems also not to have the provided structure implemented. The INI lookup seems also not fit.

Imagine, I want to find a way to get the value interfaces->vme->unit 0->family inet within an Ansible playbook, how could I do?

If your configuration file has just that structure and it is not changing, which we don't know according

... in fact it's way way longer ...

the following approach might be working for a while:

- name: Read IP address from Junos config file
  shell:
    cmd: grep -o "address.*" /tmp/junos.conf | cut -f 2 -d " " | cut -f 1 -d "/"
  register: ip_address
  warn: false
  check_mode: false
  changed_when: false
  delegate_to: localhost
  tags: junos_conf

- name: Show IP address
  debug: 
    msg: "{{ ip_address }}"  
  tags: junos_conf

There is also the option to write an own Custom Plugin.

Thanks to

Links from comments

U880D
  • 8,601
  • 6
  • 24
  • 40
  • Well that's I think a good way to do it to be fair. I've managed to get all conf file addresses thanks to your method. I'll custom it and post it here for other people ! – a-maxime Jun 18 '21 at 08:20