diff --git a/docs/plugins.md b/docs/plugins.md index 29d21c3ed..4244c8126 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -14,6 +14,7 @@ plugins/check.config.md plugins/fabric.md plugins/multilab.md + plugins/node.clone.md plugins/vrrp.version.md ``` diff --git a/docs/plugins/node.clone.md b/docs/plugins/node.clone.md new file mode 100644 index 000000000..9e928ea6d --- /dev/null +++ b/docs/plugins/node.clone.md @@ -0,0 +1,67 @@ +(plugin-node-clone)= +# Dealing with large amounts of identical devices + +The *node.clone* plugin avoids tedious repetitive work by allowing users to mark any node for cloning. Any node with a **clone** attribute gets cloned N times, duplicating links and any group memberships. + +```eval_rst +.. contents:: Table of Contents + :depth: 2 + :local: + :backlinks: none +``` + +## Using the Plugin + +* Add `plugin: [ node.clone ]` to the lab topology. +* Include the **clone** attribute in any nodes that need to be replicated multiple times. + +The plugin is invoked early in the _netlab_ topology transformation process and updates groups and adds nodes and links to the lab topology. + +### Supported attributes + +The naming of cloned nodes can be controlled through global **clone.node_name_pattern**, default "{name[:13]}-{id:02d}". +When customizing, it is recommended to ensure this generates valid DNS hostnames (of max length 16) + +The plugin adds the following node attributes: +* **clone.count** is a required int (>0) that defines the number of clones to create +* **clone.start** is the index to start at, default 1 +* **clone.step** is an optional step increase between clones, default 1 + +### Caveats + +The plugin does not support: +* link groups +* cloning of components (nodes composed of multiple nodes) + +When custom **ifindex** or **lag.ifindex** values are specified, the plugin automatically increments the value for each clone. This may generate overlapping/conflicting values, which will typically show up as duplicate interface names. It is the user's responsibility to ensure that custom values don't overlap. + +Avoid the use of static IPv4/v6 attributes for clones, they are not checked nor automatically updated, and will likely lead to duplicate IP addresses. + +## Examples + +(host-cluster)= +### Connect Multiple Hosts to a ToR + +The following lab topology has a cluster of 10 hosts all connected to a Top-of-Rack switch in the same way. +The clones will be called H_01, H_02, ... + +```yaml +plugin: [ node.clone ] + +vlans: + v1: + +nodes: + ToR: + device: frr + module: [ vlan ] + H: + device: linux + clone.count: 10 + +links: +- ToR: + ifindex: 4 # Start from port 4 + vlan.access: v1 + H: +``` diff --git a/netsim/extra/node.clone/defaults.yml b/netsim/extra/node.clone/defaults.yml new file mode 100644 index 000000000..60b97921f --- /dev/null +++ b/netsim/extra/node.clone/defaults.yml @@ -0,0 +1,11 @@ +# node.clone plugin attributes and defaults +# +--- +clone: + node_name_pattern: "{name[:13]}-{id:02d}" # Result should be a valid identifier, can use '-' in node names + + attributes: + node: + clone: { type: int, min_value: 1, _required: True } # Create N copies of this node anywhere it's used in groups or links + start: int # Optional ID to start with, default 1 + step: int # Optional increment between clones, default 1 diff --git a/netsim/extra/node.clone/plugin.py b/netsim/extra/node.clone/plugin.py new file mode 100644 index 000000000..d76d8c4f0 --- /dev/null +++ b/netsim/extra/node.clone/plugin.py @@ -0,0 +1,139 @@ +from box import Box +from netsim import data +from netsim.utils import log,strings +from netsim.augment import links + +""" +clone_link - makes a copy of the given link for each clone, updating its node +""" +def clone_link(link_data: Box, nodename: str, clones: list[str]) -> list[Box]: + cloned_links = [] + if nodename in [ i.node for i in link_data.get('interfaces',[]) ]: + for c,clone in enumerate(clones): + l = data.get_box(link_data) + l.interfaces = [] + for intf in link_data.interfaces: + intf_clone = data.get_box(intf) + if intf.node == nodename: + intf_clone.node = clone + elif 'ifindex' in intf: # Update port on the peer side, if any + intf_clone.ifindex = intf.ifindex + c + l.interfaces.append(intf_clone) + cloned_links.append(l) + return cloned_links + +""" +clone_lag - special routine to handle cloning of lag links +""" +def clone_lag(cnt: int, link_data: Box, nodename: str, clones: list[str], topology: Box) -> list[Box]: + lag_members = link_data.get('lag.members') + cloned_members = process_links(lag_members,f"lag[{cnt+1}].m",nodename,clones,topology) + if not cloned_members: # If no lag members involve + return [] # .. exit + + cloned_lag_links = [] + for c,clone in enumerate(clones): + l = data.get_box(link_data) # Clone the lag link + if l.get('lag.ifindex',0): + l.lag.ifindex = l.lag.ifindex + c # Update its ifindex, if any + l.lag.members = [] + for clonelist in cloned_members: + for intf in clonelist[c].interfaces: # Update ifindex on interfaces + if 'ifindex' in intf: + intf.ifindex += c # May generate overlapping values + l.lag.members.append( clonelist[c] ) + cloned_lag_links.append(l) + return cloned_lag_links + +""" +process_links - iterate over the 'links' attribute for the given item and clone any instances that involve node + can be the global topology or a VLAN or VRF object with 'links' + + Returns a list of a list of cloned links +""" +def process_links(linkitems: list, linkprefix: str, nodename: str, clones: list, topology: Box) -> list[list[Box]]: + result: list[list[Box]] = [] + for cnt,l in enumerate(list(linkitems)): + link_data = links.adjust_link_object( # Create link data from link definition + l=l, + linkname=f'{linkprefix}links[{cnt+1}]', + nodes=topology.nodes) + if link_data is None: + continue + elif link_data.get('lag.members',None): + cloned_links = clone_lag(cnt,link_data,nodename,clones,topology) + else: + cloned_links = clone_link(link_data,nodename,clones) + + if cloned_links: + linkitems.remove(l) + linkitems += cloned_links + result.append(cloned_links) + return result + +""" +update_links - updates 'links' lists in VLAN and VRF objects +""" +def update_links(topo_items: str, nodename: str, clones: list, topology: Box) -> None: + for vname,vdata in topology[topo_items].items(): # Iterate over global VLANs or VRFs + if isinstance(vdata,Box) and 'links' in vdata: + process_links(vdata.links,f'{topo_items}.{vname}.',nodename,clones,topology) + +""" +clone_node - Clones a given node N times, creating additional links and/or interfaces for the new nodes +""" +def clone_node(node: Box, topology: Box) -> None: + _p = { 'start': 1, 'step': 1 } + node.pop('clone',{}) # Define cloning parameters + if 'count' not in _p: + log.error("Node {node.name} missing required attribute clone.count", # Not validated by Netlab yet + category=AttributeError, module='node.clone') + return + + if 'include' in node: # Check for components + log.error("Cannot clone component {node.name}, only elementary nodes", + category=AttributeError, module='node.clone') + return + + name_format = topology.defaults.clone.node_name_pattern + clones = [] + for c in range(_p.start,_p.start+_p.count*_p.step,_p.step): + clone = data.get_box(node) + clone.name = strings.eval_format(name_format, node + { 'id': c } ) + + if clone.name in topology.nodes: # Check for overlapping names + log.error("Generated clone name '{clone.name}' conflicts with an existing node", + category=AttributeError, module='node.clone') + return + + clone.interfaces = [] # Start clean, remove reference to original node + if 'id' in node: + clone.id = node.id + c - 1 # Update any explicit node ID sequentially + topology.nodes[ clone.name ] = clone + clones.append( clone.name ) + + if 'links' in topology: + process_links(topology.links,"",node.name,clones,topology) + + if 'groups' in topology: + for groupname,gdata in topology.groups.items(): + if groupname[0]=='_': # Skip flags and other special items + continue + if node.name in gdata.get('members',[]): + gdata.members.remove( node.name ) + gdata.members.extend( clones ) + + if 'vlans' in topology: + update_links('vlans',node.name,clones,topology) + + if 'vrfs' in topology: + update_links('vrfs',node.name,clones,topology) + + topology.nodes.pop(node.name,None) # Finally + +""" +topology_expand - Main plugin function, expands the topology with cloned nodes and interfaces +""" +def topology_expand(topology: Box) -> None: + for node in list(topology.nodes.values()): + if 'clone' in node: + clone_node( node, topology ) diff --git a/tests/topology/expected/node.clone-plugin-lag.yml b/tests/topology/expected/node.clone-plugin-lag.yml new file mode 100644 index 000000000..bfc0d9d12 --- /dev/null +++ b/tests/topology/expected/node.clone-plugin-lag.yml @@ -0,0 +1,1174 @@ +groups: + routers: + device: eos + members: + - r1 + - r2 + module: + - vlan + - lag +input: +- topology/input/node.clone-plugin-lag.yml +- package:topology-defaults.yml +lag: + lacp: fast + lacp_mode: active + mode: 802.3ad +links: +- _linkname: links[1].peerlink[1] + interfaces: + - ifindex: 1 + ifname: Ethernet1 + node: r1 + - ifindex: 1 + ifname: Ethernet1 + node: r2 + lag: + mlag: + peergroup: 1 + linkindex: 1 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[2] + bridge: input_2 + interfaces: + - ifindex: 30000 + ifname: port-channel8 + node: r1 + - ifindex: 30000 + ifname: bond8 + node: h-01 + lag: + ifindex: 8 + linkindex: 2 + node_count: 2 + pool: l2only + type: lag +- _linkname: links[3] + bridge: input_3 + interfaces: + - ifindex: 30001 + ifname: port-channel9 + node: r1 + - ifindex: 30000 + ifname: bond9 + node: h-02 + lag: + ifindex: 9 + linkindex: 3 + node_count: 2 + pool: l2only + type: lag +- _linkname: links[4] + bridge: input_4 + interfaces: + - ifindex: 30000 + ifname: port-channel1 + node: r2 + - ifindex: 30001 + ifname: bond1 + node: h-01 + lag: + ifindex: 1 + linkindex: 4 + node_count: 2 + pool: l2only + type: lag +- _linkname: links[5] + bridge: input_5 + interfaces: + - ifindex: 30001 + ifname: port-channel2 + node: r2 + - ifindex: 30001 + ifname: bond2 + node: h-02 + lag: + ifindex: 2 + linkindex: 5 + node_count: 2 + pool: l2only + type: lag +- _linkname: links[6] + bridge: input_6 + interfaces: + - _vlan_mode: irb + ifindex: 30000 + ifname: bond1 + ipv4: 172.16.0.5/24 + lag: + ifindex: 1 + node: h2-01 + vlan: + access: red + - _vlan_mode: irb + ifindex: 30002 + ifname: port-channel3 + ipv4: 172.16.0.1/24 + lag: + _mlag: true + node: r1 + vlan: + access: red + - _vlan_mode: irb + ifindex: 30002 + ifname: port-channel3 + ipv4: 172.16.0.2/24 + lag: + _mlag: true + node: r2 + vlan: + access: red + lag: + ifindex: 3 + linkindex: 6 + node_count: 3 + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 + type: lag + vlan: + access: red +- _linkname: links[7] + bridge: input_7 + interfaces: + - _vlan_mode: irb + ifindex: 30000 + ifname: bond1 + ipv4: 172.16.0.6/24 + lag: + ifindex: 1 + node: h2-02 + vlan: + access: red + - _vlan_mode: irb + ifindex: 30003 + ifname: port-channel4 + ipv4: 172.16.0.1/24 + lag: + _mlag: true + node: r1 + vlan: + access: red + - _vlan_mode: irb + ifindex: 30003 + ifname: port-channel4 + ipv4: 172.16.0.2/24 + lag: + _mlag: true + node: r2 + vlan: + access: red + lag: + ifindex: 4 + linkindex: 7 + node_count: 3 + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 + type: lag + vlan: + access: red +- _linkname: links[2].lag[1] + interfaces: + - ifindex: 2 + ifname: Ethernet2 + node: r1 + - ifindex: 1 + ifname: eth1 + node: h-01 + lag: + _parentindex: 2 + linkindex: 8 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[2].lag[2] + interfaces: + - ifindex: 3 + ifname: Ethernet3 + node: r1 + - ifindex: 2 + ifname: eth2 + node: h-01 + lag: + _parentindex: 2 + linkindex: 9 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[3].lag[1] + interfaces: + - ifindex: 4 + ifname: Ethernet4 + node: r1 + - ifindex: 1 + ifname: eth1 + node: h-02 + lag: + _parentindex: 3 + linkindex: 10 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[3].lag[2] + interfaces: + - ifindex: 5 + ifname: Ethernet5 + node: r1 + - ifindex: 2 + ifname: eth2 + node: h-02 + lag: + _parentindex: 3 + linkindex: 11 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[4].lag[1] + interfaces: + - ifindex: 6 + ifname: Ethernet6 + node: r2 + - ifindex: 3 + ifname: eth3 + node: h-01 + lag: + _parentindex: 4 + linkindex: 12 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[4].lag[2] + interfaces: + - ifindex: 7 + ifname: Ethernet7 + node: r2 + - ifindex: 4 + ifname: eth4 + node: h-01 + lag: + _parentindex: 4 + linkindex: 13 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[5].lag[1] + interfaces: + - ifindex: 8 + ifname: Ethernet8 + node: r2 + - ifindex: 3 + ifname: eth3 + node: h-02 + lag: + _parentindex: 5 + linkindex: 14 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[5].lag[2] + interfaces: + - ifindex: 9 + ifname: Ethernet9 + node: r2 + - ifindex: 4 + ifname: eth4 + node: h-02 + lag: + _parentindex: 5 + linkindex: 15 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[6].lag[1] + interfaces: + - ifindex: 1 + ifname: eth1 + node: h2-01 + - ifindex: 6 + ifname: Ethernet6 + node: r1 + lag: + _parentindex: 6 + linkindex: 16 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[6].lag[2] + interfaces: + - ifindex: 2 + ifname: eth2 + node: h2-01 + - ifindex: 2 + ifname: Ethernet2 + node: r2 + lag: + _parentindex: 6 + linkindex: 17 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[7].lag[1] + interfaces: + - ifindex: 1 + ifname: eth1 + node: h2-02 + - ifindex: 7 + ifname: Ethernet7 + node: r1 + lag: + _parentindex: 7 + linkindex: 18 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[7].lag[2] + interfaces: + - ifindex: 2 + ifname: eth2 + node: h2-02 + - ifindex: 3 + ifname: Ethernet3 + node: r2 + lag: + _parentindex: 7 + linkindex: 19 + node_count: 2 + prefix: false + type: p2p +module: +- lag +- vlan +name: input +nodes: + h-01: + af: + ipv4: true + box: debian/bookworm64 + device: frr + id: 3 + interfaces: + - ifindex: 30000 + ifname: bond8 + lag: + ifindex: 8 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 2 + name: h-01 -> r1 + neighbors: + - ifname: port-channel8 + node: r1 + pool: l2only + type: lag + virtual_interface: true + - ifindex: 30001 + ifname: bond1 + lag: + ifindex: 1 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 4 + name: h-01 -> r2 + neighbors: + - ifname: port-channel1 + node: r2 + pool: l2only + type: lag + virtual_interface: true + - ifindex: 1 + ifname: eth1 + lag: + _parentindex: 2 + linkindex: 8 + name: h-01 -> r1 + neighbors: + - ifname: Ethernet2 + node: r1 + type: p2p + - ifindex: 2 + ifname: eth2 + lag: + _parentindex: 2 + linkindex: 9 + name: h-01 -> r1 + neighbors: + - ifname: Ethernet3 + node: r1 + type: p2p + - ifindex: 3 + ifname: eth3 + lag: + _parentindex: 4 + linkindex: 12 + name: h-01 -> r2 + neighbors: + - ifname: Ethernet6 + node: r2 + type: p2p + - ifindex: 4 + ifname: eth4 + lag: + _parentindex: 4 + linkindex: 13 + name: h-01 -> r2 + neighbors: + - ifname: Ethernet7 + node: r2 + type: p2p + lag: + lacp: fast + lacp_mode: active + mode: 802.3ad + loopback: + ifindex: 0 + ifname: lo + ipv4: 10.0.0.3/32 + neighbors: [] + type: loopback + virtual_interface: true + mgmt: + ifname: eth0 + ipv4: 192.168.121.103 + mac: 08:4f:a9:00:00:03 + module: + - lag + - vlan + name: h-01 + h-02: + af: + ipv4: true + box: debian/bookworm64 + device: frr + id: 4 + interfaces: + - ifindex: 30000 + ifname: bond9 + lag: + ifindex: 9 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 3 + name: h-02 -> r1 + neighbors: + - ifname: port-channel9 + node: r1 + pool: l2only + type: lag + virtual_interface: true + - ifindex: 30001 + ifname: bond2 + lag: + ifindex: 2 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 5 + name: h-02 -> r2 + neighbors: + - ifname: port-channel2 + node: r2 + pool: l2only + type: lag + virtual_interface: true + - ifindex: 1 + ifname: eth1 + lag: + _parentindex: 3 + linkindex: 10 + name: h-02 -> r1 + neighbors: + - ifname: Ethernet4 + node: r1 + type: p2p + - ifindex: 2 + ifname: eth2 + lag: + _parentindex: 3 + linkindex: 11 + name: h-02 -> r1 + neighbors: + - ifname: Ethernet5 + node: r1 + type: p2p + - ifindex: 3 + ifname: eth3 + lag: + _parentindex: 5 + linkindex: 14 + name: h-02 -> r2 + neighbors: + - ifname: Ethernet8 + node: r2 + type: p2p + - ifindex: 4 + ifname: eth4 + lag: + _parentindex: 5 + linkindex: 15 + name: h-02 -> r2 + neighbors: + - ifname: Ethernet9 + node: r2 + type: p2p + lag: + lacp: fast + lacp_mode: active + mode: 802.3ad + loopback: + ifindex: 0 + ifname: lo + ipv4: 10.0.0.4/32 + neighbors: [] + type: loopback + virtual_interface: true + mgmt: + ifname: eth0 + ipv4: 192.168.121.104 + mac: 08:4f:a9:00:00:04 + module: + - lag + - vlan + name: h-02 + h2-01: + af: + ipv4: true + box: debian/bookworm64 + device: frr + id: 5 + interfaces: + - ifindex: 30000 + ifname: bond1 + lag: + ifindex: 1 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 6 + name: '[Access VLAN red] h2-01 -> [r1,r2]' + neighbors: + - ifname: port-channel3 + ipv4: 172.16.0.1/24 + node: r1 + - ifname: port-channel3 + ipv4: 172.16.0.2/24 + node: r2 + type: lag + virtual_interface: true + vlan: + access: red + access_id: 1000 + - ifindex: 1 + ifname: eth1 + lag: + _parentindex: 6 + linkindex: 16 + name: h2-01 -> r1 + neighbors: + - ifname: Ethernet6 + node: r1 + type: p2p + - ifindex: 2 + ifname: eth2 + lag: + _parentindex: 6 + linkindex: 17 + name: h2-01 -> r2 + neighbors: + - ifname: Ethernet2 + node: r2 + type: p2p + - bridge_group: 1 + ifindex: 3 + ifname: vlan1000 + ipv4: 172.16.0.5/24 + name: VLAN red (1000) -> [r2,r1,h2-02] + neighbors: + - ifname: Vlan1000 + ipv4: 172.16.0.2/24 + node: r2 + - ifname: Vlan1000 + ipv4: 172.16.0.1/24 + node: r1 + - ifname: vlan1000 + ipv4: 172.16.0.6/24 + node: h2-02 + type: svi + virtual_interface: true + vlan: + mode: irb + name: red + lag: + lacp: fast + lacp_mode: active + mode: 802.3ad + loopback: + ifindex: 0 + ifname: lo + ipv4: 10.0.0.5/32 + neighbors: [] + type: loopback + virtual_interface: true + mgmt: + ifname: eth0 + ipv4: 192.168.121.105 + mac: 08:4f:a9:00:00:05 + module: + - lag + - vlan + name: h2-01 + vlan: + max_bridge_group: 1 + vlans: + red: + bridge_group: 1 + id: 1000 + mode: irb + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 + h2-02: + af: + ipv4: true + box: debian/bookworm64 + device: frr + id: 6 + interfaces: + - ifindex: 30000 + ifname: bond1 + lag: + ifindex: 1 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 7 + name: '[Access VLAN red] h2-02 -> [r1,r2]' + neighbors: + - ifname: port-channel4 + ipv4: 172.16.0.1/24 + node: r1 + - ifname: port-channel4 + ipv4: 172.16.0.2/24 + node: r2 + type: lag + virtual_interface: true + vlan: + access: red + access_id: 1000 + - ifindex: 1 + ifname: eth1 + lag: + _parentindex: 7 + linkindex: 18 + name: h2-02 -> r1 + neighbors: + - ifname: Ethernet7 + node: r1 + type: p2p + - ifindex: 2 + ifname: eth2 + lag: + _parentindex: 7 + linkindex: 19 + name: h2-02 -> r2 + neighbors: + - ifname: Ethernet3 + node: r2 + type: p2p + - bridge_group: 1 + ifindex: 3 + ifname: vlan1000 + ipv4: 172.16.0.6/24 + name: VLAN red (1000) -> [h2-01,r2,r1] + neighbors: + - ifname: vlan1000 + ipv4: 172.16.0.5/24 + node: h2-01 + - ifname: Vlan1000 + ipv4: 172.16.0.2/24 + node: r2 + - ifname: Vlan1000 + ipv4: 172.16.0.1/24 + node: r1 + type: svi + virtual_interface: true + vlan: + mode: irb + name: red + lag: + lacp: fast + lacp_mode: active + mode: 802.3ad + loopback: + ifindex: 0 + ifname: lo + ipv4: 10.0.0.6/32 + neighbors: [] + type: loopback + virtual_interface: true + mgmt: + ifname: eth0 + ipv4: 192.168.121.106 + mac: 08:4f:a9:00:00:06 + module: + - lag + - vlan + name: h2-02 + vlan: + max_bridge_group: 1 + vlans: + red: + bridge_group: 1 + id: 1000 + mode: irb + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 + r1: + af: + ipv4: true + box: arista/veos + device: eos + id: 1 + interfaces: + - ifindex: 1 + ifname: Ethernet1 + lag: + mlag: + ifindex: 4094 + peer: 169.254.127.0 + peergroup: 1 + self: 169.254.127.1/31 + vlan: 4094 + linkindex: 1 + name: r1 -> r2 + neighbors: + - ifname: Ethernet1 + node: r2 + type: p2p + - ifindex: 30000 + ifname: port-channel8 + lag: + ifindex: 8 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 2 + name: r1 -> h-01 + neighbors: + - ifname: bond8 + node: h-01 + pool: l2only + type: lag + virtual_interface: true + - ifindex: 30001 + ifname: port-channel9 + lag: + ifindex: 9 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 3 + name: r1 -> h-02 + neighbors: + - ifname: bond9 + node: h-02 + pool: l2only + type: lag + virtual_interface: true + - ifindex: 30002 + ifname: port-channel3 + lag: + _mlag: true + ifindex: 3 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 6 + name: '[Access VLAN red] r1 -> [h2-01,r2]' + neighbors: + - ifname: bond1 + ipv4: 172.16.0.5/24 + node: h2-01 + - ifname: port-channel3 + ipv4: 172.16.0.2/24 + node: r2 + type: lag + virtual_interface: true + vlan: + access: red + access_id: 1000 + - ifindex: 30003 + ifname: port-channel4 + lag: + _mlag: true + ifindex: 4 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 7 + name: '[Access VLAN red] r1 -> [h2-02,r2]' + neighbors: + - ifname: bond1 + ipv4: 172.16.0.6/24 + node: h2-02 + - ifname: port-channel4 + ipv4: 172.16.0.2/24 + node: r2 + type: lag + virtual_interface: true + vlan: + access: red + access_id: 1000 + - ifindex: 2 + ifname: Ethernet2 + lag: + _parentindex: 2 + linkindex: 8 + name: r1 -> h-01 + neighbors: + - ifname: eth1 + node: h-01 + type: p2p + - ifindex: 3 + ifname: Ethernet3 + lag: + _parentindex: 2 + linkindex: 9 + name: r1 -> h-01 + neighbors: + - ifname: eth2 + node: h-01 + type: p2p + - ifindex: 4 + ifname: Ethernet4 + lag: + _parentindex: 3 + linkindex: 10 + name: r1 -> h-02 + neighbors: + - ifname: eth1 + node: h-02 + type: p2p + - ifindex: 5 + ifname: Ethernet5 + lag: + _parentindex: 3 + linkindex: 11 + name: r1 -> h-02 + neighbors: + - ifname: eth2 + node: h-02 + type: p2p + - ifindex: 6 + ifname: Ethernet6 + lag: + _parentindex: 6 + linkindex: 16 + name: r1 -> h2-01 + neighbors: + - ifname: eth1 + node: h2-01 + type: p2p + - ifindex: 7 + ifname: Ethernet7 + lag: + _parentindex: 7 + linkindex: 18 + name: r1 -> h2-02 + neighbors: + - ifname: eth1 + node: h2-02 + type: p2p + - bridge_group: 1 + ifindex: 8 + ifname: Vlan1000 + ipv4: 172.16.0.1/24 + name: VLAN red (1000) -> [h2-01,r2,h2-02] + neighbors: + - ifname: vlan1000 + ipv4: 172.16.0.5/24 + node: h2-01 + - ifname: Vlan1000 + ipv4: 172.16.0.2/24 + node: r2 + - ifname: vlan1000 + ipv4: 172.16.0.6/24 + node: h2-02 + type: svi + virtual_interface: true + vlan: + mode: irb + name: red + lag: + lacp: fast + lacp_mode: active + mode: 802.3ad + loopback: + ifindex: 0 + ifname: Loopback0 + ipv4: 10.0.0.1/32 + neighbors: [] + type: loopback + virtual_interface: true + mgmt: + ifname: Management1 + ipv4: 192.168.121.101 + mac: 08:4f:a9:00:00:01 + module: + - lag + - vlan + name: r1 + vlan: + max_bridge_group: 1 + vlans: + red: + bridge_group: 1 + id: 1000 + mode: irb + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 + r2: + _set_ifindex: true + af: + ipv4: true + box: arista/veos + device: eos + id: 2 + interfaces: + - ifindex: 1 + ifname: Ethernet1 + lag: + mlag: + ifindex: 4094 + peer: 169.254.127.1 + peergroup: 1 + self: 169.254.127.0/31 + vlan: 4094 + linkindex: 1 + name: r2 -> r1 + neighbors: + - ifname: Ethernet1 + node: r1 + type: p2p + - ifindex: 2 + ifname: Ethernet2 + lag: + _parentindex: 6 + linkindex: 17 + name: r2 -> h2-01 + neighbors: + - ifname: eth2 + node: h2-01 + type: p2p + - ifindex: 3 + ifname: Ethernet3 + lag: + _parentindex: 7 + linkindex: 19 + name: r2 -> h2-02 + neighbors: + - ifname: eth2 + node: h2-02 + type: p2p + - bridge_group: 1 + ifindex: 4 + ifname: Vlan1000 + ipv4: 172.16.0.2/24 + name: VLAN red (1000) -> [h2-01,r1,h2-02] + neighbors: + - ifname: vlan1000 + ipv4: 172.16.0.5/24 + node: h2-01 + - ifname: Vlan1000 + ipv4: 172.16.0.1/24 + node: r1 + - ifname: vlan1000 + ipv4: 172.16.0.6/24 + node: h2-02 + type: svi + virtual_interface: true + vlan: + mode: irb + name: red + - ifindex: 5 + ifname: Ethernet5 + linkindex: 0 + neighbors: [] + remote_id: 2 + remote_ifindex: 666 + type: p2p + - ifindex: 6 + ifname: Ethernet6 + lag: + _parentindex: 4 + linkindex: 12 + name: r2 -> h-01 + neighbors: + - ifname: eth3 + node: h-01 + type: p2p + - ifindex: 7 + ifname: Ethernet7 + lag: + _parentindex: 4 + linkindex: 13 + name: r2 -> h-01 + neighbors: + - ifname: eth4 + node: h-01 + type: p2p + - ifindex: 8 + ifname: Ethernet8 + lag: + _parentindex: 5 + linkindex: 14 + name: r2 -> h-02 + neighbors: + - ifname: eth3 + node: h-02 + type: p2p + - ifindex: 9 + ifname: Ethernet9 + lag: + _parentindex: 5 + linkindex: 15 + name: r2 -> h-02 + neighbors: + - ifname: eth4 + node: h-02 + type: p2p + - ifindex: 30000 + ifname: port-channel1 + lag: + ifindex: 1 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 4 + name: r2 -> h-01 + neighbors: + - ifname: bond1 + node: h-01 + pool: l2only + type: lag + virtual_interface: true + - ifindex: 30001 + ifname: port-channel2 + lag: + ifindex: 2 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 5 + name: r2 -> h-02 + neighbors: + - ifname: bond2 + node: h-02 + pool: l2only + type: lag + virtual_interface: true + - ifindex: 30002 + ifname: port-channel3 + lag: + _mlag: true + ifindex: 3 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 6 + name: '[Access VLAN red] r2 -> [h2-01,r1]' + neighbors: + - ifname: bond1 + ipv4: 172.16.0.5/24 + node: h2-01 + - ifname: port-channel3 + ipv4: 172.16.0.1/24 + node: r1 + type: lag + virtual_interface: true + vlan: + access: red + access_id: 1000 + - ifindex: 30003 + ifname: port-channel4 + lag: + _mlag: true + ifindex: 4 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 7 + name: '[Access VLAN red] r2 -> [h2-02,r1]' + neighbors: + - ifname: bond1 + ipv4: 172.16.0.6/24 + node: h2-02 + - ifname: port-channel4 + ipv4: 172.16.0.1/24 + node: r1 + type: lag + virtual_interface: true + vlan: + access: red + access_id: 1000 + lag: + lacp: fast + lacp_mode: active + mode: 802.3ad + libvirt: + nic_adapter_count: 10 + loopback: + ifindex: 0 + ifname: Loopback0 + ipv4: 10.0.0.2/32 + neighbors: [] + type: loopback + virtual_interface: true + mgmt: + ifname: Management1 + ipv4: 192.168.121.102 + mac: 08:4f:a9:00:00:02 + module: + - lag + - vlan + name: r2 + vlan: + max_bridge_group: 1 + vlans: + red: + bridge_group: 1 + id: 1000 + mode: irb + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 +plugin: +- node.clone +provider: libvirt +vlans: + red: + host_count: 0 + id: 1000 + neighbors: + - ifname: vlan1000 + ipv4: 172.16.0.5/24 + node: h2-01 + - ifname: Vlan1000 + ipv4: 172.16.0.2/24 + node: r2 + - ifname: Vlan1000 + ipv4: 172.16.0.1/24 + node: r1 + - ifname: vlan1000 + ipv4: 172.16.0.6/24 + node: h2-02 + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 diff --git a/tests/topology/expected/node.clone-plugin.yml b/tests/topology/expected/node.clone-plugin.yml new file mode 100644 index 000000000..0b356a9f1 --- /dev/null +++ b/tests/topology/expected/node.clone-plugin.yml @@ -0,0 +1,1196 @@ +groups: + hosts: + members: + - h-03 + - h-07 + - host_w_long_n-01 + - host_w_long_n-02 + - host_w_long_n-03 +input: +- topology/input/node.clone-plugin.yml +- package:topology-defaults.yml +lag: + lacp: fast + lacp_mode: active + mode: 802.3ad +links: +- _linkname: links[1] + interfaces: + - ifindex: 16 + ifname: eth16 + ipv4: 10.1.0.2/30 + node: r + - ifindex: 1 + ifname: eth1 + ipv4: 10.1.0.1/30 + mtu: 1600 + node: h-03 + linkindex: 1 + node_count: 2 + prefix: + ipv4: 10.1.0.0/30 + type: p2p +- _linkname: links[2] + interfaces: + - ifindex: 17 + ifname: eth17 + ipv4: 10.1.0.6/30 + node: r + - ifindex: 1 + ifname: eth1 + ipv4: 10.1.0.5/30 + mtu: 1600 + node: h-07 + linkindex: 2 + node_count: 2 + prefix: + ipv4: 10.1.0.4/30 + type: p2p +- _linkname: links[3] + bridge: input_3 + interfaces: + - ifindex: 30000 + ifname: bond5 + ipv4: 10.1.0.9/30 + node: r + - ifindex: 30000 + ifname: bond5 + ipv4: 10.1.0.10/30 + node: h-03 + lag: + ifindex: 5 + linkindex: 3 + node_count: 2 + prefix: + ipv4: 10.1.0.8/30 + type: lag +- _linkname: links[4] + bridge: input_4 + interfaces: + - ifindex: 30001 + ifname: bond6 + ipv4: 10.1.0.13/30 + node: r + - ifindex: 30000 + ifname: bond6 + ipv4: 10.1.0.14/30 + node: h-07 + lag: + ifindex: 6 + linkindex: 4 + node_count: 2 + prefix: + ipv4: 10.1.0.12/30 + type: lag +- _linkname: links[5] + bridge: input_5 + interfaces: + - ifindex: 30002 + ifname: bond1 + ipv4: 10.1.0.17/30 + node: r + - ifindex: 30001 + ifname: bond1 + ipv4: 10.1.0.18/30 + node: h-03 + lag: + ifindex: 1 + linkindex: 5 + node_count: 2 + prefix: + ipv4: 10.1.0.16/30 + type: lag +- _linkname: links[6] + bridge: input_6 + interfaces: + - ifindex: 30003 + ifname: bond2 + ipv4: 10.1.0.21/30 + node: r + - ifindex: 30001 + ifname: bond2 + ipv4: 10.1.0.22/30 + node: h-07 + lag: + ifindex: 2 + linkindex: 6 + node_count: 2 + prefix: + ipv4: 10.1.0.20/30 + type: lag +- _linkname: links[7] + bridge: input_7 + gateway: + ipv4: 172.16.1.1/24 + interfaces: + - ifindex: 1 + ifname: eth1 + ipv4: 172.16.1.1/24 + node: r + - ifindex: 1 + ifname: eth1 + ipv4: 172.16.1.10/24 + node: host_w_long_n-01 + linkindex: 7 + node_count: 2 + prefix: + ipv4: 172.16.1.0/24 + role: stub + type: lan +- _linkname: links[8] + bridge: input_8 + gateway: + ipv4: 172.16.2.1/24 + interfaces: + - ifindex: 2 + ifname: eth2 + ipv4: 172.16.2.1/24 + node: r + - ifindex: 1 + ifname: eth1 + ipv4: 172.16.2.11/24 + node: host_w_long_n-02 + linkindex: 8 + node_count: 2 + prefix: + ipv4: 172.16.2.0/24 + role: stub + type: lan +- _linkname: links[9] + bridge: input_9 + gateway: + ipv4: 172.16.3.1/24 + interfaces: + - ifindex: 3 + ifname: eth3 + ipv4: 172.16.3.1/24 + node: r + - ifindex: 1 + ifname: eth1 + ipv4: 172.16.3.12/24 + node: host_w_long_n-03 + linkindex: 9 + node_count: 2 + prefix: + ipv4: 172.16.3.0/24 + role: stub + type: lan +- _linkname: links[3].lag[1] + interfaces: + - ifindex: 4 + ifname: eth4 + node: r + - ifindex: 2 + ifname: eth2 + node: h-03 + lag: + _parentindex: 3 + linkindex: 10 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[3].lag[2] + interfaces: + - ifindex: 5 + ifname: eth5 + node: r + - ifindex: 3 + ifname: eth3 + node: h-03 + lag: + _parentindex: 3 + linkindex: 11 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[4].lag[1] + interfaces: + - ifindex: 6 + ifname: eth6 + node: r + - ifindex: 2 + ifname: eth2 + node: h-07 + lag: + _parentindex: 4 + linkindex: 12 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[4].lag[2] + interfaces: + - ifindex: 7 + ifname: eth7 + node: r + - ifindex: 3 + ifname: eth3 + node: h-07 + lag: + _parentindex: 4 + linkindex: 13 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[5].lag[1] + interfaces: + - ifindex: 20 + ifname: eth20 + node: r + - ifindex: 4 + ifname: eth4 + node: h-03 + lag: + _parentindex: 5 + linkindex: 14 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[5].lag[2] + interfaces: + - ifindex: 21 + ifname: eth21 + node: r + - ifindex: 5 + ifname: eth5 + node: h-03 + lag: + _parentindex: 5 + linkindex: 15 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[6].lag[1] + interfaces: + - ifindex: 22 + ifname: eth22 + node: r + - ifindex: 4 + ifname: eth4 + node: h-07 + lag: + _parentindex: 6 + linkindex: 16 + node_count: 2 + prefix: false + type: p2p +- _linkname: links[6].lag[2] + interfaces: + - ifindex: 23 + ifname: eth23 + node: r + - ifindex: 5 + ifname: eth5 + node: h-07 + lag: + _parentindex: 6 + linkindex: 17 + node_count: 2 + prefix: false + type: p2p +- _linkname: vlans.red.links[1] + bridge: input_18 + interfaces: + - _vlan_mode: irb + ifindex: 8 + ifname: eth8 + ipv4: 172.16.0.1/24 + node: r + vlan: + access: red + - _vlan_mode: irb + ifindex: 6 + ifname: eth6 + ipv4: 172.16.0.2/24 + node: h-03 + vlan: + access: red + linkindex: 18 + node_count: 2 + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 + type: lan + vlan: + access: red +- _linkname: vlans.red.links[2] + bridge: input_19 + interfaces: + - _vlan_mode: irb + ifindex: 9 + ifname: eth9 + ipv4: 172.16.0.1/24 + node: r + vlan: + access: red + - _vlan_mode: irb + ifindex: 6 + ifname: eth6 + ipv4: 172.16.0.3/24 + node: h-07 + vlan: + access: red + linkindex: 19 + node_count: 2 + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 + type: lan + vlan: + access: red +- _linkname: vrfs.red.links[1] + interfaces: + - ifindex: 10 + ifname: eth10 + ipv4: 10.1.0.26/30 + node: r + - ifindex: 7 + ifname: eth7 + ipv4: 10.1.0.25/30 + node: h-03 + linkindex: 20 + node_count: 2 + prefix: + ipv4: 10.1.0.24/30 + type: p2p + vrf: red +- _linkname: vrfs.red.links[2] + interfaces: + - ifindex: 11 + ifname: eth11 + ipv4: 10.1.0.30/30 + node: r + - ifindex: 7 + ifname: eth7 + ipv4: 10.1.0.29/30 + node: h-07 + linkindex: 21 + node_count: 2 + prefix: + ipv4: 10.1.0.28/30 + type: p2p + vrf: red +module: +- lag +- vlan +- vrf +name: input +nodes: + h-03: + af: + ipv4: true + vpnv4: true + box: debian/bookworm64 + device: frr + id: 2 + interfaces: + - ifindex: 1 + ifname: eth1 + ipv4: 10.1.0.1/30 + linkindex: 1 + mtu: 1600 + name: h-03 -> r + neighbors: + - ifname: eth16 + ipv4: 10.1.0.2/30 + node: r + type: p2p + - ifindex: 30000 + ifname: bond5 + ipv4: 10.1.0.10/30 + lag: + ifindex: 5 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 3 + name: h-03 -> r + neighbors: + - ifname: bond5 + ipv4: 10.1.0.9/30 + node: r + type: lag + virtual_interface: true + - ifindex: 30001 + ifname: bond1 + ipv4: 10.1.0.18/30 + lag: + ifindex: 1 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 5 + name: h-03 -> r + neighbors: + - ifname: bond1 + ipv4: 10.1.0.17/30 + node: r + type: lag + virtual_interface: true + - ifindex: 2 + ifname: eth2 + lag: + _parentindex: 3 + linkindex: 10 + name: h-03 -> r + neighbors: + - ifname: eth4 + node: r + type: p2p + - ifindex: 3 + ifname: eth3 + lag: + _parentindex: 3 + linkindex: 11 + name: h-03 -> r + neighbors: + - ifname: eth5 + node: r + type: p2p + - ifindex: 4 + ifname: eth4 + lag: + _parentindex: 5 + linkindex: 14 + name: h-03 -> r + neighbors: + - ifname: eth20 + node: r + type: p2p + - ifindex: 5 + ifname: eth5 + lag: + _parentindex: 5 + linkindex: 15 + name: h-03 -> r + neighbors: + - ifname: eth21 + node: r + type: p2p + - bridge: input_18 + ifindex: 6 + ifname: eth6 + linkindex: 18 + name: '[Access VLAN red] h-03 -> r' + neighbors: + - ifname: eth8 + ipv4: 172.16.0.1/24 + node: r + type: lan + vlan: + access: red + access_id: 1000 + - ifindex: 7 + ifname: eth7 + ipv4: 10.1.0.25/30 + linkindex: 20 + name: h-03 -> r + neighbors: + - ifname: eth10 + ipv4: 10.1.0.26/30 + node: r + vrf: red + type: p2p + vrf: red + - bridge_group: 1 + ifindex: 8 + ifname: vlan1000 + ipv4: 172.16.0.2/24 + name: VLAN red (1000) -> [r,h-07] + neighbors: + - ifname: vlan1000 + ipv4: 172.16.0.1/24 + node: r + - ifname: vlan1000 + ipv4: 172.16.0.3/24 + node: h-07 + type: svi + virtual_interface: true + vlan: + mode: irb + name: red + lag: + lacp: fast + lacp_mode: active + mode: 802.3ad + loopback: + ifindex: 0 + ifname: lo + ipv4: 10.0.0.2/32 + neighbors: [] + type: loopback + virtual_interface: true + mgmt: + ifname: eth0 + ipv4: 192.168.121.102 + mac: 08:4f:a9:00:00:02 + module: + - lag + - vlan + - vrf + name: h-03 + vlan: + max_bridge_group: 1 + vlans: + red: + bridge_group: 1 + id: 1000 + mode: irb + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 + vrf: + as: 65000 + vrfs: + red: + af: + ipv4: true + export: + - '65000:1' + id: 1 + import: + - '65000:1' + rd: '65000:1' + vrfidx: 100 + h-07: + af: + ipv4: true + vpnv4: true + box: debian/bookworm64 + device: frr + id: 3 + interfaces: + - ifindex: 1 + ifname: eth1 + ipv4: 10.1.0.5/30 + linkindex: 2 + mtu: 1600 + name: h-07 -> r + neighbors: + - ifname: eth17 + ipv4: 10.1.0.6/30 + node: r + type: p2p + - ifindex: 30000 + ifname: bond6 + ipv4: 10.1.0.14/30 + lag: + ifindex: 6 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 4 + name: h-07 -> r + neighbors: + - ifname: bond6 + ipv4: 10.1.0.13/30 + node: r + type: lag + virtual_interface: true + - ifindex: 30001 + ifname: bond2 + ipv4: 10.1.0.22/30 + lag: + ifindex: 2 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 6 + name: h-07 -> r + neighbors: + - ifname: bond2 + ipv4: 10.1.0.21/30 + node: r + type: lag + virtual_interface: true + - ifindex: 2 + ifname: eth2 + lag: + _parentindex: 4 + linkindex: 12 + name: h-07 -> r + neighbors: + - ifname: eth6 + node: r + type: p2p + - ifindex: 3 + ifname: eth3 + lag: + _parentindex: 4 + linkindex: 13 + name: h-07 -> r + neighbors: + - ifname: eth7 + node: r + type: p2p + - ifindex: 4 + ifname: eth4 + lag: + _parentindex: 6 + linkindex: 16 + name: h-07 -> r + neighbors: + - ifname: eth22 + node: r + type: p2p + - ifindex: 5 + ifname: eth5 + lag: + _parentindex: 6 + linkindex: 17 + name: h-07 -> r + neighbors: + - ifname: eth23 + node: r + type: p2p + - bridge: input_19 + ifindex: 6 + ifname: eth6 + linkindex: 19 + name: '[Access VLAN red] h-07 -> r' + neighbors: + - ifname: eth9 + ipv4: 172.16.0.1/24 + node: r + type: lan + vlan: + access: red + access_id: 1000 + - ifindex: 7 + ifname: eth7 + ipv4: 10.1.0.29/30 + linkindex: 21 + name: h-07 -> r + neighbors: + - ifname: eth11 + ipv4: 10.1.0.30/30 + node: r + vrf: red + type: p2p + vrf: red + - bridge_group: 1 + ifindex: 8 + ifname: vlan1000 + ipv4: 172.16.0.3/24 + name: VLAN red (1000) -> [h-03,r] + neighbors: + - ifname: vlan1000 + ipv4: 172.16.0.2/24 + node: h-03 + - ifname: vlan1000 + ipv4: 172.16.0.1/24 + node: r + type: svi + virtual_interface: true + vlan: + mode: irb + name: red + lag: + lacp: fast + lacp_mode: active + mode: 802.3ad + loopback: + ifindex: 0 + ifname: lo + ipv4: 10.0.0.3/32 + neighbors: [] + type: loopback + virtual_interface: true + mgmt: + ifname: eth0 + ipv4: 192.168.121.103 + mac: 08:4f:a9:00:00:03 + module: + - lag + - vlan + - vrf + name: h-07 + vlan: + max_bridge_group: 1 + vlans: + red: + bridge_group: 1 + id: 1000 + mode: irb + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 + vrf: + as: 65000 + vrfs: + red: + af: + ipv4: true + export: + - '65000:1' + id: 1 + import: + - '65000:1' + rd: '65000:1' + vrfidx: 100 + host_w_long_n-01: + af: + ipv4: true + box: generic/ubuntu2004 + device: linux + id: 10 + interfaces: + - bridge: input_7 + gateway: + ipv4: 172.16.1.1/24 + ifindex: 1 + ifname: eth1 + ipv4: 172.16.1.10/24 + linkindex: 7 + name: host_w_long_n-01 -> r + neighbors: + - ifname: eth1 + ipv4: 172.16.1.1/24 + node: r + role: stub + type: lan + mgmt: + ifname: eth0 + ipv4: 192.168.121.110 + mac: 08:4f:a9:00:00:0a + name: host_w_long_n-01 + role: host + host_w_long_n-02: + af: + ipv4: true + box: generic/ubuntu2004 + device: linux + id: 11 + interfaces: + - bridge: input_8 + gateway: + ipv4: 172.16.2.1/24 + ifindex: 1 + ifname: eth1 + ipv4: 172.16.2.11/24 + linkindex: 8 + name: host_w_long_n-02 -> r + neighbors: + - ifname: eth2 + ipv4: 172.16.2.1/24 + node: r + role: stub + type: lan + mgmt: + ifname: eth0 + ipv4: 192.168.121.111 + mac: 08:4f:a9:00:00:0b + name: host_w_long_n-02 + role: host + host_w_long_n-03: + af: + ipv4: true + box: generic/ubuntu2004 + device: linux + id: 12 + interfaces: + - bridge: input_9 + gateway: + ipv4: 172.16.3.1/24 + ifindex: 1 + ifname: eth1 + ipv4: 172.16.3.12/24 + linkindex: 9 + name: host_w_long_n-03 -> r + neighbors: + - ifname: eth3 + ipv4: 172.16.3.1/24 + node: r + role: stub + type: lan + mgmt: + ifname: eth0 + ipv4: 192.168.121.112 + mac: 08:4f:a9:00:00:0c + name: host_w_long_n-03 + role: host + r: + _set_ifindex: true + af: + ipv4: true + vpnv4: true + box: debian/bookworm64 + device: frr + id: 1 + interfaces: + - bridge: input_7 + ifindex: 1 + ifname: eth1 + ipv4: 172.16.1.1/24 + linkindex: 7 + name: r -> host_w_long_n-01 + neighbors: + - ifname: eth1 + ipv4: 172.16.1.10/24 + node: host_w_long_n-01 + role: stub + type: lan + - bridge: input_8 + ifindex: 2 + ifname: eth2 + ipv4: 172.16.2.1/24 + linkindex: 8 + name: r -> host_w_long_n-02 + neighbors: + - ifname: eth1 + ipv4: 172.16.2.11/24 + node: host_w_long_n-02 + role: stub + type: lan + - bridge: input_9 + ifindex: 3 + ifname: eth3 + ipv4: 172.16.3.1/24 + linkindex: 9 + name: r -> host_w_long_n-03 + neighbors: + - ifname: eth1 + ipv4: 172.16.3.12/24 + node: host_w_long_n-03 + role: stub + type: lan + - ifindex: 4 + ifname: eth4 + lag: + _parentindex: 3 + linkindex: 10 + name: r -> h-03 + neighbors: + - ifname: eth2 + node: h-03 + type: p2p + - ifindex: 5 + ifname: eth5 + lag: + _parentindex: 3 + linkindex: 11 + name: r -> h-03 + neighbors: + - ifname: eth3 + node: h-03 + type: p2p + - ifindex: 6 + ifname: eth6 + lag: + _parentindex: 4 + linkindex: 12 + name: r -> h-07 + neighbors: + - ifname: eth2 + node: h-07 + type: p2p + - ifindex: 7 + ifname: eth7 + lag: + _parentindex: 4 + linkindex: 13 + name: r -> h-07 + neighbors: + - ifname: eth3 + node: h-07 + type: p2p + - bridge: input_18 + ifindex: 8 + ifname: eth8 + linkindex: 18 + name: '[Access VLAN red] r -> h-03' + neighbors: + - ifname: eth6 + ipv4: 172.16.0.2/24 + node: h-03 + type: lan + vlan: + access: red + access_id: 1000 + - bridge: input_19 + ifindex: 9 + ifname: eth9 + linkindex: 19 + name: '[Access VLAN red] r -> h-07' + neighbors: + - ifname: eth6 + ipv4: 172.16.0.3/24 + node: h-07 + type: lan + vlan: + access: red + access_id: 1000 + - ifindex: 10 + ifname: eth10 + ipv4: 10.1.0.26/30 + linkindex: 20 + name: r -> h-03 + neighbors: + - ifname: eth7 + ipv4: 10.1.0.25/30 + node: h-03 + vrf: red + type: p2p + vrf: red + - ifindex: 11 + ifname: eth11 + ipv4: 10.1.0.30/30 + linkindex: 21 + name: r -> h-07 + neighbors: + - ifname: eth7 + ipv4: 10.1.0.29/30 + node: h-07 + vrf: red + type: p2p + vrf: red + - bridge_group: 1 + ifindex: 12 + ifname: vlan1000 + ipv4: 172.16.0.1/24 + name: VLAN red (1000) -> [h-03,h-07] + neighbors: + - ifname: vlan1000 + ipv4: 172.16.0.2/24 + node: h-03 + - ifname: vlan1000 + ipv4: 172.16.0.3/24 + node: h-07 + type: svi + virtual_interface: true + vlan: + mode: irb + name: red + - ifindex: 13 + ifname: eth13 + linkindex: 0 + neighbors: [] + remote_id: 1 + remote_ifindex: 666 + type: p2p + - ifindex: 14 + ifname: eth14 + linkindex: 0 + neighbors: [] + remote_id: 1 + remote_ifindex: 666 + type: p2p + - ifindex: 15 + ifname: eth15 + linkindex: 0 + neighbors: [] + remote_id: 1 + remote_ifindex: 666 + type: p2p + - ifindex: 16 + ifname: eth16 + ipv4: 10.1.0.2/30 + linkindex: 1 + name: r -> h-03 + neighbors: + - ifname: eth1 + ipv4: 10.1.0.1/30 + node: h-03 + type: p2p + - ifindex: 17 + ifname: eth17 + ipv4: 10.1.0.6/30 + linkindex: 2 + name: r -> h-07 + neighbors: + - ifname: eth1 + ipv4: 10.1.0.5/30 + node: h-07 + type: p2p + - ifindex: 18 + ifname: eth18 + linkindex: 0 + neighbors: [] + remote_id: 1 + remote_ifindex: 666 + type: p2p + - ifindex: 19 + ifname: eth19 + linkindex: 0 + neighbors: [] + remote_id: 1 + remote_ifindex: 666 + type: p2p + - ifindex: 20 + ifname: eth20 + lag: + _parentindex: 5 + linkindex: 14 + name: r -> h-03 + neighbors: + - ifname: eth4 + node: h-03 + type: p2p + - ifindex: 21 + ifname: eth21 + lag: + _parentindex: 5 + linkindex: 15 + name: r -> h-03 + neighbors: + - ifname: eth5 + node: h-03 + type: p2p + - ifindex: 22 + ifname: eth22 + lag: + _parentindex: 6 + linkindex: 16 + name: r -> h-07 + neighbors: + - ifname: eth4 + node: h-07 + type: p2p + - ifindex: 23 + ifname: eth23 + lag: + _parentindex: 6 + linkindex: 17 + name: r -> h-07 + neighbors: + - ifname: eth5 + node: h-07 + type: p2p + - ifindex: 30000 + ifname: bond5 + ipv4: 10.1.0.9/30 + lag: + ifindex: 5 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 3 + name: r -> h-03 + neighbors: + - ifname: bond5 + ipv4: 10.1.0.10/30 + node: h-03 + type: lag + virtual_interface: true + - ifindex: 30001 + ifname: bond6 + ipv4: 10.1.0.13/30 + lag: + ifindex: 6 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 4 + name: r -> h-07 + neighbors: + - ifname: bond6 + ipv4: 10.1.0.14/30 + node: h-07 + type: lag + virtual_interface: true + - ifindex: 30002 + ifname: bond1 + ipv4: 10.1.0.17/30 + lag: + ifindex: 1 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 5 + name: r -> h-03 + neighbors: + - ifname: bond1 + ipv4: 10.1.0.18/30 + node: h-03 + type: lag + virtual_interface: true + - ifindex: 30003 + ifname: bond2 + ipv4: 10.1.0.21/30 + lag: + ifindex: 2 + lacp: fast + lacp_mode: active + mode: 802.3ad + linkindex: 6 + name: r -> h-07 + neighbors: + - ifname: bond2 + ipv4: 10.1.0.22/30 + node: h-07 + type: lag + virtual_interface: true + lag: + lacp: fast + lacp_mode: active + mode: 802.3ad + libvirt: + nic_adapter_count: 24 + loopback: + ifindex: 0 + ifname: lo + ipv4: 10.0.0.1/32 + neighbors: [] + type: loopback + virtual_interface: true + mgmt: + ifname: eth0 + ipv4: 192.168.121.101 + mac: 08:4f:a9:00:00:01 + module: + - lag + - vlan + - vrf + name: r + vlan: + max_bridge_group: 1 + vlans: + red: + bridge_group: 1 + id: 1000 + mode: irb + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 + vrf: + as: 65000 + vrfs: + red: + af: + ipv4: true + export: + - '65000:1' + id: 1 + import: + - '65000:1' + rd: '65000:1' + vrfidx: 100 +plugin: +- node.clone +provider: libvirt +vlans: + red: + host_count: 0 + id: 1000 + neighbors: + - ifname: vlan1000 + ipv4: 172.16.0.2/24 + node: h-03 + - ifname: vlan1000 + ipv4: 172.16.0.1/24 + node: r + - ifname: vlan1000 + ipv4: 172.16.0.3/24 + node: h-07 + prefix: + allocation: id_based + ipv4: 172.16.0.0/24 +vrf: + as: 65000 +vrfs: + red: + export: + - '65000:1' + id: 1 + import: + - '65000:1' + rd: '65000:1' diff --git a/tests/topology/input/lag-mlag.yml b/tests/topology/input/lag-mlag.yml index ed76dd944..a8628b6e8 100644 --- a/tests/topology/input/lag-mlag.yml +++ b/tests/topology/input/lag-mlag.yml @@ -30,4 +30,4 @@ links: vlan.access: red - lag: members: [ h2-s1,h2-s2 ] # A second lag should get a unique ifindex, not overlapping with the first one - vlan.access: red \ No newline at end of file + vlan.access: red diff --git a/tests/topology/input/node.clone-plugin-lag.yml b/tests/topology/input/node.clone-plugin-lag.yml new file mode 100644 index 000000000..5637eedcb --- /dev/null +++ b/tests/topology/input/node.clone-plugin-lag.yml @@ -0,0 +1,47 @@ +# +# Tests various lag related cases +# +--- +plugin: [ node.clone ] + +module: [lag,vlan] + +vlans: + red: + +groups: + _auto_create: True + routers: + members: [r1,r2] # Devices that supports (m)lag + device: eos + module: [vlan,lag] + +nodes: + h: # Short name, regular test + device: frr + clone.count: 2 + + h2: + device: frr + clone.count: 2 + +links: +- lag: + members: [r1-r2] + mlag.peergroup: True +- lag: + members: [ r1-h, r1-h ] + ifindex: 8 # Custom lag.ifindex, gets incremented for each clone + pool: l2only +- lag: + members: + - r2: + ifindex: 6 # Custom ifindex on interface, gets incremented for each clone + h: + - r2: + ifindex: 7 + h: + pool: l2only +- lag: + members: [ h2-r1, h2-r2 ] # mlag, avoid issue with overlapping lag.ifindex + vlan.access: red \ No newline at end of file diff --git a/tests/topology/input/node.clone-plugin.yml b/tests/topology/input/node.clone-plugin.yml new file mode 100644 index 000000000..03d93f9c7 --- /dev/null +++ b/tests/topology/input/node.clone-plugin.yml @@ -0,0 +1,52 @@ +--- +plugin: [ node.clone ] + +module: [lag,vlan,vrf] + +vlans: + red: + links: [r-h] # VLAN links get updated + +vrfs: + red: + links: [r-h] # VRF links get updated + +groups: + _auto_create: True # Test presence of bool flag + hosts: + members: [h,host_w_long_name] # Gets updated with cloned nodes + +nodes: + r: + device: frr + + h: # Short name, regular test + device: frr + clone: + count: 2 + start: 3 # Create h-03 and h-07 + step: 4 + + host_w_long_name: # Test that node names get shortened to at most 16 chars + device: linux + clone.count: 3 # Create 3 hosts + id: 10 # Starting at ID 10 + +links: +- r-host_w_long_name # Plugin supports different styles of specifying links, all normalized +- r: + ifindex: 16 # Custom port on router -> gets incremented + h: + mtu: 1600 # Interface atts get copied too + +- lag: + members: [ r-h, r-h ] + ifindex: 5 # Custom lag.ifindex, gets incremented for each clone +- lag: + members: + - r: + ifindex: 20 # Custom ifindex on interface, gets incremented for each clone + h: + - r: + ifindex: 21 + h: \ No newline at end of file