How to get facts via Ansible

1,352 views
Skip to first unread message

Eugene Prokopiev

unread,
Oct 14, 2016, 1:37:10 PM10/14/16
to Junos Python EZ
Hi,

I have latest ansible and junos-eznc installed via pip --user command and one host entry in ~/ansible/hosts. I tried to get facts by ad-hoc command without success:

$ ansible all -i ~/ansible/hosts -m setup -k
SSH password:
192.168.10.1 | FAILED! => {
    "failed": true,
    "msg": "failed to transfer file to error: unknown command: /bin/sh/setup:\nsftp> put /tmp/.private/enp/tmpvyBPCL 'error: unknown command: /bin/sh/setup'\n\nsftp: remote open(\"/var/home/remote/error: unknown command: /bin/sh/setup\"): No such file or directory\r\n"
}


OK, setup looks like not for network devices, so I tried to do the same with playbook (as described in http://docs.ansible.com/ansible/junos_facts_module.html#examples):

$ cat ~/ansible/playbooks/juniper/facts.yml
- name: collect default set of facts
  junos_facts:

$ ansible-playbook ~/ansible/playbooks/juniper/facts.yml -i ansible/hosts -k
SSH password:
ERROR! 'junos_facts' is not a valid attribute for a Play

The error appears to have been in '/home/enp/ansible/playbooks/juniper/facts.yml': line 1, column 3, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:


- name: collect default set of facts
  ^ here


Still no success :( What is wrong?

Eugene Prokopiev

unread,
Oct 14, 2016, 1:51:05 PM10/14/16
to Junos Python EZ
This playbook (partialy from http://www.juniper.net/techpubs/en_US/junos-ansible1.0/topics/example/junos-ansible-playbooks-device-configuring.html) works better:

$ cat ~/ansible/playbooks/juniper/facts.yml
- name: get facts from device running Junos OS
  hosts: 192.168.10.1
  roles:
  - Juniper.junos
  connection: local
  gather_facts: yes


$ ansible-playbook ~/ansible/playbooks/juniper/facts.yml -i ansible/hosts -k
SSH password:

PLAY [get facts from device running Junos OS] **********************************

TASK [setup] *******************************************************************
ok: [192.168.10.1]

PLAY RECAP *********************************************************************
192.168.10.1              : ok=1    changed=0    unreachable=0    failed=0  


But how to see the facts and how to avoid to set hosts twice? I see errors without -i argument or without hosts option in playbook

Stacy W. Smith

unread,
Oct 14, 2016, 3:27:20 PM10/14/16
to Eugene Prokopiev, Junos Python EZ
Hi Eugene,

I'm always glad to seen new folks using Ansible with Junos. Please do continue to reach out to us if you have any additional questions.

To start with, it is helpful to understand the difference between how Ansible communicates with most hosts/servers and how it communicates with most networking devices.

In the typical Ansible communication model, the Ansible control machine establishes/maintains an SSH session to the target host. The playbook/modules are downloaded to the host and then executed by a Python interpreter on the host itself. The result (in JSON format) is then returned over the the SSH session to the Ansible control machine.

When communicating with network devices, the Ansible control machine executes the playbook/modules locally on the Ansible control machine itself. Each module establishes a communication channel with the target network device. In the case of Junos device's, that communication channel is typically a NETCONF over SSH connection which is provided by the PyEZ library on which the Junos for Ansible modules are built.

This atypical communication model means that many of the standard Ansible modules can not be used with networking devices. This includes the standard "setup" module which normally does fact gathering on most hosts/servers. That's why the first attempt in your previous email didn't work.

This atypical communication model also means that you must pass connection parameters (hostname, username, and password) as arguments to each Junos module.

The next important point to understand is that there are currently two sets of Junos modules for Ansible. The "core" modules are included in Ansible 2.1 and greater and are documented at http://docs.ansible.com/ansible/list_of_network_modules.html#junos. These core modules were developed by Ansible with input from Juniper. The older "galaxy" modules were developed by Juniper directly and work with older 1.x releases as well as current 2.x releases. The galaxy modules must be installed using sudo ansible-galaxy install Juniper.junos. Documentation for the galaxy modules can be found at http://junos-ansible-modules.readthedocs.io/en/1.4.0/. You can use any combination of core and/or galaxy modules in your playbooks.

Currently there is some overlap between the core modules and the galaxy modules and there are some differences in how arguments are specified for each set of modules. Juniper is actively working with Ansible on a plan to consolidate and standardize the modules.

With that explanation, here's an example playbook which uses the core junos_facts module to gather and print Junos facts (using the core debug module):

---
- name: Get facts using the core module
  hosts: all
  connection: local
  gather_facts: no
  tasks:
    - name: Get Junos Facts Using Core Module
      junos_facts:
        host: "{{ inventory_hostname }}"
        username: "user"
        password: "user123"
        config: yes
        config_format: xml
      register: response
    - name: Print Facts via Registered Response
      debug:
        var: response.ansible_facts


and here is an example playbook which uses the galaxy get_junos_facts module:

---
- name: Get facts using the galaxy module
  hosts: all
  connection: local
  gather_facts: no
  roles:
    - Juniper.junos
  tasks:
    - name: Get Junos Facts Using Galaxy Module
      junos_get_facts:
        host: "{{ inventory_hostname }}"
        user: "user"
        passwd: "user123"
      register: response
    - name: Print Facts via Registered Response
      debug:
        var: response.facts

Hope this helps,
--Stacy


--
You received this message because you are subscribed to the Google Groups "Junos Python EZ" group.
To unsubscribe from this group and stop receiving emails from it, send an email to junos-python-...@googlegroups.com.
Visit this group at https://groups.google.com/group/junos-python-ez.
To view this discussion on the web visit https://groups.google.com/d/msgid/junos-python-ez/b223371f-31c4-42fc-a5a3-6bc5e704b0e7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Eugene Prokopiev

unread,
Oct 15, 2016, 2:05:07 AM10/15/16
to Junos Python EZ, eugene.p...@gmail.com
Thank you for so detailed answer!

Can you say why we must use 'gather_facts: no' in both cases?

Eugene Prokopiev

unread,
Oct 15, 2016, 2:14:20 AM10/15/16
to Junos Python EZ, eugene.p...@gmail.com


пятница, 14 октября 2016 г., 22:27:20 UTC+3 пользователь Stacy Smith написал:

... here's an example playbook which uses the core junos_facts module to gather and print Junos facts (using the core debug module):

---
- name: Get facts using the core module
  hosts: all
  connection: local
  gather_facts: no
  tasks:
    - name: Get Junos Facts Using Core Module
      junos_facts:
        host: "{{ inventory_hostname }}"
        username: "user"
        password: "user123"
        config: yes
        config_format: xml
      register: response
    - name: Print Facts via Registered Response
      debug:
        var: response.ansible_facts



This playbook failed with:

 TASK [Get Junos Facts Using Core Module] ***************************************
fatal: [192.168.10.1]: FAILED! => {"changed": false, "failed": true, "msg": "jxmlease is required but does not appear to be installed"}

Is this about something on JunOS side? Is it possible to use core modules and avoid this error without changing something on JunOS side? Galaxy example works good.

Eugene Prokopiev

unread,
Oct 15, 2016, 11:31:07 AM10/15/16
to Junos Python EZ, eugene.p...@gmail.com


суббота, 15 октября 2016 г., 9:14:20 UTC+3 пользователь Eugene Prokopiev написал:

fatal: [192.168.10.1]: FAILED! => {"changed": false, "failed": true, "msg": "jxmlease is required but does not appear to be installed"}

Is this about something on JunOS side? Is it possible to use core modules and avoid this error without changing something on JunOS side? Galaxy example works good.


ah, sorry, this is resolved by pip install jxmlease. But response contains JunOS router full configuration both in xml and json. Is it possible to see facts only as with galaxy example?

Eugene Prokopiev

unread,
Oct 15, 2016, 11:46:33 AM10/15/16
to Junos Python EZ, eugene.p...@gmail.com


суббота, 15 октября 2016 г., 18:31:07 UTC+3 пользователь Eugene Prokopiev написал:

ah, sorry, this is resolved by pip install jxmlease. But response contains JunOS router full configuration both in xml and json. Is it possible to see facts only as with galaxy example?

Sure, done by removing 'config: yes' and 'config_format: xml' from playbook.

So, only one thing which I can't understand is why we must use 'gather_facts: no' in both cases. No visible changes in compare with 'gather_facts: yes'. Maybe facts can be fetched by 'gather_facts: yes' without any tasks in playbook but can't be shown?

And additional (maybe playbook specific) question: is it possible to put response data structure into files (one file for all hosts or directory with files for every host) or even pass response data to python script or embedded python code for
additional processing?

Stacy W. Smith

unread,
Oct 16, 2016, 11:33:48 AM10/16/16
to Eugene Prokopiev, Junos Python EZ
On Oct 15, 2016, at 12:05 AM, Eugene Prokopiev <eugene.p...@gmail.com> wrote:

Thank you for so detailed answer!

Can you say why we must use 'gather_facts: no' in both cases?

By default, Ansible performs fact gathering using the setup module. This is the module that gathers facts for Linux/Unix-based systems. Since the playbook runs on the Ansible control machine (because of connection: local) this results in gathering facts about the control machine rather than the target network device. So, setting gather_facts: no is not strictly required, but it keeps from spending extra unnecessary cycles gathering facts about the Ansible control machine that aren't really useful.

--Stacy

Stacy W. Smith

unread,
Oct 16, 2016, 11:51:07 AM10/16/16
to Eugene Prokopiev, Junos Python EZ

On Oct 15, 2016, at 9:31 AM, Eugene Prokopiev <eugene.p...@gmail.com> wrote:
Is it possible to see facts only as with galaxy example?


The core junos_facts module allows you to (optionally) download the config as part of the facts. The galaxy get_junos_facts module does not allow you to download the config. The config is always provided in text format. If you choose config_format: xml then the configuration is also provided in JSON format. It's this conversion from XML to JSON that requires the jxmlease module to be installed.

You can disable the config download by setting config: no and removing config_format like this:


---
- name: Get facts using the core module
  hosts: all
  connection: local
  gather_facts: no
  tasks:
    - name: Get Junos Facts Using Core Module
      junos_facts:
        host: "{{ inventory_hostname }}"
        username: "user"
        password: "user123"
        config: no

      register: response
    - name: Print Facts via Registered Response
      debug:
        var: response.ansible_facts

--Stacy
Reply all
Reply to author
Forward
0 new messages