Juniper / ansible-junos-stdlib

Junos modules for Ansible
Apache License 2.0
303 stars 157 forks source link

Command module cannot retrieve configuration in xml form #601

Closed moophat closed 1 year ago

moophat commented 1 year ago

Issue Type

juniper.device collection and Python libraries version

ansible 2.8.0
Py 3.7.5
juniper.device would have this issue regardless of version - as I checked the code

OS / Environment

Junos version 15.1 Junos version 20.4

Summary

The command module would execute the requested command line in the rpc form `

show something here

` However Junos itself would not return the correct format if the command is "show configuration". Configuration must be achieved using the "get-config" rpc. And even in this case

Steps to reproduce

Create a playbook using the command module, specify

  • format as xml/json
  • the command list include "show configuration" command
- name: test collect xml config
  hosts: all
  connection: local
  gather_facts: no
  roles:
    - Juniper.junos

  vars:
    format: "xml"
    command_list:
      - "show configuration"

  pre_tasks:
    - name: "[VARIABLES] - Generate Credential"
      set_fact:
        credential:
          username: juniper
          password: juniper@123
          host: 10.96.10.10
          port: 22
          logdir: "/var/tmp/test_pyez_collect_config_xml"
          level:  INFO
        host: "{{ '{{' }} ansible_host {{ '}}' }}"
      run_once: true
      delegate_to: localhost

  tasks: 
    - name: run show command in device
      juniper_junos_command:
        provider: "{{ credential }}"
        commands: "{{command_list}}"
        display: "{{ format }}"

      register: command_result
      ignore_errors: yes

Expected results

Configuration xml should be properly returned

Actual results

Only text config was returned 

I have patched together a quickfix using the existing code from rpc module. However it will not support xml filter because the command modules itself do not have such input. Let me know if you are open for a PR for this quick hack.

chidanandpujar commented 1 year ago

Hi,

Please test with following playbook and format: xml to display the output command in xml format .

---
- name: Test juniper.device.command module
  hosts: all
  connection: local
  gather_facts: no
  collections:
    - juniper.device

  tasks:
    - name: TEST commands with XML output.
      command:
        commands:
          - "show system uptime"
        format: xml
      register: test

    - name: Check TEST 
      debug:
        var: test

ansible-playbook -i inventory pb.juniper_junos_command_issue_601.yml 

PLAY [Test juniper.device.command module] **********************************************************************************************************************************************************

TASK [TEST commands with XML output.] **************************************************************************************************************************************************************
ok: [test]

TASK [Check TEST] **********************************************************************************************************************************************************************************
ok: [test] => {
    "test": {
        "changed": false,
        "command": "show system uptime",
        "failed": false,
        "format": "xml",
        "msg": "The command executed successfully.",
        "parsed_output": {
            "system-uptime-information": {
                "current-time": {
                    "date-time": "2022-11-15 03:39:12 PST"
                },
                "last-configured-time": {
                    "date-time": "2022-11-15 01:37:08 PST",
                    "time-length": "02:02:04",
                    "user": "root"
                },
                "protocols-started-time": {
                    "date-time": "2022-11-15 01:37:13 PST",
                    "time-length": "02:01:59"
                },
                "system-booted-time": {
                    "date-time": "2022-11-15 01:35:43 PST",
                    "time-length": "02:03:29"
                },
                "time-source": "NTP CLOCK",
                "uptime-information": {
                    "active-user-count": "1",
                    "date-time": "3:39AM",
                    "load-average-1": "0.38",
                    "load-average-15": "0.36",
                    "load-average-5": "0.41",
                    "up-time": "2:03",
                    "user-table": ""
                }
            }
        },
        "stdout": "<system-uptime-information>\n  <current-time>\n    <date-time seconds=\"1668512352\">2022-11-15 03:39:12 PST</date-time>\n  </current-time>\n  <time-source>NTP CLOCK</time-source>\n  <system-booted-time>\n    <date-time seconds=\"1668504943\">2022-11-15 01:35:43 PST</date-time>\n    <time-length seconds=\"7409\">02:03:29</time-length>\n  </system-booted-time>\n  <protocols-started-time>\n    <date-time seconds=\"1668505033\">2022-11-15 01:37:13 PST</date-time>\n    <time-length seconds=\"7319\">02:01:59</time-length>\n  </protocols-started-time>\n  <last-configured-time>\n    <date-time seconds=\"1668505028\">2022-11-15 01:37:08 PST</date-time>\n    <time-length seconds=\"7324\">02:02:04</time-length>\n    <user>root</user>\n  </last-configured-time>\n  <uptime-information>\n    <date-time seconds=\"1668512352\">3:39AM</date-time>\n    <up-time seconds=\"7380\">2:03</up-time>\n    <active-user-count format=\"1 users\">1</active-user-count>\n    <load-average-1>0.38</load-average-1>\n    <load-average-5>0.41</load-average-5>\n    <load-average-15>0.36</load-average-15>\n    <user-table/>\n  </uptime-information>\n</system-uptime-information>\n",
        "stdout_lines": [
            "<system-uptime-information>",
            "  <current-time>",
            "    <date-time seconds=\"1668512352\">2022-11-15 03:39:12 PST</date-time>",
            "  </current-time>",
            "  <time-source>NTP CLOCK</time-source>",
            "  <system-booted-time>",
            "    <date-time seconds=\"1668504943\">2022-11-15 01:35:43 PST</date-time>",
            "    <time-length seconds=\"7409\">02:03:29</time-length>",
            "  </system-booted-time>",
            "  <protocols-started-time>",
            "    <date-time seconds=\"1668505033\">2022-11-15 01:37:13 PST</date-time>",
            "    <time-length seconds=\"7319\">02:01:59</time-length>",
            "  </protocols-started-time>",
            "  <last-configured-time>",
            "    <date-time seconds=\"1668505028\">2022-11-15 01:37:08 PST</date-time>",
            "    <time-length seconds=\"7324\">02:02:04</time-length>",
            "    <user>root</user>",
            "  </last-configured-time>",
            "  <uptime-information>",
            "    <date-time seconds=\"1668512352\">3:39AM</date-time>",
            "    <up-time seconds=\"7380\">2:03</up-time>",
            "    <active-user-count format=\"1 users\">1</active-user-count>",
            "    <load-average-1>0.38</load-average-1>",
            "    <load-average-5>0.41</load-average-5>",
            "    <load-average-15>0.36</load-average-15>",
            "    <user-table/>",
            "  </uptime-information>",
            "</system-uptime-information>"
        ]
    }
}

PLAY RECAP *****************************************************************************************************************************************************************************************
test                       : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Thanks

chidanandpujar commented 1 year ago

Hi ,

The command modules enable you to execute operational mode commands on devices running Junos OS , please use the config module to retrieve the configuration

---
- name: Test juniper.device.config module
  hosts: all
  connection: local
  gather_facts: no
  collections:
    - juniper.device
  tasks:
#################
    - name: Retrieve the committed configuration
      config:
        retrieve: 'committed'
        format: "xml"
        diff: false
        check: false
        commit: false
      register: test1
      ignore_errors: True
      tags: [ test1 ]

    - name: Check TEST 1
      debug:
        var: test1

Thanks

moophat commented 1 year ago

@chidanandpujar hi, thanks for the prompt response but I think you misunderstood the use case or skimmed the part where I specify this is a show configuration specific problem.

I'm aware that the config or rpc module can do the job, and the command module's xml format work for other commands. The root cause is as I specified, Junos itself do not understand the implemented rpc in command module

<command formar=xml> $command </command>

if $command include any form of "show configuration".

However the the command module itself support inputting command as a list . And from the NOC's point of view, "show configuration xyz" is a valid command as any other show and most of the time, those network operators will be specifying a list of command(s) to be collected through some configuration file or other interface (cron, awx, jenkin, rundeck) which in turn invoke a playbook that utilize the command modules. They won't be bothered with the playbook itself.

It will be a dirty/man-in-the-middle type of hack to modify the playbook to check if they want xml configuration, then invoke config module, otherwise use other modules and so on. By the spririt of Ansible, module should be idempotence, and the same type of input should produce the same type of output - not like this.

This is not even documented so aside from the NOC not knowing much about the playbook, if the playbook writer cannot check into the router rpc interface like myself (Devops or Sys) , they won't even understand what they did wrong.

Which is why this ticket is mostly for asking whether you guys are open for PR to apply the correct behavior to command modukes.

moophat commented 1 year ago

Doesn't seem like the repo is being monitored anymore, feel free to close it, I'll update a pull request for review later

chidanandpujar commented 1 year ago

Hi , Thank you , I will take a look on the support for "show configuration" , will discuss with team and reopen the issue .

Thanks & Regards Chidanand