napalm-automation / napalm

Network Automation and Programmability Abstraction Layer with Multivendor support
Apache License 2.0
2.26k stars 554 forks source link

IOSXR can't get correct diff_file in Ansible/Napalm check mode #1391

Open beleof opened 3 years ago

beleof commented 3 years ago

Description of Issue/Question

We found IOSXR have problem get the correct diff_file in Ansible/Napalm check mode. For example, we want to delete the prefix-set CLOUD in configuration file.

diff --git a/configs_static/xrv-1.conf b/configs_static/xrv-1.conf
index bae5138..18bc4ff 100644
--- a/configs_static/xrv-1.conf
+++ b/configs_static/xrv-1.conf
@@ -68,10 +68,6 @@ interface GigabitEthernet0/0/0/2
  cdp
  ipv4 address 192.168.66.8 255.255.255.254
 !
-prefix-set CLOUD
-  9.244.40.0/24 eq 24
-end-set
-!
 prefix-set PUBLIC
   9.244.40.0/24 eq 24
 end-set

After delete tie prefix-set and run the Ansible playbook in check mode found no changes

PLAY RECAP ********************************************************************************************************************************************************************************************************************** xrv-1 : ok=8 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0 When run the playbook in production mode in can made the change.

Note: Please check https://guides.github.com/features/mastering-markdown/ to see how to properly format your request.

Did you follow the steps from https://github.com/napalm-automation/napalm#faq

(Place an x between the square brackets where applicable)

Setup

napalm version

(Paste verbatim output from pip freeze | grep napalm between quotes below)

pji@las4779:~/repos/network_ansible$ pip freeze | grep napalm
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
napalm==2.3.1
napalm-ansible==0.9.1

Network operating system version

(Paste verbatim output from show version - or equivalent - between quotes below)

RP/0/RP0/CPU0:xrv-1#sho version
Tue Feb 23 04:09:40.200 UTC
Cisco IOS XR Software, Version 7.1.1
Copyright (c) 2013-2020 by Cisco Systems, Inc.

Steps to Reproduce the Issue

Error Traceback

(Paste the complete traceback of the exception between quotes below)

it's related to the issue #1381
ktbyers commented 3 years ago

NAPALM 2.3.1 is obsolete. You would need to reproduce the issue in the latest released version of NAPALM (NAPALM 3.2.0)

beleof commented 3 years ago

Hey @ktbyers

we setup an environment with napalm 3.2.0, reproduce the issue.

[root@localhost bin]# pip list | grep napalm

napalm                3.2.0
napalm-ansible        1.1.0
beleof commented 3 years ago

Can you advise what commands NAPALM uses internally to get the diff out of the IOS-XR device? We run NAPALM from Ansible with replace_config: true, and when we try to delete a prefix set or other config item, diffs in the Ansible check mode look like this:

[root@localhost ansible]# cat configs/xrv-1/diff
-  !
-  prefix-set PUBLIC_ROUTES
#  prefix-set CLOUD-VPC
#    10.56.162.0/24
#  end-set
#  !
#  prefix-set CLOUD-VPC
#  end-set

While is rather informative, doing the diff on the device gives us a bit more IOS-XR-native format:

RP/0/RP0/CPU0:xrv-1(config)#load disk0:candidate_config.txt
Loading.
8885 bytes parsed in 1 sec 
RP/0/RP0/CPU0:xrv-1(config)#show configuration changes diff 
Thu Mar 11 17:33:01.679 UTC
Building configuration...
!! IOS XR Configuration 7.1.1
-  !
-  prefix-set LAS_PUBLIC_ROUTES
end

The disk0:candidate_config.txt file here is the same config file (named assembled.conf in our deployment) that is uploaded to the device using NAPALM, i.e. the very one used in the config_file: variable. We have also tried to compare thecandidate.conf and running.confafter running Ansible in check mode against the device, but diffing these gives a rather interesting result:

[root@localhost ansibleansible]# diff configs/xrv-1/candidate.conf  configs/xrv-1/running.conf
116a117
>   10.56.162.0/24

I.e. it has a subnet from a prefix-set that shouldn't be touched at all.

ktbyers commented 3 years ago

Let me try to respond on this issue tomorrow.

ktbyers commented 3 years ago

Ooops, didn't get to this yet. Still need to look into it.

beleof commented 3 years ago

@ktbyers @mirceaulinic Do we have some findings after looking to it ?

ktbyers commented 3 years ago

@beleof Can you post your playbook? So your change only drops a prefix-set and nothing else?

Here is what NAPALM does:

    def compare_replace_config(self):
        """ 
        Compare configuration to be replaced with the one on the device.

        Compare executed candidate config with the running config and
        return a diff, assuming the entire config will be replaced.

        :return:  Config diff.
        """
        diff = self._execute_config_show("show configuration changes diff")
        # Strip header lines
        diff = self.strip_config_header(diff)
        # Strip trailer line
        diff = re.sub(r"^end$", "", diff, flags=re.M)
        return diff.strip()

This is for the replace operation (which you indicated you were using above).

Code is here:

https://github.com/napalm-automation/napalm/blob/develop/napalm/pyIOSXR/iosxr.py#L636

This assumes you are using the most recent released version of NAPALM.

beleof commented 3 years ago

@ktbyers Here is the playbook to install the configuration

- name: Check if static/brownfield file exists
  stat:
    path: "{{ static_conf_dir }}/{{ inventory_hostname }}.conf"
  register: static_config

- name: Include static/brownfield configs if applicable
  copy:
    src: "{{ static_conf_dir }}/{{ inventory_hostname }}.conf"
    dest: "{{ host_tmpdir }}/z_static.conf"
  when: static_config.stat.exists == True
  changed_when: no
  check_mode: no

- name: Assemble config parts
  assemble:
    src: "{{ host_tmpdir }}/"
    dest: "{{ host_config_dir }}/assembled.conf"
  changed_when: no
  check_mode: no

- name: Install configs via napalm
  napalm_install_config:
    hostname: "{{ ansible_host }}"
    username: "{{ user|default(ansible_user) }}"
    dev_os: "{{ os }}"
    password: "{{ ansible_ssh_pass }}"
    config_file: "{{ host_config_dir }}/assembled.conf"
    commit_changes: "{{ not ansible_check_mode }}"
    diff_file: "{{ host_config_dir }}/diff"
    replace_config: true
    archive_file: "{{ host_config_dir }}/running.conf"
    candidate_file: "{{ host_config_dir }}/candidate.conf"
    timeout: "{{ napalm_config_timeout|default('150') }}"
    optional_args:
      ssl_verify: False
  tags: napalm:apply

Here we put the configuration file configs_static/xrv-1.conf to device via Nampalm/Ansible.

Yea, the diff in check mode didn't show us which command is deleted or added. Another example here, we want to delete the route policy LB_Clusters_IN and add DENY-ALL as bellow

 router bgp 65000
  neighbor-group LB_Clusters
   address-family ipv4 unicast
-   route-policy LB_Clusters_IN in
+   route-policy DENY-ALL in
    route-policy LB_Clusters_OUT out

we run the Ansible playbook in check mode and check the diff as bellow which didn't show us the exact change.

pji@las4779:~/repos/network_ansible$ cat configs/xrv-1/diff
#  router bgp 65000
#   neighbor-group LB_Clusters
#    address-family ipv4 unicast
#     route-policy LB_Clusters_IN in
#     route-policy DENY-ALL in
#    !

Not sure if we have this issue before and if can fix it in Napalm?

beleof commented 3 years ago

@ktbyers Do you have any questions about the playbook ? Can you please help try to re-produce the issue?

beleof commented 3 years ago

@ktbyers Could you please kindly take a looks of this? Please let me know if you need any more information of the issue.