diff --git a/netsim/augment/devices.py b/netsim/augment/devices.py index 33f8fb180..84b3854bb 100644 --- a/netsim/augment/devices.py +++ b/netsim/augment/devices.py @@ -94,5 +94,46 @@ def get_consolidated_device_data(node: Box, defaults: Box) -> Box: def get_provider(node: Box, defaults: Box) -> str: return node.get('provider',defaults.provider) +""" +Build module supported_on lists based on device features settings +""" +def build_module_support_lists(topology: Box) -> None: + sets = topology.defaults + devs = sets.devices + + for dname in list(devs.keys()): # Iterate over all known devices + ddata = devs[dname] + if not 'features' in ddata: # Skip devices without features + continue + + for m in list(ddata.features.keys()): # Iterate over device features + if not m in sets: + continue # Weird feature name, skip it + + mdata = sets[m] # Get module data + if not 'attributes' in mdata: # Is this a valid module? + continue # ... not without attributes + + if not 'supported_on' in mdata: # Create 'supported_on' list if needed + mdata.supported_on = [] + + if ddata.feature[m] is False and dname in mdata.supported_on: + mdata.supported_on.remove(dname) # The device DOES NOT support the module + ddata.features.pop(m) # Remove the feature so it won't crash the transformation + continue + + if not dname in mdata.supported_on: # Append device to module support list if needed + mdata.supported_on.append(dname) + + f_value = ddata.features[m] + if f_value is None or f_value is True: # Normalize features to dicts + ddata.features[m] = {} + +""" +Initial device setting augmentation: + +* Build supported_on module lists +* Future: Inherit device data from parent devices +""" def augment_device_settings(topology: Box) -> None: - pass + build_module_support_lists(topology) diff --git a/netsim/augment/main.py b/netsim/augment/main.py index 0b9d56769..6a4a02acd 100644 --- a/netsim/augment/main.py +++ b/netsim/augment/main.py @@ -14,9 +14,13 @@ from .. import devices as quirks from ..data import global_vars -def transform_setup(topology: Box) -> None: +def topology_init(topology: Box) -> None: global_vars.init(topology) augment.config.attributes(topology) + augment.devices.augment_device_settings(topology) + +def transform_setup(topology: Box) -> None: + topology_init(topology) augment.topology.check_required_elements(topology) topology.nodes = augment.nodes.create_node_dict(topology.nodes) if 'links' in topology: @@ -24,7 +28,6 @@ def transform_setup(topology: Box) -> None: augment.components.expand_components(topology) - augment.devices.augment_device_settings(topology) augment.plugin.init(topology) # Initialize plugins very early on in case they modify extra attributes augment.plugin.execute('init',topology) augment.topology.check_tools(topology) diff --git a/netsim/cli/show.py b/netsim/cli/show.py index 28f580c34..12389e952 100644 --- a/netsim/cli/show.py +++ b/netsim/cli/show.py @@ -11,6 +11,7 @@ from .. import common from .. import read_topology from .. import data +from ..augment import main DEVICES_TO_SKIP = ['none','unknown'] @@ -133,8 +134,11 @@ def show_module_support(settings: Box, args: argparse.Namespace) -> None: else: dev_mods = [ m for m in mod_list if device in settings[m].supported_on ] if args.device and args.format == 'yaml': - for m in mod_list: - result[m] = settings.devices[device].features.get(m,True) + for m in dev_mods: + f_value = settings.devices[device].features.get(m,True) + if f_value is None or (not f_value and isinstance(f_value,dict)): + f_value = True + result[m] = f_value else: result[device] = dev_mods if args.format == 'text': @@ -298,9 +302,11 @@ def run(cli_args: typing.List[str]) -> None: empty_file = "package:cli/empty.yml" loc_defaults = empty_file if args.system else "" topology = read_topology.load(empty_file,loc_defaults,"package:topology-defaults.yml") + if topology is None: common.fatal("Cannot read system settings") return + main.topology_init(topology) settings = topology.defaults show_dispatch[args.action](settings,args) diff --git a/netsim/devices/csr.yml b/netsim/devices/csr.yml index a6096b61c..763683259 100644 --- a/netsim/devices/csr.yml +++ b/netsim/devices/csr.yml @@ -16,33 +16,39 @@ group_vars: node: min_mtu: 1500 features: - bgp: - local_as: True - vrf_local_as: True - local_as_ibgp: True - activate_af: True initial: ipv4: - unnumbered: True + unnumbered: true ipv6: - lla: True - ospf: - unnumbered: True + lla: true + bfd: true + bgp: + activate_af: true + local_as: true + local_as_ibgp: true + vrf_local_as: true + eigrp: true + gateway: + protocol: + - vrrp isis: unnumbered: - ipv4: True - ipv6: True - network: True + ipv4: true + ipv6: true + network: true mpls: - ldp: True - bgp: True - vpn: True - 6pe: True + 6pe: true + bgp: true + ldp: true + vpn: true + ospf: + unnumbered: true + sr: true vlan: model: switch svi_interface_name: BDI{vlan} - gateway: - protocol: [ vrrp ] + vrf: true + vxlan: true libvirt: image: cisco/csr1000v create: diff --git a/netsim/devices/eos.yml b/netsim/devices/eos.yml index f3973b505..515783836 100644 --- a/netsim/devices/eos.yml +++ b/netsim/devices/eos.yml @@ -11,40 +11,44 @@ group_vars: ansible_network_os: eos ansible_connection: network_cli features: - bgp: - local_as: True - vrf_local_as: True - local_as_ibgp: True - activate_af: True initial: - system_mtu: True + system_mtu: true ipv4: - unnumbered: True + unnumbered: true ipv6: - lla: True - ospf: - unnumbered: True + lla: true + bfd: true + bgp: + activate_af: true + local_as: true + local_as_ibgp: true + vrf_local_as: true + evpn: + asymmetrical_irb: true + bundle: [ vlan_aware ] + irb: true + gateway: + protocol: [ anycast, vrrp ] isis: unnumbered: - ipv4: True - ipv6: True - network: True + ipv4: true + ipv6: true + network: true mpls: - ldp: True - bgp: True - vpn: True - 6pe: True + 6pe: true + bgp: true + ldp: true + vpn: true + ospf: + unnumbered: true + sr: true vlan: model: l3-switch + native_routed: true + subif_name: '{ifname}.{subif_index}' svi_interface_name: Vlan{vlan} - subif_name: "{ifname}.{subif_index}" - native_routed: True - evpn: - irb: True - asymmetrical_irb: True - bundle: [ vlan_aware ] - gateway: - protocol: [ anycast, vrrp ] + vrf: true + vxlan: true clab: interface: name: et{ifindex} diff --git a/netsim/devices/iosv.yml b/netsim/devices/iosv.yml index ef5c87ca6..9ec70a202 100644 --- a/netsim/devices/iosv.yml +++ b/netsim/devices/iosv.yml @@ -21,34 +21,37 @@ libvirt: virtualbox: image: cisco/iosv features: + bfd: true bgp: - local_as: True - vrf_local_as: True - local_as_ibgp: True - activate_af: True + local_as: true + vrf_local_as: true + local_as_ibgp: true + activate_af: true initial: ipv4: - unnumbered: False + unnumbered: false ipv6: - lla: True + lla: true ospf: - unnumbered: True + unnumbered: true isis: unnumbered: - ipv4: True - ipv6: True - network: True + ipv4: true + ipv6: true + network: true + eigrp: true mpls: - ldp: True - bgp: True - vpn: True - 6pe: True + ldp: true + bgp: true + vpn: true + 6pe: true vlan: model: router svi_interface_name: BVI{bvi} subif_name: "{ifname}.{subif_index}" - mixed_trunk: True - native_routed: True + mixed_trunk: true + native_routed: true + vrf: true gateway: protocol: [ vrrp ] external: diff --git a/netsim/modules/bfd.yml b/netsim/modules/bfd.yml index 89db2b43d..445284efe 100644 --- a/netsim/modules/bfd.yml +++ b/netsim/modules/bfd.yml @@ -1,6 +1,6 @@ # BFD (RFC 5880) default settings and attributes # -supported_on: [ srlinux, sros, iosv, csr, nxos, eos, vyos, arubacx, none ] +supported_on: [ srlinux, sros, nxos, vyos, arubacx, none ] min_echo_rx: 0 # Echo function, 0=disabled by default multiplier: 3 # Detection time multiplier, number of packets lost before down attributes: diff --git a/netsim/modules/bgp.yml b/netsim/modules/bgp.yml index c2ca0c57a..38b58a855 100644 --- a/netsim/modules/bgp.yml +++ b/netsim/modules/bgp.yml @@ -1,6 +1,6 @@ # BGP default settings and attributes # -supported_on: [ cumulus, cumulus_nvue, eos, frr, csr, iosv, nxos, asav, vsrx, vyos, routeros, +supported_on: [ cumulus, cumulus_nvue, frr, nxos, asav, vsrx, vyos, routeros, srlinux, sros, none, dellos10, routeros7, vmx, iosxr, arubacx, vptx, none ] ebgp_role: external advertise_roles: [ stub ] diff --git a/netsim/modules/eigrp.yml b/netsim/modules/eigrp.yml index 6eafb8d64..5df98ab33 100644 --- a/netsim/modules/eigrp.yml +++ b/netsim/modules/eigrp.yml @@ -1,6 +1,6 @@ # EIGRP default settings and attributes # -supported_on: [ csr, iosv, nxos, none ] +supported_on: [ nxos, none ] transform_after: [ vlan,vrf ] config_after: [ vlan ] as: 1 diff --git a/netsim/modules/evpn.yml b/netsim/modules/evpn.yml index f56197645..675140451 100644 --- a/netsim/modules/evpn.yml +++ b/netsim/modules/evpn.yml @@ -1,6 +1,6 @@ # EVPN default settings and attributes requires: [ bgp ] -supported_on: [ sros, srlinux, frr, eos, vyos, dellos10, cumulus, nxos, arubacx, vptx, none ] +supported_on: [ sros, srlinux, frr, vyos, dellos10, cumulus, nxos, arubacx, vptx, none ] no_propagate: [ start_transit_vni, transport, vlan_bundle_service, as ] transform_after: [ vlan, vxlan, vrf ] config_after: [ vlan, vxlan, vrf ] diff --git a/netsim/modules/gateway.yml b/netsim/modules/gateway.yml index 480e08328..f5cd0c986 100644 --- a/netsim/modules/gateway.yml +++ b/netsim/modules/gateway.yml @@ -1,6 +1,6 @@ # Gateway (FHRP) default settings and attributes # -supported_on: [ none, eos, cumulus, iosv, csr, nxos, sros, srlinux, vyos, dellos10, arubacx ] +supported_on: [ none, cumulus, nxos, sros, srlinux, vyos, dellos10, arubacx ] transform_after: [ vlan, vrf, ospf, isis, eigrp ] config_after: [ vlan,vrf ] id: -2 diff --git a/netsim/modules/isis.yml b/netsim/modules/isis.yml index 5ce764cc0..b45b3de4c 100644 --- a/netsim/modules/isis.yml +++ b/netsim/modules/isis.yml @@ -1,6 +1,6 @@ # ISIS default settings and attributes # -supported_on: [ eos, frr, csr, iosv, nxos, asav, vsrx, srlinux, sros, vyos, vmx, iosxr, vptx, none ] +supported_on: [ frr, nxos, asav, vsrx, srlinux, sros, vyos, vmx, iosxr, vptx, none ] area: "49.0001" type: level-2 transform_after: [ vlan,vrf ] diff --git a/netsim/modules/mpls.yml b/netsim/modules/mpls.yml index 84fd420f9..560d87496 100644 --- a/netsim/modules/mpls.yml +++ b/netsim/modules/mpls.yml @@ -1,6 +1,6 @@ # MPLS (LDP, BGP LU, L3VPN, 6PE) default settings and attributes # -supported_on: [ eos, iosv, csr, routeros, vyos, routeros7, sros, vmx, vsrx, frr, none, vptx, arubacx ] +supported_on: [ routeros, vyos, routeros7, sros, vmx, vsrx, frr, none, vptx, arubacx ] config_after: [ vlan, ospf, isis, bgp ] transform_after: [ vlan, bgp ] ldp: True diff --git a/netsim/modules/ospf.yml b/netsim/modules/ospf.yml index 6ece6f3f2..0e129f124 100644 --- a/netsim/modules/ospf.yml +++ b/netsim/modules/ospf.yml @@ -2,7 +2,7 @@ # area: 0.0.0.0 supported_on: [ - arcos, cumulus, cumulus_nvue, eos, fortios, frr, csr, iosv, nxos, vsrx, vyos, routeros, + arcos, cumulus, cumulus_nvue, fortios, frr, nxos, vsrx, vyos, routeros, srlinux, sros, dellos10, routeros7, vmx, iosxr, arubacx, vptx, none ] transform_after: [ vlan,vrf ] config_after: [ vlan ] diff --git a/netsim/modules/sr.yml b/netsim/modules/sr.yml index b68ca56ef..74d3ea518 100644 --- a/netsim/modules/sr.yml +++ b/netsim/modules/sr.yml @@ -1,7 +1,7 @@ # SR-MPLS default settings and attributes # requires: [ isis ] -supported_on: [ csr, eos, srlinux, sros, vsrx, vmx, vptx, none ] +supported_on: [ srlinux, sros, vsrx, vmx, vptx, none ] transform_after: [ vlan ] attributes: global: diff --git a/netsim/modules/vlan.yml b/netsim/modules/vlan.yml index 6e1d3c8a9..17c859c76 100644 --- a/netsim/modules/vlan.yml +++ b/netsim/modules/vlan.yml @@ -1,6 +1,6 @@ # VLAN default settings and attributes # -supported_on: [ eos, iosv, csr, vyos, dellos10, srlinux, none, routeros, nxos, frr, cumulus, sros, routeros7, vmx, vsrx, arubacx, vptx, none ] +supported_on: [ vyos, dellos10, srlinux, none, routeros, nxos, frr, cumulus, sros, routeros7, vmx, vsrx, arubacx, vptx, none ] no_propagate: [ start_vlan_id, mode ] start_vlan_id: 1000 mode: irb diff --git a/netsim/modules/vrf.yml b/netsim/modules/vrf.yml index 6b6b534f5..82841a9ac 100644 --- a/netsim/modules/vrf.yml +++ b/netsim/modules/vrf.yml @@ -1,6 +1,6 @@ # VRF default settings and attributes # -supported_on: [ eos, iosv, csr, routeros, dellos10, vyos, cumulus_nvue, nxos, srlinux, frr, cumulus, sros, routeros7, vmx, vsrx, arubacx, vptx, none ] +supported_on: [ routeros, dellos10, vyos, cumulus_nvue, nxos, srlinux, frr, cumulus, sros, routeros7, vmx, vsrx, arubacx, vptx, none ] config_after: [ vlan, ospf, isis, bgp, mpls ] transform_after: [ vlan, bgp ] as: 65000 diff --git a/netsim/modules/vxlan.yml b/netsim/modules/vxlan.yml index ee788f50c..0a2e3857b 100644 --- a/netsim/modules/vxlan.yml +++ b/netsim/modules/vxlan.yml @@ -1,6 +1,6 @@ # VXLAN default settings and attributes # -supported_on: [ eos, nxos, vyos, csr, dellos10, srlinux, frr, cumulus, sros, arubacx, vptx, none ] +supported_on: [ nxos, vyos, dellos10, srlinux, frr, cumulus, sros, arubacx, vptx, none ] requires: [ vlan ] config_after: [ vrf ] # For platforms that suppport L3 VXLAN, vrfs must be created first transform_after: [ vlan, vrf ]