diff --git a/docs/caveats.md b/docs/caveats.md index 47e94b1e2a..1991663697 100644 --- a/docs/caveats.md +++ b/docs/caveats.md @@ -408,6 +408,15 @@ ansible-galaxy collection install community.network * EXOS does not support the same VRRP group for IPv4 and IPv6 * Saved EXOS device configuration includes commands that cannot be configured on the EXOS VM. _netlab_ therefore cannot do a configuration reload for EXOS devices. +(caveats-voss)= +## Extreme Networks VOSS + +* The only way to configure VOSS devices with Ansible is the now-deprecated **community.network.voss_config** Ansible module. This collection is no longer actively maintained. To install it, you can still run: + +```shell +ansible-galaxy collection install community.network +``` + (caveats-fortios)= ## Fortinet FortiOS diff --git a/docs/labs/clab.md b/docs/labs/clab.md index b0f1239dd8..a34206c47b 100644 --- a/docs/labs/clab.md +++ b/docs/labs/clab.md @@ -47,6 +47,7 @@ Lab topology file created by **[netlab up](../netlab/up.md)** or **[netlab creat | Citrix Netscaler | netlab/netscaler:latest | | Dell OS10 | vrnetlab/vr-ftosv | | dnsmasq | netlab/dnsmasq:latest | +| Extreme VOSS | vrnetlab/extreme_voss:9.4.0.0 | | Fortinet FortiOS | vrnetlab/vr-fortios:7.4.8 | | FRR | quay.io/frrouting/frr:10.1.2 | | Juniper vMX | vrnetlab/vr-vmx:18.2R1.9 | diff --git a/netsim/ansible/tasks/deploy-config/voss.yml b/netsim/ansible/tasks/deploy-config/voss.yml new file mode 100644 index 0000000000..3179d556ed --- /dev/null +++ b/netsim/ansible/tasks/deploy-config/voss.yml @@ -0,0 +1,5 @@ +## voss_config is deprecated with no obvious replacement +- name: "voss_config: deploying {{ netsim_action }} from {{ config_template }}" + community.network.voss_config: + src: "{{ config_template }}" + tags: [ print_action, always ] diff --git a/netsim/ansible/tasks/readiness-check/voss.yml b/netsim/ansible/tasks/readiness-check/voss.yml new file mode 100644 index 0000000000..752a0fff2a --- /dev/null +++ b/netsim/ansible/tasks/readiness-check/voss.yml @@ -0,0 +1,15 @@ +--- +- name: Wait for CLI to be ready on VOSS devices + ansible.netcommon.cli_command: + command: "{{ netlab_check_command | default('show sys-info | head 5') }}" + register: cli_out + until: cli_out.stdout is defined and cli_out.stdout | length > 0 + retries: "{{ netlab_check_retries | default(40) }}" + delay: "{{ netlab_check_delay | default(10) }}" + failed_when: false + changed_when: false + +- name: Confirm VOSS CLI is ready + debug: + msg: "Node {{ inventory_hostname }} is ready." + when: cli_out.stdout is defined and cli_out.stdout | length > 0 diff --git a/netsim/ansible/templates/initial/voss.j2 b/netsim/ansible/templates/initial/voss.j2 new file mode 100644 index 0000000000..14f80fa158 --- /dev/null +++ b/netsim/ansible/templates/initial/voss.j2 @@ -0,0 +1,36 @@ +sys name {{ inventory_hostname.replace("_","-") }} +{# +no router isis enable +y +#} + +router isis +{# spbm 1 #} +{# spbm 1 nick-name 1.11.11 #} +spbm 1 b-vid 4051,4052 primary 4051 +manual-area 49.0001 +{# system-id 1234.0000.0001 #} +exit + +{% if vlans is defined %} +{% include 'voss.vlan.j2' %} +{% endif %} + +{% for l in netlab_interfaces if l.type|default('') not in ['loopback'] %} +{% if l.type|default('') == 'svi' %} +interface vlan {{ vlans[l.vlan.name].id }} +{% if l.ipv4 is defined and l.ipv4 is string and l.ipv4|ansible.utils.ipv4 %} +ip address {{ l.ipv4|ansible.utils.ipaddr('address') }} {{ l.ipv4|ansible.utils.ipaddr('netmask') }} +{% endif %} +exit +{% else %} +interface {{ l.ifname }} +{% if l.name is defined %} +name "{{ l.name | replace('->','to') }}" +{% elif l.type|default('') == 'stub' %} +name "Stub" +{% endif %} +no shutdown +exit +{% endif %} +{% endfor %} diff --git a/netsim/ansible/templates/initial/voss.vlan.j2 b/netsim/ansible/templates/initial/voss.vlan.j2 new file mode 100644 index 0000000000..d635ab2d09 --- /dev/null +++ b/netsim/ansible/templates/initial/voss.vlan.j2 @@ -0,0 +1,7 @@ +{% for vname,vdata in vlans.items() %} +{% if vname|lower != 'default' and vdata.id != 1 %} +vlan create {{ vdata.id }} name "{{ vname }}" type port-mstprstp 0 +{# Extend the VLAN over the SPB fabric, I-SID derived from the VLAN ID (placeholder until an SPB module exists) #} +vlan i-sid {{ vdata.id }} {{ 10000 + vdata.id }} +{% endif %} +{% endfor +%} diff --git a/netsim/ansible/templates/vlan/voss.j2 b/netsim/ansible/templates/vlan/voss.j2 new file mode 100644 index 0000000000..9d0df2281f --- /dev/null +++ b/netsim/ansible/templates/vlan/voss.j2 @@ -0,0 +1,26 @@ +{% for ifdata in interfaces if ifdata.vlan is defined and ifdata.type|default('') not in ['svi','vlan_member'] %} +{% set port = ifdata.ifname.split(' ')[-1] %} +{% if ifdata.vlan.trunk is defined %} +interface {{ ifdata.ifname }} +encapsulation dot1q +exit +{% for vname in ifdata.vlan.trunk.keys()|sort %} +vlan members add {{ vlans[vname].id }} {{ port }} +{% endfor %} +{% if ifdata.vlan.native is defined %} +interface {{ ifdata.ifname }} +default-vlan-id {{ vlans[ifdata.vlan.native].id }} +untag-port-default-vlan enable +exit +{% endif %} +{% if 'default' not in ifdata.vlan.trunk.keys()|map('lower') %} +vlan members remove 1 {{ port }} +{% endif %} +{% elif ifdata.vlan.access is defined %} +vlan members remove 1 {{ port }} +vlan members add {{ vlans[ifdata.vlan.access].id }} {{ port }} +interface {{ ifdata.ifname }} +default-vlan-id {{ vlans[ifdata.vlan.access].id }} +exit +{% endif %} +{% endfor +%} diff --git a/netsim/devices/exos.yml b/netsim/devices/exos.yml index f9261b7860..8b91c6f627 100644 --- a/netsim/devices/exos.yml +++ b/netsim/devices/exos.yml @@ -30,7 +30,7 @@ libvirt: create_template: exos.xml.j2 image: netlab/exos clab: - build: True + build: https://github.com/srl-labs/vrnetlab/tree/master/extreme/exos image: vrnetlab/extreme_exos features: initial: diff --git a/netsim/devices/voss.yml b/netsim/devices/voss.yml new file mode 100644 index 0000000000..1e2fb5066e --- /dev/null +++ b/netsim/devices/voss.yml @@ -0,0 +1,56 @@ +--- +description: Extreme VOSS +support: + level: minimal +interface_name: "GigabitEthernet 1/{ifindex}" +loopback_interface_name: "loopback {ifindex}" +ifindex_offset: 1 +mgmt_if: Mgmt +features: + initial: + min_mtu: 1500 + max_mtu: 9216 + # ra: true + # normalize: true + # collect: true + # reload: false + # isis: + # circuit_type: true + # #import: [ bgp, ospf, ripv2, connected, static, vrf ] + # unnumbered: + # ipv4: true + # ipv6: true + # network: true + vlan: + model: switch + svi_interface_name: vlan{vlan} + +clab: + build: https://github.com/srl-labs/vrnetlab/tree/master/extreme/voss + image: vrnetlab/extreme_voss + features: + initial: + healthcheck: true + node: + kind: linux # kind not yet available in Containerlab + env: + CLAB_MGMT_PASSTHROUGH: "true" + interface: + name: "eth{ifindex}" + group_vars: + ansible_user: vrnetlab + ansible_ssh_pass: VR-netlab9 + netlab_ready: [ ansible ] # VOSS SSH ignores exec requests (rc=255), so the ssh check never passes + netlab_check_retries: 40 + netlab_check_delay: 10 +group_vars: + ansible_password: rwa + ansible_network_os: voss + ansible_connection: ansible.netcommon.network_cli + ansible_become: true + ansible_become_method: enable + netlab_console_connection: ssh + netlab_ready: [ ansible ] +external: + image: none +graphite.icon: switch