Skip to content

Commit 1644bb8

Browse files
authored
Simplified SR OS configuration deployment (#2306)
* Move gNMI checks into readiness tasklist * Cleanup the configuration deployment tasklist to use Jinja2 lookup with gNMI-only deployment * Remove MD-CLI templates * Generate complete interface name in device data * Generate 'loopback.X' or 'system' loopback name in device data * Treat system interface like any other interface in initial configuration deployment Minor changes: * Add VLAN to interface description only if VLAN != 0 * Set description of additional loopbacks to "loopback"
1 parent 34f498f commit 1644bb8

7 files changed

Lines changed: 48 additions & 318 deletions

File tree

Lines changed: 20 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,26 @@
11
---
2+
- name: Generate gNMI YAML configuration
3+
set_fact: yaml_config={{ lookup('template',config_template) }}
24

3-
- name: Check that required plugin exists, use 'netlab install grpc' to install it
4-
vars:
5-
ansible_connection: nokia.grpc.gnmi
6-
register: plugin_checked
7-
when: plugin_checked is not defined
8-
nokia.grpc.gnmi_config:
9-
prefix: test-plugin
10-
11-
- local_action:
12-
module: tempfile
13-
state: file
14-
suffix: temp
15-
prefix: ansible.sros.{{ inventory_hostname }}.
16-
register: tempfile_1
17-
18-
- name: Set default provisioning model to use OpenConfig (sros_use_openconfig={{sros_use_openconfig}})
19-
when: sros_use_openconfig|default(true)
20-
set_fact:
21-
sros_provisioning_model: "sros.openconfig"
22-
23-
# - name: Example how to check if a BGP RR is being used
24-
# vars:
25-
# rr: "{{ groups['all']|map('extract',hostvars)|map(attribute='bgp.rr')|list }}"
26-
# set_fact:
27-
# uses_route_reflector: "{{ rr != [] }}"
28-
29-
- name: Check if OpenConfig can be used as provisioning method/model (config_template={{config_template}})
30-
when: "'ospf' in config_template or 'sr' in module|default([]) or not sros_use_openconfig|default(True)"
31-
set_fact:
32-
sros_provisioning_model: "sros" # Default: without '.gnmi'
33-
34-
- name: Select provisioning template netsim_action={{ netsim_action }}
35-
set_fact:
36-
template_to_use: "{{ config_template|replace('sros.j2',sros_provisioning_model+'.j2') }}"
37-
38-
- name: Process template {{ template_to_use }}
39-
local_action:
40-
module: template
41-
src: "{{ template_to_use }}"
42-
dest: "{{ tempfile_1.path }}"
43-
44-
- block:
45-
- name: Show generated config from {{template_to_use}} based on {{tempfile_1.path}}
46-
debug: msg="{{ cfg }}" verbosity=1
47-
48-
- name: Check that prepared config from {{template_to_use}} in {{tempfile_1.path}} is valid YAML
49-
debug: msg="{{ cfg | from_yaml }}" verbosity=2
50-
51-
vars:
52-
cfg: "{{ lookup('file', tempfile_1.path ) }}"
53-
54-
- name: Wait up to 180s for gNMI(TCP {{sros_grpc_port}}) to be ready on {{ ansible_host }}
55-
local_action:
56-
module: wait_for
57-
port: "{{ sros_grpc_port }}"
58-
host: "{{ ansible_host }}"
59-
connect_timeout: 60
60-
timeout: 180
61-
sleep: 10 # Wait 10s between attempts
62-
63-
- block:
64-
- block:
65-
- name: Enable Open Config YAML modules (retry to give Containerlab a chance to finish configuration)
66-
when: enable_open_config is not defined and 'ixr-ec' != clab.type
67-
tags: [ initial ]
68-
nokia.grpc.gnmi_config:
69-
prefix: configure
70-
update:
71-
- path: system/management-interface/yang-modules/openconfig-modules
72-
val: True # {{ sros_provisioning_model == "sros.openconfig" }}
73-
register: enable_open_config
74-
retries: 4
75-
delay: 15
76-
until: enable_open_config is success
77-
78-
rescue:
79-
- name: reset the gNMI connection, then try one more time
80-
meta: reset_connection
81-
82-
- debug: var=enable_open_config
83-
# - debug: var=hostvars
84-
85-
- name: Update {{ netsim_action }} node configuration (using gNMI SET based on YAML template {{template_to_use}})
86-
when: d or u or r
87-
vars:
88-
cfg: "{{ lookup('file', tempfile_1.path ) | from_yaml }}"
89-
d: "{{ cfg.delete if 'delete' in cfg and cfg.delete is not string else [] }}"
90-
u: "{{ cfg.updates if 'updates' in cfg and cfg.updates is not string else [] }}"
91-
r: "{{ cfg.replace if 'replace' in cfg and cfg.replace is not string else [] }}"
92-
nokia.grpc.gnmi_config:
93-
# prefix: configure
94-
delete: "{{ d }}"
95-
replace: "{{ r }}"
96-
update: "{{ u }}"
97-
register: gnmi_set_result
98-
retries: "{{ 2 if ansible_verbosity==0 else 0 }}"
99-
until: gnmi_set_result is success
100-
tags: [ print_action, always ]
101-
102-
- debug: var=gnmi_set_result
103-
5+
- name: Update {{ netsim_action }} node configuration from gNMI template {{ config_template }}
6+
when: d or u or r
1047
vars:
8+
cfg: "{{ yaml_config | from_yaml }}"
9+
d: "{{ cfg.delete if 'delete' in cfg and cfg.delete is not string else [] }}"
10+
u: "{{ cfg.updates if 'updates' in cfg and cfg.updates is not string else [] }}"
11+
r: "{{ cfg.replace if 'replace' in cfg and cfg.replace is not string else [] }}"
10512
ansible_connection: nokia.grpc.gnmi
10613
ansible_gnmi_encoding: JSON
10714
ansible_port: "{{ sros_grpc_port }}"
108-
109-
# Alternative: ansible.netcommon.cli_command
110-
# Uses network_cli connection
111-
# - community.network.sros_command:
112-
# - nokia.sros.md:
113-
# commands: "{{ lookup('file', tempfile_1.path ).splitlines() }}"
114-
115-
# Let's use Netconf + OpenConfig
116-
# - name: use lookup filter to provide xml configuration
117-
#netconf_config:
118-
# xml: "{{ lookup('file', tempfile_1.path) }}"
119-
# host: "{{ ansible_host }}"
120-
# username: "{{ ansible_user }}"
121-
# password: "{{ ansible_ssh_pass }}"
122-
# community.yang.configure:
123-
124-
# - name: Fetch given yang model and its dependencies from remote host
125-
# community.yang.fetch:
126-
# # name: Nokia
127-
# dir: "{{playbook_dir}}/{{inventory_hostname}}/yang_files"
128-
# register: result
129-
#
130-
# - name: configure interface using structured data in JSON format
131-
# community.yang.configure:
132-
# config: "{{ lookup('file', tempfile_1.path) | to_json }}"
133-
# file: "{{ playbook_dir }}/{{inventory_hostname}}/yang_files/Nokia-ifmgr-cfg.yang"
134-
# search_path: "{{ playbook_dir }}/{{inventory_hostname}}/yang_files"
135-
# register: result
136-
137-
- local_action:
138-
module: file
139-
path: "{{ tempfile_1.path }}"
140-
state: absent
141-
when: tempfile_1.path is defined
15+
nokia.grpc.gnmi_config:
16+
# prefix: configure
17+
delete: "{{ d }}"
18+
replace: "{{ r }}"
19+
update: "{{ u }}"
20+
register: gnmi_set_result
21+
retries: "{{ 2 if ansible_verbosity==0 else 0 }}"
22+
until: gnmi_set_result is success
23+
tags: [ print_action, always ]
24+
25+
- debug: var=gnmi_set_result
26+
when: ansible_verbosity
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
- name: Check that required plugin exists, use 'netlab install grpc' to install it
2+
vars:
3+
ansible_connection: nokia.grpc.gnmi
4+
nokia.grpc.gnmi_config:
5+
prefix: test-plugin
6+
7+
- name: Wait up to 180s for gNMI(TCP {{sros_grpc_port}}) to be ready on {{ ansible_host }}
8+
local_action:
9+
module: wait_for
10+
port: "{{ sros_grpc_port }}"
11+
host: "{{ ansible_host }}"
12+
connect_timeout: 60
13+
timeout: 180
14+
sleep: 5

netsim/ansible/templates/bgp/sros.md-cli.j2

Lines changed: 0 additions & 93 deletions
This file was deleted.

netsim/ansible/templates/initial/sros.j2

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
{% macro if_name(i,name=None) -%}
2-
{% set _name = name or i.ifname %}
3-
{% set _pre = "stub-" if i.type|default()=='stub' else 'i' if _name[0].isdigit() else "" %}
4-
{{- (('oc_%s%s/1_0' if sros_use_openconfig|default(true) else '%s%s')|format(_pre,_name)).replace(':','_') -}}
2+
{{ name or i.ifname }}
53
{%- endmacro %}
64

75
{% macro declare_router(i,sub_path="") -%}
@@ -46,7 +44,7 @@
4644
{{ declare_interface(l,name) }}
4745
val:
4846
admin-state: enable
49-
description: "{{ desc }} vlan={{vlan}}"
47+
description: "{{ desc }}{{ 'vlan= '+vlan|string if vlan else '' }}"
5048
{% if port %}
5149
{% if l.vrf is defined %}
5250
sap:
@@ -80,13 +78,18 @@
8078
{% set v6 = l.ipv6|default(False) %}
8179
{% set in_base = l.vrf is not defined and (l.vlan is not defined or l.vlan.mode|default('irb')=='route') %}
8280

83-
{% if l.name is defined %}
81+
{% if l.ifname == "system" %}
82+
{% set desc = "System interface" %}
83+
{% elif l.type == "loopback" %}
84+
{% set desc = "Loopback" %}
85+
{% elif l.name is defined %}
8486
{% set desc = l.name|replace('->','~') + " (" + l.role|default('') + ")" %}
85-
{% elif l.type|default("") == "stub" %}
87+
{% elif l.type == "stub" %}
8688
{% set desc = "Stub interface" %}
8789
{% endif %}
8890

8991
{% set portname = l.parent_ifname if l.type=='vlan_member' else l.ifname %}
92+
{% set portname = portname.replace('eth-','') %}
9093
{% if 'ixr' in clab.type and clab.type != 'ixr-x' %}
9194
{# Remove connector from port name for IXR platform #}
9295
{% set portname = portname.replace("c","") %}
@@ -122,7 +125,7 @@
122125
{% endif %}
123126

124127
{% if v4 or v6 %}
125-
{% if l.type not in ['loopback','stub','svi'] %}
128+
{% if l.type not in ['loopback','svi'] %}
126129
{{ interface(l.ifname,desc,v4,v6,portname,l,vlan=vlan) }}
127130
{% else %}
128131
{{ interface(l.ifname,desc,v4,v6,None,l) }}
@@ -152,13 +155,6 @@ updates:
152155
val:
153156
ecmp: {{ 1 if 'ixr' in clab.type else 64 }}
154157

155-
{% if loopback is defined %}
156-
{% set _v4 = loopback.ipv4|default(False) %}
157-
{% set _v6 = loopback.ipv6|default(False) %}
158-
{# The interface name 'system' is special, also used for IP unnumbered #}
159-
{{ interface("system","system interface",_v4,_v6,port=None,l=loopback) }}
160-
{% endif %}
161-
162-
{% for l in (interfaces|default([])) if l.vlan is not defined and l.subif_index is not defined %}
158+
{% for l in netlab_interfaces if l.vlan is not defined and l.subif_index is not defined %}
163159
{{ port(l) }}
164160
{% endfor %}

netsim/ansible/templates/initial/sros.md-cli.j2

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)