Hello, my friend,

In this article, we’ll continue the evaluation of the telemetry, which we can extract from the network functions using NETCONF. The focus will be on Nokia SR OS devices.

Disclaimer

This article isn’t standalone. It’s the continuation of the previous discussion, where we have reviewed telemetry from Cisco IOS XR. Please, refer to that article to get details about topology, lab setup and initial pre-checks.

Another point, just to recap, we are focusing currently on native vendor YANG modules. OpenConfig operational YANG modules will be discussed in a separated article.

Nokia SR OS // Operational YANG modules

In Nokia SR OS world, the modules, which contains operational data has keyword “state” in their name:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ ls -l Yang/nokia/SR16_YANG/ | grep 'state'
-rwxrw-rw-. 1 aaa aaa   40648 Jun  4 17:17 nokia-state-aaa.yang
-rwxrw-rw-. 1 aaa aaa  120487 Jun  4 17:17 nokia-state-bfd.yang
-rwxrw-rw-. 1 aaa aaa    9781 Jun  4 17:17 nokia-state-card-fp.yang
-rwxrw-rw-. 1 aaa aaa   51391 Jun  4 17:17 nokia-state-card.yang
-rwxrw-rw-. 1 aaa aaa    7328 Jun  4 17:17 nokia-state-cflowd.yang
-rwxrw-rw-. 1 aaa aaa   69518 Jun  4 17:17 nokia-state-chassis.yang
-rwxrw-rw-. 1 aaa aaa   94247 Jun  4 17:17 nokia-state-filter.yang
-rwxrw-rw-. 1 aaa aaa   28780 Jun  4 17:17 nokia-state-isa-video-group.yang
-rwxrw-rw-. 1 aaa aaa    9410 Jun  4 17:17 nokia-state-isa.yang
-rwxrw-rw-. 1 aaa aaa   17963 Jun  4 17:17 nokia-state-lag.yang
-rwxrw-rw-. 1 aaa aaa  226392 Jun  4 17:17 nokia-state-log.yang
-rwxrw-rw-. 1 aaa aaa   18717 Jun  4 17:17 nokia-state-mcast-cac.yang
-rwxrw-rw-. 1 aaa aaa    3653 Jun  4 17:17 nokia-state-mcast-mgmt.yang
!
! FURTHER OUTPUT IS OMITTED

 

But comparing to Cisco IOS XR, there is a major difference in telemetry behaviour. The difference is that all the modules are collected by the end of the day in a single parent’s module called “nokia-state.yang”. Later on, you will see, how to we’ll call this module in the playbook.

As we are going to use the mentioned module, let’s discovery its structure with the help of “pyang”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
$ pyang -f tree -p Yang/nokia/SR16_YANG/ Yang/nokia/SR16_YANG/nokia-state.yang | more
Yang/nokia/SR16_YANG/nokia-state-router-igmp.yang:12: error: circular dependency for module "nokia-state-router"
Yang/nokia/SR16_YANG/nokia-state-router-ldp.yang:14: error: circular dependency for module "nokia-state-router"
Yang/nokia/SR16_YANG/nokia-state-router-mpls.yang:12: error: circular dependency for module "nokia-state-router"
Yang/nokia/SR16_YANG/nokia-state-router-ospf3.yang:14: error: circular dependency for module "nokia-state-router"
Yang/nokia/SR16_YANG/nokia-state-router-rsvp.yang:11: error: circular dependency for module "nokia-state-router"
Yang/nokia/SR16_YANG/nokia-state-submgt-pcc-rule.yang:12: error: circular dependency for module "nokia-state-service"
Yang/nokia/SR16_YANG/nokia-state-subscriber-mgmt.yang:9: warning: imported module nokia-types-filter not used
Yang/nokia/SR16_YANG/nokia-state-svc-vprn.yang:23: error: circular dependency for module "nokia-state-service"
Yang/nokia/SR16_YANG/nokia-state-svc-vprn.yang:24: error: circular dependency for module "nokia-state-subscriber-mgmt"
Yang/nokia/SR16_YANG/nokia-state-system-security-tls.yang:10: error: circular dependency for module "nokia-state-system"
Yang/nokia/SR16_YANG/nokia-state-system-security-tls.yang:11: error: circular dependency for module "nokia-state-system-security"
module: nokia-state
  +--ro state
     +--ro aaa
     |  +--ro wpp
     |  |  +--ro portal-group* [group-name]
     |  |     +--ro group-name            types-sros:named-item
     |  |     +--ro controlled-router?    types-sros:router-instance
     |  |     +--ro enabled-interfaces?   uint32
     |  |     +--ro triggered-hosts?      boolean
     |  |     +--ro host* [address]
     |  |        +--ro address                types-sros:ipv4-unicast-address
     |  |        +--ro state?                 enumeration
     |  |        +--ro serial-number?         uint32
     |  |        +--ro request-id?            uint32
     |  |        +--ro remote-port?           inet:port-number
     |  |        +--ro local-address?         types-sros:ipv4-unicast-address
     |  |        +--ro user-name?             types-sros:display-string
     |  |        +--ro service?               types-services:service-name
     |  |        +--ro mac-address?           yang:mac-address
     |  |        +--ro is-triggered?          boolean
     |  |        +--ro track-srrp-instance?   uint32
     |  |        +--ro is-mcs-backup?         boolean
     |  |        +--ro active-portal
     |  |           +--ro router-instance?   types-sros:router-instance
     |  |           +--ro name?              types-sros:named-item
     |  +--ro radius-script-policy* [name]
     |  |  +--ro name                    types-sros:named-item
     |  |  +--ro primary-oper-state?     types-sros:oper-state
     |  |  +--ro secondary-oper-state?   types-sros:oper-state
     |  +--ro radius-server-policy* [name]
     |  |  +--ro name             types-sros:named-item
     |  |  +--ro blocked-state?   enumeration
     |  |  +--ro servers
     |  |  |  +--ro server* [server-index]
     |  |  |     +--ro server-index           uint32
     |  |  |     +--ro oper-state?            enumeration
     |  |  |     +--ro out-of-service-time?   types-sros:time-duration
     |  |  |     +--ro overload-time?         types-sros:time-duration
     |  |  +--ro acct-on-off
     |  |     +--ro oper-state?    enumeration
     |  |     +--ro session-id?    types-sros:display-string-or-empty
     |  |     +--ro trigger?       enumeration
     |  |     +--ro server-name?   types-sros:named-item-or-empty
     |  |     +--ro retry-count?   uint32
     |  +--ro route-downloader* [name]
!
! FURTHER OUTPUT IS OMITTED

 

The output of the modules is extremely long. It has 19996 lines.

In the same way, as we already discussed for Cisco IOS XR operational YANG modules, all the nodes have “ro” type, what stands for read-only.

Nokia SR OS // Model-driven telemetry algorithm

As we’ve just mentioned, all the possible telemetry information could be collected from the network function running on Nokia SR OS using single YANG module, so that we can simplify the algorithm for Cisco IOS XR:

  • Construct XML message with proper YANG modules, which is “nokia-state.yang” to get data.
  • Fetch telemetry data using NETCONF/YANG
  • Parse data to extract some information

As you can see, we continue to use the same Ansible module “netconf_get”, which allows us to collect through NETCONF requested information. In the upcoming modules we’ll show how to use push-model with Kafka so that network functions sending the data themselves without NETCONF requests, but rather using gRPC/gNMI transport.

Nokia SR OS // Ansible playbook for telemetry collection

To implement the algorithm above, our playbook using roles has the following structure:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+--ansible
   +--136_lab.yml
   +--group_vars
   |  +--cisco
   |  |  +--cisco_host.yml
   |  +--nokia
   |     +--nokia_host.yml
   +--roles
      +--nokia
         +--136_lab
            +--tasks
            |  +--comapring_loop.yml
            |  +--main.yml
            +--templates
            |  +--nokia_telemetry_interfaces.j2
            |  +--nokia_telemetry_routing_bgp.j2
            |  +--nokia_telemetry_routing_ospf.j2
            +--vars
               +--XR3_infra_profile.yml

 

Let’s refresh the content of the master Ansible playbook:

1
2
3
4
5
6
7
8
9
10
11
12
$ cat 136_lab.yml
---
- hosts
: cisco
  connection
: netconf
  roles
:
    - { role
: cisco/136_lab }

- hosts
: nokia
  connection
: netconf
  roles
:
    - { role
: nokia/136_lab }
...

 

Same structure we have used more or less with all of our Ansible playbook with roles.

The “group_vars” for Nokia SR OS contains exactly the same set of parameters, as we have previously used in Cisco IOS XR:

1
2
3
4
5
6
7
$ cat group_vars/nokia/nokia_host.yml
---
ansible_network_os
: sros
ansible_user
: admin
ansible_pass
: admin
ansible_ssh_pass
: admin
...

 

Now to infrastructure profile. Actually, we don’t need it to create the proper requests opposed to what we had in Cisco IOS XR, but we’ll need them later on, when we’d extract some data from telemetry output:

1
2
3
4
5
6
7
8
9
10
11
12
$ cat roles/nokia/136_lab/vars/SR1_infra_profile.yml
---
node
:
    hostname
: SR1
    vendor
: nokia
    os
: sros
    version
: 16.0.R3
    configuration_profiles
:
        - profile
: interfaces
        - profile
: routing_ospf
        - profile
: routing_bgp
...

 

Structure of “main.yml” playbook is tailored to the algorithm mentioned above, hence it’s deviating from the Cisco IOS XR one:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
$ cat roles/nokia/136_lab/tasks/main.yml
---
- name
: VERIFICATION // {{ inventory_hostname }} // IMPORTING INFRASTRUCTURE PROFILE
  include_vars
:
      file
: "{{ inventory_hostname }}_infra_profile.yml"
      name
: PROFILE

- name
: VERIFICATION // {{ inventory_hostname }} // DELETE PREVIOUS TEST REPORT
  file
:
      dest
: /tmp/{{ inventory_hostname }}_test_report.txt
      state
: absent
  ignore_errors
: yes

- name
: VERIFICATION // {{ inventory_hostname }} // CREATING TEST REPORT
  file
:
      dest
: /tmp/{{ inventory_hostname }}_test_report.txt
      state
: touch

- name
: VERIFICATION // {{ inventory_hostname }} // FETCHING TELEMETRY DATA
  netconf_get
:
      filter
: <state xmlns="urn:nokia.com:sros:ns:yang:sr:state"/>
      display
: json
  register
: output_json

- name
: VERIFICATION // {{ inventory_hostname }} // SAVING TELEMETRY DATA
  copy
:
      content
: "{{ output_json.output | to_nice_json }}"
      dest
: /tmp/{{ inventory_hostname }}/{{ inventory_hostname }}_yang_telemetry.json

- name
: VERIFICATION // {{ inventory_hostname }} // MODIFIICATION OF COLLECTED TELEMETRY FOR PYTHON PROCESSING
  replace
:
      path
: /tmp/{{ inventory_hostname }}/{{ inventory_hostname }}_yang_telemetry.json
      regexp
: '-'
      replace
: '_'

- name
: VERIFICATION // {{ inventory_hostname }} // IMPORTING COLLECTED TELEMETRY DATA
  include_vars
:
      file
: /tmp/{{ inventory_hostname }}/{{ inventory_hostname }}_yang_telemetry.json
      name
: COLLECTED

- name
: VERIFICATION // {{ inventory_hostname }} // COLLECTING TELEMETRY AND SEARCHING DATA
  include_tasks
: comparing_loop.yml
  loop
: "{{ PROFILE.node.configuration_profiles }}"

- name
: VERIFICATION // {{ inventory_hostname }} // COMPILING REPORT
  shell
: "cat /tmp/temp_report_136_{{ inventory_hostname }}_* > /tmp/{{ inventory_hostname }}_test_report.txt"

- name
: VERIFICATION // {{ inventory_hostname }} // REPORTING READINESS
  debug
:
      msg
: "Collection of telemetry data from {{ inventory_hostname }} is done."
...

 

More details you can find in the previous article about telemetry with NETCONF/YANG in Cisco IOS XR.

The following list briefly recap what’s done in the playbook.:

  • We import the file with variables, which contains configuration profiles to check
  • We delete previous report (if it exists) and create empty file for the new one
  • Using single NETCONF GET request we collect all telemetry data and save it
  • We extract all the interesting data from telemetry and fill in predefined reports using additional playbook called “comparing_loop.yml”.
  • We combine all the pieces into in a single report file
  • We inform that job is done

Comparing loop plays important role here, that’s why we need to review its details:

1
2
3
4
5
6
7
8
$ cat roles/nokia/136_lab/tasks/comparing_loop.yml
---
- name
: VERIFICATION // {{ inventory_hostname }} // COMPARING COLLECTED TELEMETRY TO REFERENCE // {{ item.profile }}
  template
:
      src
: nokia_telemetry_{{ item.profile }}.j2
      dest
: /tmp/temp_report_136_{{ inventory_hostname }}_{{ item.profile }}.txt
      mode
: 0755
...

 

Well, this playbook is relatively easy, as we just call the appropriate template for each “configuration profile”.

The last important point, we need to take a look on before going to an execution of the playbooks, is to review the templates to extract information from telemetry. We start with the port level data:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ cat roles/nokia/136_lab/templates/nokia_telemetry_interfaces.j2
+------------------------------------------+
|     Checking of the interfaces status    |
+------------------------------------------+

{% for port_current in COLLECTED.data.state.port %}
    Port: {{ port_current.port_id }}
    Status: {{ port_current.oper_state }}

{% endfor %}

===========================================
    Verification of interfaces is done
===========================================

 

For OSPF routing protocol the following template is used:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ cat roles/nokia/136_lab/templates/nokia_telemetry_routing_ospf.j2
+------------------------------------------+
|       Checking of the OSPF status        |
+------------------------------------------+

{% for router_current in COLLECTED.data.state.router %}
{% if router_current.ospf is defined %}

  Process OSPF {{ router_current.ospf.ospf_instance }} is configured within routing context {{ router_current.router_name }}

{% for ospf_iface in router_current.ospf.area.interface %}
{% if ospf_iface.neighbor_count != '0' %}
    Neighbor:
      RID:          {{ ospf_iface.neighbor_state.router_id }}
      IP:           {{ ospf_iface.neighbor_state.address }}
      Connected to: {{ ospf_iface.interface_name }}
      Status:       {{ ospf_iface.neighbor_state.oper_state }}


{% else %}
    There is no OSPF neighbors detected on interface {{ ospf_iface.interface_name }}

{% endif %}
{% endfor%}
{% else %}
  There is no OSPF process configured within routing context {{ router_current.router_name }}
{% endif %}
{% endfor %}

===========================================
    Verification of OSPF neighbors is done
===========================================

 

We need to point out that it’s a bit more complicated than the template for Cisco IOS XR, as by default network functions running Nokia SR OS (SR 7750) has 2 routing context since 16.0.R1, one of which is “management”. It’s built in, but it isn’t something you configure.

The same logic, with looping over routing contexts is also applicable for BGP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ cat roles/nokia/136_lab/templates/nokia_telemetry_routing_bgp.j2
+------------------------------------------+
|        Checking of the BGP status        |
+------------------------------------------+

{% for router_current in COLLECTED.data.state.router %}
{% if router_current.bgp is defined %}

  Process BGP is configured within routing context {{ router_current.router_name }}
{% if router_current.bgp.neighbor is defined %}
    Neighbor:
      ID:          {{ router_current.bgp.neighbor.ip_address }}
      State:       {{ router_current.bgp.neighbor.statistics.session_state }}
      AFI/SAFI:    {% for afi in router_current.bgp.neighbor.statistics.negotiated_family %}{{ afi }} {% endfor %}


{% else %}
    There is no BGP neighbors detected

{% endif %}
{% else %}
  There is no BGP process configured within routing context {{ router_current.router_name }}
{% endif %}
{% endfor %}

===========================================
    Verification of BGP neighbors is done
===========================================

 

If you have checked the article about model-driven telemetry with Cisco IOS XR, you might have spotted that we are checking exactly the same information, which is absolutely important if we speak about any kind of automation and network baselining.

Nokia SR OS // Collecting telemetry via NETCONF/YANG with Ansible

We have reached the most exciting and the most interesting part of the article: execution of our Ansible automation and verification of the results:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
$ ansible-playbook 136_lab.yml --limit=SR1

PLAY [cisco] ***********************************************************************************************************************************************************
skipping: no hosts matched

PLAY [nokia] ***********************************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // IMPORTING INFRASTRUCTURE PROFILE] *****************************************************************************************
ok: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // DELETE PREVIOUS TEST REPORT] **********************************************************************************************
changed: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // CREATING TEST REPORT] *****************************************************************************************************
changed: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // FETCHING TELEMETRY DATA] **************************************************************************************************
ok: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // SAVING TELEMETRY DATA] ****************************************************************************************************
changed: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // MODIFIICATION OF COLLECTED TELEMETRY FOR PYTHON PROCESSING] ***************************************************************
changed: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // IMPORTING COLLECTED TELEMETRY DATA] ***************************************************************************************
ok: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // COLLECTING TELEMETRY AND SEARCHING DATA] **********************************************************************************
included: /home/aaa/ansible/roles/nokia/136_lab/tasks/comparing_loop.yml for SR1 => (item={u'profile': u'interfaces'})
included: /home/aaa/ansible/roles/nokia/136_lab/tasks/comparing_loop.yml for SR1 => (item={u'profile': u'routing_ospf'})
included: /home/aaa/ansible/roles/nokia/136_lab/tasks/comparing_loop.yml for SR1 => (item={u'profile': u'routing_bgp'})

TASK [nokia/136_lab : VERIFICATION // SR1 // COMPARING COLLECTED TELEMETRY TO REFERENCE // interfaces] *****************************************************************
ok: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // COMPARING COLLECTED TELEMETRY TO REFERENCE // routing_ospf] ***************************************************************
changed: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // COMPARING COLLECTED TELEMETRY TO REFERENCE // routing_bgp] ****************************************************************
changed: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // COMPILING REPORT] *********************************************************************************************************
changed: [SR1]

TASK [nokia/136_lab : VERIFICATION // SR1 // REPORTING READINESS] ******************************************************************************************************
ok: [SR1] => {
    "msg": "Collection of telemetry data from SR1 is done."
}

PLAY RECAP *************************************************************************************************************************************************************
SR1                        : ok=16   changed=7    unreachable=0    failed=0

 

The whole playbook is successfully executed, what is definitely good sign. Now we can review some details. First of all, let’s check how the raw telemetry data looks like:

1
2
$ ls -l /tmp/SR1/ | grep 'yang'
-rw-rw-r--. 1 aaa aaa 1396972 Oct 14 19:18 SR1_yang_telemetry.json

 

Wow. The raw text data with telemetry in YANG format from Nokia SR OS device (7750 SR-1 or VSR in this case) is almost 1,4. Megabytes. That’s huge amount of information.

Let’s take a look into details, what we have there:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
$ cat SR1_yang_telemetry.json
{
    "data": {
        "state": {
            "aaa": {
                "wpp": ""
            },
            "bfd": "",
            "card": {
                "available_mda_slots": "2",
                "clock_source": "none",
                "equipped_level": "he",
                "equipped_type": "iom_1",
                "fp": {
                    "fp_number": "1",
                    "generation": "fp4",
                    "ingress": "",
                    "statistics": {
                        "buffer_memory_error": "0",
                        "cam_error": "0",
                        "egress_fcs_error": "0",
                        "ingress_fcs_error": "0",
                        "internal_datapath_cell_error": "0",
                        "internal_datapath_error": "0",
                        "internal_memory_error": "0",
                        "memory_parity_error": "0",
                        "source_slots_egress_fcs_error": "",
                        "statistics_memory_error": "0"
                    },
                    "total_policy_accounting_in_use": "0"
                },
                "hardware_data": {
                    "alarm_state": "alarm_cleared",
                    "base_mac_address": "02:65:01:00:00:00",
                    "boot_code_version": "simulated",
                    "common_language_equipment_identifier": "Sim CLEI",
                    "contained_in": "Chassis 1",
                    "contains_temperature_sensor": "true",
                    "equipped_platform_type": "platform_7750",
                    "failure_reason": "",
                    "field_replaceable_unit": "true",
                    "firmware_code_version": "",
                    "firmware_revision_status": "acceptable",
                    "manufacturing_assembly_number": "01_2345_67",
                    "manufacturing_date": "01012003",
                    "manufacturing_deviations": "Sim MfgDeviation card_1",
                    "oper_state": "in_service",
                    "part_number": "f362a30add1e466d80a3607438c87d22",
                    "power_zone_location": "1",
                    "serial_number": "card_1",
                    "software_code_version": "TiMOS_B_16.0.R3 both/x86_64 Nokia 7750 SR Copyright (c) 2000_2018 Nokia.\nAll rights reserved. All use subject to applicab
le license agreements.\nBuilt on Wed Aug 29 12:48:09 PDT 2018 by builder in /builds/160B/R3/panos/main",
                    "software_image_source": "unknown",
                    "software_last_boot_time": "2018_10_14T14:19:26.0Z",
                    "temperature": "_128",
                    "temperature_threshold": "75"
                },
                "installed_mda_slots": "1",
                "last_bootup_reason": "hard_reboot",
                "licensed_bandwidth": "80",
                "licensed_level": "he",
                "mda": [
                    {
                        "access": {
                            "ingress": ""
                        },
                        "capabilities": "ethernet",
                        "channels_in_use": "0",
                        "equipped_ports": "6",
                        "equipped_type": "me6_100gb_qsfp28",
                        "hardware_data": {
!
! FURTHER OUTPUT IS OMITTED

 

You remember, previously we told that the that YANG module we called here has almost 20 thousand lines of entries… And that’s just the YANG module, without multiple interfaces and so on. So you can imagine, how much information we have here. You can spend a lot of information reviewing what we have. But for now, we’ll check the status of our report, which includes:

  • Status of the interfaces
  • Status of the OSPF neighbors
  • Status of the BGP peering

As we have merged everything together, let’s verify the final one:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
$ cat /tmp/SR1_test_report.txt
+------------------------------------------+
|     Checking of the interfaces status    |
+------------------------------------------+

    Port: 1/1/c1
    Status: up

    Port: 1/1/c1/1
    Status: up

    Port: 1/1/c1/2
    Status: down

    Port: 1/1/c1/3
    Status: down

    Port: 1/1/c1/4
    Status: down

    Port: 1/1/c2
    Status: up

    Port: 1/1/c2/1
    Status: down

    Port: 1/1/c2/2
    Status: down

    Port: 1/1/c2/3
    Status: down

    Port: 1/1/c2/4
    Status: down

    Port: 1/1/c3
    Status: down

    Port: 1/1/c4
    Status: down

    Port: 1/1/c5
    Status: down

    Port: 1/1/c6
    Status: down

    Port: A/1
    Status: up

    Port: A/4
    Status: down


===========================================
    Verification of interfaces is done
===========================================
+------------------------------------------+
|        Checking of the BGP status        |
+------------------------------------------+


  Process BGP is configured within routing context Base
    Neighbor:
      ID:          10.0.0.33
      State:       Established
      AFI/SAFI:    VPN_IPv4 VPN_IPv6

  There is no BGP process configured within routing context management


===========================================
    Verification of BGP neighbors is done
===========================================
+------------------------------------------+
|       Checking of the OSPF status        |
+------------------------------------------+


  Process OSPF 0 is configured within routing context Base

    There are no OSPF neighbors detected on an interface system

    Neighbor:
      RID:          10.0.0.33
      IP:           10.11.33.33
      Connected to: uplink1
      Status:       full

  There is no OSPF process configured within routing context management


===========================================
    Verification of OSPF neighbors is done
===========================================

 

You see that some operational data (name of variables, I mean) deviates from Cisco IOS XR to Nokia SR OS. I can easily imagine that another vendor will have many different names. But what is important, we can match them on our own so that we can create a real visualization of our baseline.

Here you can find the playbooks from this lab: 138_lab.tar

Lessons learned

I must admit. I haven’t shown you everything I wanted. In the context of interfaces, I have shown the only status of the port (physical and data link layer), but I haven’t shown you the network layer, meaning IPv4/IPv6 addresses and so on. The reason for that I haven’t managed to create the proper template in Jinja2 or some bugs in Ansible / associated Python modules. The template I tried was quite similar to one I’ve used in OSPF:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ cat roles/nokia/136_lab/templates/nokia_telemetry_interfaces.j2
{% for router_current in COLLECTED.data.state.router %}
{% if router_current.interface is defined %}

  The following interfaces are configured within routing context {{ router_current.router_name }}

{% for iface in router_current.interface %}
    Interface:       {{ iface.interface_name }}
    Status:          {{ iface.if_oper_status }}

{% endfor %}
{% else %}
    There are no interfaces configured within routing context {{ router_current.router_name }}

{% endif %}
{% endfor %}

 

But during execution of the playbook, I was constantly getting error:

1
2
TASK [nokia/136_lab : VERIFICATION // SR1 // COMPARING COLLECTED TELEMETRY TO REFERENCE // interfaces] *****************************************************************
fatal: [SR1]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'unicode object' has no attribute 'interface_name'"}

 

I’ve found on some forums that there might be problems with importing long JSON structure and processing them as variables, but, of course, I might have made some mistakes. If anybody will try this template, let me know your results. As it hasn’t worked, I don’t include it in general package.

Conclusion

In this and in the previous article we have reviewed the telemetry information, which we can collect in vendor native models for Cisco IOS XR and Nokia (Alcatel-Lucent) SR OS respectively. Telemetry provides a lot of information, what we can use for building our business logic in the network. On the other hand, those require manual model creation per vendor. In the next article, we’ll take a look on OpenConfig modules again with the aim to get telemetry in a vendor-neutral manner. Take care and goodbye!

Support us





P.S.

If you have further questions or you need help with your networks, I’m happy to assist you, just send me a message (http://karneliuk.com/contact/). Also don’t forget to share the article on your social media, if you like it.

BR,
Anton Karneliuk