Loading src/tests/Spine-Leaf-BGP-test/data/fabric-descriptor-spine1-spine2-leaf1-leaf4-evpn-vxlan-static.json 0 → 100644 +396 −0 Original line number Diff line number Diff line { "logical_resources": [ { "fabric_id": "core-spine-leaf-evpn-static", "asn": { "settings": { "range": "65000-65199" }, "allocations": { "e162b163-6969-512a-8ee9-cce9f0687c64": { "device_name": "Spine1", "value": "65001" }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61": { "device_name": "Spine2", "value": "65002" }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": { "device_name": "Spine3", "value": "65003" }, "6ac9614b-6893-549d-b39c-d4af4320678a": { "device_name": "Leaf1", "value": "65101" }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "device_name": "Leaf4", "value": "65104" } } }, "loopback": { "settings": { "range": "10.255.0.0/16" }, "allocations": { "e162b163-6969-512a-8ee9-cce9f0687c64": { "device_name": "Spine1", "value": "10.255.0.1" }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61": { "device_name": "Spine2", "value": "10.255.0.2" }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": { "device_name": "Spine3", "value": "10.255.0.3" }, "6ac9614b-6893-549d-b39c-d4af4320678a": { "device_name": "Leaf1", "value": "10.255.1.1" }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "device_name": "Leaf4", "value": "10.255.1.4" } } }, "router_id": { "settings": { "range": "10.255.0.0/16" }, "allocations": { "e162b163-6969-512a-8ee9-cce9f0687c64": { "device_name": "Spine1", "value": "10.255.0.1" }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61": { "device_name": "Spine2", "value": "10.255.0.2" }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": { "device_name": "Spine3", "value": "10.255.0.3" }, "6ac9614b-6893-549d-b39c-d4af4320678a": { "device_name": "Leaf1", "value": "10.255.1.1" }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "device_name": "Leaf4", "value": "10.255.1.4" } } }, "ip": { "settings": { "range": "10.0.0.0/16" }, "allocations": { "e162b163-6969-512a-8ee9-cce9f0687c64#leaf1": { "device_name": "Spine1", "value": "10.0.0.0" }, "e162b163-6969-512a-8ee9-cce9f0687c64#leaf4": { "device_name": "Spine1", "value": "10.0.0.6" }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61#leaf1": { "device_name": "Spine2", "value": "10.0.1.0" }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61#leaf4": { "device_name": "Spine2", "value": "10.0.1.6" }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740#leaf1": { "device_name": "Spine3", "value": "10.0.2.0" }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740#leaf4": { "device_name": "Spine3", "value": "10.0.2.6" }, "6ac9614b-6893-549d-b39c-d4af4320678a#spine1": { "device_name": "Leaf1", "value": "10.0.0.1" }, "6ac9614b-6893-549d-b39c-d4af4320678a#spine2": { "device_name": "Leaf1", "value": "10.0.1.1" }, "6ac9614b-6893-549d-b39c-d4af4320678a#spine3": { "device_name": "Leaf1", "value": "10.0.2.1" }, "03d3c087-da28-539e-aae0-60da7b90bad6#spine1": { "device_name": "Leaf4", "value": "10.0.0.7" }, "03d3c087-da28-539e-aae0-60da7b90bad6#spine2": { "device_name": "Leaf4", "value": "10.0.1.7" }, "03d3c087-da28-539e-aae0-60da7b90bad6#spine3": { "device_name": "Leaf4", "value": "10.0.2.7" } } }, "vlan": { "settings": { "range": "10-4094" }, "allocations": { "6ac9614b-6893-549d-b39c-d4af4320678a": { "device_name": "Leaf1", "value": "10" }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "device_name": "Leaf4", "value": "10" } } }, "vni": { "settings": { "range": "1000-999999" }, "allocations": { "6ac9614b-6893-549d-b39c-d4af4320678a": { "device_name": "Leaf1", "value": "1010" }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "device_name": "Leaf4", "value": "1010" } } }, "interface_ip_address": { "allocations": { "e162b163-6969-512a-8ee9-cce9f0687c64": { "interfaces": { "lo0": { "ip": "10.255.0.1/32", "comment": "Spine1 Loopback" }, "sfp-sfpplus1": { "ip": "10.0.0.0/31", "comment": "To Leaf1", "bgp_session_name": "Leaf1", "link_to_device": "6ac9614b-6893-549d-b39c-d4af4320678a", "link_to_interface": "sfp-sfpplus1" }, "sfp-sfpplus4": { "ip": "10.0.0.6/31", "comment": "To Leaf4", "bgp_session_name": "Leaf4", "link_to_device": "03d3c087-da28-539e-aae0-60da7b90bad6", "link_to_interface": "sfp-sfpplus1" } } }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61": { "interfaces": { "lo0": { "ip": "10.255.0.2/32", "comment": "Spine2 Loopback" }, "sfp-sfpplus1": { "ip": "10.0.1.0/31", "comment": "To Leaf1", "bgp_session_name": "Leaf1", "link_to_device": "6ac9614b-6893-549d-b39c-d4af4320678a", "link_to_interface": "sfp-sfpplus2" }, "sfp-sfpplus4": { "ip": "10.0.1.6/31", "comment": "To Leaf4", "bgp_session_name": "Leaf4", "link_to_device": "03d3c087-da28-539e-aae0-60da7b90bad6", "link_to_interface": "sfp-sfpplus2" } } }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": { "interfaces": { "lo0": { "ip": "10.255.0.3/32", "comment": "Spine3 Loopback" }, "sfp-sfpplus1": { "ip": "10.0.2.0/31", "comment": "To Leaf1", "bgp_session_name": "Leaf1", "link_to_device": "6ac9614b-6893-549d-b39c-d4af4320678a", "link_to_interface": "sfp-sfpplus3" }, "sfp-sfpplus4": { "ip": "10.0.2.6/31", "comment": "To Leaf4", "bgp_session_name": "Leaf4", "link_to_device": "03d3c087-da28-539e-aae0-60da7b90bad6", "link_to_interface": "sfp-sfpplus3" } } }, "6ac9614b-6893-549d-b39c-d4af4320678a": { "interfaces": { "lo0": { "ip": "10.255.1.1/32", "comment": "Leaf1 Loopback" }, "sfp-sfpplus1": { "ip": "10.0.0.1/31", "comment": "To Spine1", "bgp_session_name": "Spine1", "link_to_device": "e162b163-6969-512a-8ee9-cce9f0687c64", "link_to_interface": "sfp-sfpplus1" }, "sfp-sfpplus2": { "ip": "10.0.1.1/31", "comment": "To Spine2", "bgp_session_name": "Spine2", "link_to_device": "1f3a8cbe-5826-585b-a207-4826d4ae9a61", "link_to_interface": "sfp-sfpplus1" }, "sfp-sfpplus3": { "ip": "10.0.2.1/31", "comment": "To Spine3", "bgp_session_name": "Spine3", "link_to_device": "81b97fc5-6c85-5d0d-86e2-e00ff04a4740", "link_to_interface": "sfp-sfpplus1" } } }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "interfaces": { "lo0": { "ip": "10.255.1.4/32", "comment": "Leaf4 Loopback" }, "sfp-sfpplus1": { "ip": "10.0.0.7/31", "comment": "To Spine1", "bgp_session_name": "Spine1", "link_to_device": "e162b163-6969-512a-8ee9-cce9f0687c64", "link_to_interface": "sfp-sfpplus4" }, "sfp-sfpplus2": { "ip": "10.0.1.7/31", "comment": "To Spine2", "bgp_session_name": "Spine2", "link_to_device": "1f3a8cbe-5826-585b-a207-4826d4ae9a61", "link_to_interface": "sfp-sfpplus4" }, "sfp-sfpplus3": { "ip": "10.0.2.7/31", "comment": "To Spine3", "bgp_session_name": "Spine3", "link_to_device": "81b97fc5-6c85-5d0d-86e2-e00ff04a4740", "link_to_interface": "sfp-sfpplus4" } } } } }, "vrf_interfaces": { "e162b163-6969-512a-8ee9-cce9f0687c64": [ "sfp-sfpplus1", "sfp-sfpplus4", "lo0" ], "1f3a8cbe-5826-585b-a207-4826d4ae9a61": [ "sfp-sfpplus1", "sfp-sfpplus4", "lo0" ], "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": [ "sfp-sfpplus1", "sfp-sfpplus4", "lo0" ], "6ac9614b-6893-549d-b39c-d4af4320678a": [ "sfp-sfpplus1", "sfp-sfpplus2", "sfp-sfpplus3", "lo0" ], "03d3c087-da28-539e-aae0-60da7b90bad6": [ "sfp-sfpplus1", "sfp-sfpplus2", "sfp-sfpplus3", "lo0" ] }, "tenant_networks": { "default": { "name": "tenant-vni1010", "vlan_id": 10, "vni": 1010, "bridge_name": "br-vni1010", "vxlan_name": "vxlan1010", "evpn_name": "bgp-evpn-1010", "route_target_import": "1010:1010", "route_target_export": "1010:1010", "discovery_mode": "static" } }, "bridge_ports": { "6ac9614b-6893-549d-b39c-d4af4320678a": [ "sfp-sfpplus7" ], "03d3c087-da28-539e-aae0-60da7b90bad6": [ "sfp-sfpplus8" ] }, "static_vteps": { "6ac9614b-6893-549d-b39c-d4af4320678a": [ "10.255.1.4" ], "03d3c087-da28-539e-aae0-60da7b90bad6": [ "10.255.1.1" ] } } ], "spine-leaf": [ { "fabric_id": "core-spine-leaf-evpn-static", "device_roles": { "e162b163-6969-512a-8ee9-cce9f0687c64": "DEVICEROLE_SPINE", "1f3a8cbe-5826-585b-a207-4826d4ae9a61": "DEVICEROLE_SPINE", "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": "DEVICEROLE_SPINE", "6ac9614b-6893-549d-b39c-d4af4320678a": "DEVICEROLE_LEAF", "03d3c087-da28-539e-aae0-60da7b90bad6": "DEVICEROLE_LEAF" }, "settings": { "underlay_type": "bgp", "overlay_type": "vxlan", "underlay_bgp": true, "overlay_bgp": true, "apply_config": true, "spine_count": 3, "leaf_count": 2 } } ] } src/tests/Spine-Leaf-BGP-test/evpn_vxlan_repeat_benchmark.py +4 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,10 @@ from device.client.DeviceClient import DeviceClient from spine_leaf.client.SpineLeafClient import SpineLeafClient DEFAULT_DESCRIPTOR = 'tmp/fabric-descriptor-spine1-spine2-leaf1-leaf4-evpn-vxlan-static.json' DEFAULT_DESCRIPTOR = ( 'src/tests/Spine-Leaf-BGP-test/data/' 'fabric-descriptor-spine1-spine2-leaf1-leaf4-evpn-vxlan-static.json' ) DEFAULT_DEVICE_UUIDS = [ 'e162b163-6969-512a-8ee9-cce9f0687c64', '1f3a8cbe-5826-585b-a207-4826d4ae9a61', Loading src/tests/Spine-Leaf-BGP-test/spine-leaf-all-multi-test.py +88 −24 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ import json import logging import os import copy import socket import subprocess from common.proto.context_pb2 import ConfigRule from common.proto.spineleaf_pb2 import DeployDeviceConfigRequest, UnsetDeviceRoleRequest Loading @@ -24,6 +26,7 @@ from common.tools.object_factory.ConfigRule import ( json_config_rule_set, json_config_rule_delete, ) from service.service.tools.object_uuid import get_uuid_from_string from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from spine_leaf.client.SpineLeafClient import SpineLeafClient Loading @@ -38,21 +41,59 @@ LOGGER = logging.getLogger('spineleaf_all_multi_test') # ----------------------------- # ENV # ----------------------------- CONTEXTSERVICE_HOST = os.getenv('CONTEXTSERVICE_SERVICE_HOST', '10.152.183.46') def _resolve_service_host(env_name, service_name, namespace='tfs'): env_value = os.getenv(env_name, '').strip() if env_value: return env_value dns_name = f'{service_name}.{namespace}.svc.cluster.local' try: socket.gethostbyname(dns_name) LOGGER.info('Resolved %s from Kubernetes DNS name %s', env_name, dns_name) return dns_name except OSError: pass try: result = subprocess.run( [ 'microk8s', 'kubectl', 'get', 'svc', service_name, '-n', namespace, '-o', 'jsonpath={.spec.clusterIP}', ], check=True, capture_output=True, text=True, ) cluster_ip = result.stdout.strip() if cluster_ip: LOGGER.info('Resolved %s from Kubernetes service %s/%s => %s', env_name, namespace, service_name, cluster_ip) return cluster_ip except (FileNotFoundError, subprocess.CalledProcessError) as exc: LOGGER.warning('Unable to resolve Kubernetes service %s/%s: %s', namespace, service_name, exc) raise RuntimeError( f'Unable to resolve {service_name}. Set {env_name} explicitly, for example ' f'{env_name}=<current-service-ip-or-hostname>.' ) CONTEXTSERVICE_HOST = _resolve_service_host('CONTEXTSERVICE_SERVICE_HOST', 'contextservice') CONTEXTSERVICE_PORT = int(os.getenv('CONTEXTSERVICE_SERVICE_PORT_GRPC', '1010')) DEVICESERVICE_HOST = os.getenv('DEVICESERVICE_SERVICE_HOST', '10.152.183.102') DEVICESERVICE_HOST = _resolve_service_host('DEVICESERVICE_SERVICE_HOST', 'deviceservice') DEVICESERVICE_PORT = int(os.getenv('DEVICESERVICE_SERVICE_PORT_GRPC', '2020')) SPINE_LEAFSERVICE_HOST = os.getenv('SPINE_LEAFSERVICE_SERVICE_HOST', '10.152.183.147') SPINE_LEAFSERVICE_HOST = _resolve_service_host('SPINE_LEAFSERVICE_SERVICE_HOST', 'spine-leafservice') SPINE_LEAFSERVICE_PORT = int(os.getenv('SPINE_LEAFSERVICE_SERVICE_PORT_GRPC', '10095')) FABRIC_ID = os.getenv( 'FABRIC_ID', '354a08b7-3730-5dd6-9472-47554115818b', SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) DEFAULT_DESCRIPTOR_FILE = os.path.join( SCRIPT_DIR, 'data', 'fabric-descriptor-spine1-spine2-leaf1-leaf4-evpn-vxlan-static.json', ) DESCRIPTOR_FILE = os.getenv('DESCRIPTOR_FILE', '') DESCRIPTOR_FILE = os.getenv('DESCRIPTOR_FILE', DEFAULT_DESCRIPTOR_FILE) DEFAULT_DEVICE_UUIDS = [ 'e162b163-6969-512a-8ee9-cce9f0687c64', Loading Loading @@ -89,6 +130,25 @@ def is_apply_enabled() -> bool: return os.getenv('APPLY_CONFIG', 'false').lower() in ('1', 'true', 'yes') def get_fabric_id() -> str: env_fabric_id = os.getenv('FABRIC_ID', '').strip() if env_fabric_id: return env_fabric_id if DESCRIPTOR_FILE and os.path.exists(DESCRIPTOR_FILE): try: with open(DESCRIPTOR_FILE, 'r', encoding='UTF-8') as f: descriptor = json.load(f) fabric = (descriptor.get('spine-leaf') or [{}])[0] fabric_name = str(fabric.get('fabric_name', fabric.get('fabric_id', '')) or '') if fabric_name: return get_uuid_from_string(fabric_name) except Exception: LOGGER.exception('Could not derive fabric id from descriptor %s', DESCRIPTOR_FILE) return '354a08b7-3730-5dd6-9472-47554115818b' def parse_spineleaf_rule(entry): if not isinstance(entry, (list, tuple)) or len(entry) != 2: return None Loading Loading @@ -144,8 +204,9 @@ def build_descriptor_rules(descriptor_file, device_uuid): settings = fabric.get('settings', {}) store = SpineLeafStateStore() fabric_id_value = get_fabric_id() fabric_id, _, _ = store.create_fabric( FABRIC_ID, fabric_id_value, 'spine_leaf', str(settings.get('underlay_type', 'bgp')), str(settings.get('overlay_type', '')), Loading Loading @@ -255,8 +316,18 @@ class ApplySpineLeafConfig: LOGGER.info('') LOGGER.info('=== DEVICE %s ===', device_uuid) deconfigure = is_deconfigure_enabled() descriptor_rules = build_descriptor_rules(DESCRIPTOR_FILE, device_uuid) if deconfigure and descriptor_rules: payload = {'driver_config_rules': []} LOGGER.info( 'Skipping SpineLeaf DeployDeviceConfig for descriptor-driven deconfigure of %s', device_uuid, ) else: request = DeployDeviceConfigRequest( fabric_id=FABRIC_ID, fabric_id=get_fabric_id(), device_uuid=device_uuid, ) Loading @@ -268,12 +339,9 @@ class ApplySpineLeafConfig: LOGGER.info('Parsed payload keys for %s: %s', device_uuid, list(payload.keys())) deconfigure = is_deconfigure_enabled() set_rules = [] delete_rules = [] driver_config_rules = payload.get('driver_config_rules', []) descriptor_rules = build_descriptor_rules(DESCRIPTOR_FILE, device_uuid) if deconfigure and descriptor_rules: seen_rules = { json.dumps(parse_spineleaf_rule(entry), sort_keys=True) Loading Loading @@ -334,7 +402,7 @@ class ApplySpineLeafConfig: LOGGER.info('DELETE result %s => %s', device_uuid, result) unset_request = UnsetDeviceRoleRequest( fabric_id=FABRIC_ID, fabric_id=get_fabric_id(), device_uuid=device_uuid, ) unset_result = self.spine_leaf_client.UnsetDeviceRole(unset_request) Loading Loading @@ -366,9 +434,5 @@ class ApplySpineLeafConfig: device_client.close() context_client.close() # ----------------------------- # ENTRY # ----------------------------- if __name__ == '__main__': ApplySpineLeafConfig().run() Loading
src/tests/Spine-Leaf-BGP-test/data/fabric-descriptor-spine1-spine2-leaf1-leaf4-evpn-vxlan-static.json 0 → 100644 +396 −0 Original line number Diff line number Diff line { "logical_resources": [ { "fabric_id": "core-spine-leaf-evpn-static", "asn": { "settings": { "range": "65000-65199" }, "allocations": { "e162b163-6969-512a-8ee9-cce9f0687c64": { "device_name": "Spine1", "value": "65001" }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61": { "device_name": "Spine2", "value": "65002" }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": { "device_name": "Spine3", "value": "65003" }, "6ac9614b-6893-549d-b39c-d4af4320678a": { "device_name": "Leaf1", "value": "65101" }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "device_name": "Leaf4", "value": "65104" } } }, "loopback": { "settings": { "range": "10.255.0.0/16" }, "allocations": { "e162b163-6969-512a-8ee9-cce9f0687c64": { "device_name": "Spine1", "value": "10.255.0.1" }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61": { "device_name": "Spine2", "value": "10.255.0.2" }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": { "device_name": "Spine3", "value": "10.255.0.3" }, "6ac9614b-6893-549d-b39c-d4af4320678a": { "device_name": "Leaf1", "value": "10.255.1.1" }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "device_name": "Leaf4", "value": "10.255.1.4" } } }, "router_id": { "settings": { "range": "10.255.0.0/16" }, "allocations": { "e162b163-6969-512a-8ee9-cce9f0687c64": { "device_name": "Spine1", "value": "10.255.0.1" }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61": { "device_name": "Spine2", "value": "10.255.0.2" }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": { "device_name": "Spine3", "value": "10.255.0.3" }, "6ac9614b-6893-549d-b39c-d4af4320678a": { "device_name": "Leaf1", "value": "10.255.1.1" }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "device_name": "Leaf4", "value": "10.255.1.4" } } }, "ip": { "settings": { "range": "10.0.0.0/16" }, "allocations": { "e162b163-6969-512a-8ee9-cce9f0687c64#leaf1": { "device_name": "Spine1", "value": "10.0.0.0" }, "e162b163-6969-512a-8ee9-cce9f0687c64#leaf4": { "device_name": "Spine1", "value": "10.0.0.6" }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61#leaf1": { "device_name": "Spine2", "value": "10.0.1.0" }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61#leaf4": { "device_name": "Spine2", "value": "10.0.1.6" }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740#leaf1": { "device_name": "Spine3", "value": "10.0.2.0" }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740#leaf4": { "device_name": "Spine3", "value": "10.0.2.6" }, "6ac9614b-6893-549d-b39c-d4af4320678a#spine1": { "device_name": "Leaf1", "value": "10.0.0.1" }, "6ac9614b-6893-549d-b39c-d4af4320678a#spine2": { "device_name": "Leaf1", "value": "10.0.1.1" }, "6ac9614b-6893-549d-b39c-d4af4320678a#spine3": { "device_name": "Leaf1", "value": "10.0.2.1" }, "03d3c087-da28-539e-aae0-60da7b90bad6#spine1": { "device_name": "Leaf4", "value": "10.0.0.7" }, "03d3c087-da28-539e-aae0-60da7b90bad6#spine2": { "device_name": "Leaf4", "value": "10.0.1.7" }, "03d3c087-da28-539e-aae0-60da7b90bad6#spine3": { "device_name": "Leaf4", "value": "10.0.2.7" } } }, "vlan": { "settings": { "range": "10-4094" }, "allocations": { "6ac9614b-6893-549d-b39c-d4af4320678a": { "device_name": "Leaf1", "value": "10" }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "device_name": "Leaf4", "value": "10" } } }, "vni": { "settings": { "range": "1000-999999" }, "allocations": { "6ac9614b-6893-549d-b39c-d4af4320678a": { "device_name": "Leaf1", "value": "1010" }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "device_name": "Leaf4", "value": "1010" } } }, "interface_ip_address": { "allocations": { "e162b163-6969-512a-8ee9-cce9f0687c64": { "interfaces": { "lo0": { "ip": "10.255.0.1/32", "comment": "Spine1 Loopback" }, "sfp-sfpplus1": { "ip": "10.0.0.0/31", "comment": "To Leaf1", "bgp_session_name": "Leaf1", "link_to_device": "6ac9614b-6893-549d-b39c-d4af4320678a", "link_to_interface": "sfp-sfpplus1" }, "sfp-sfpplus4": { "ip": "10.0.0.6/31", "comment": "To Leaf4", "bgp_session_name": "Leaf4", "link_to_device": "03d3c087-da28-539e-aae0-60da7b90bad6", "link_to_interface": "sfp-sfpplus1" } } }, "1f3a8cbe-5826-585b-a207-4826d4ae9a61": { "interfaces": { "lo0": { "ip": "10.255.0.2/32", "comment": "Spine2 Loopback" }, "sfp-sfpplus1": { "ip": "10.0.1.0/31", "comment": "To Leaf1", "bgp_session_name": "Leaf1", "link_to_device": "6ac9614b-6893-549d-b39c-d4af4320678a", "link_to_interface": "sfp-sfpplus2" }, "sfp-sfpplus4": { "ip": "10.0.1.6/31", "comment": "To Leaf4", "bgp_session_name": "Leaf4", "link_to_device": "03d3c087-da28-539e-aae0-60da7b90bad6", "link_to_interface": "sfp-sfpplus2" } } }, "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": { "interfaces": { "lo0": { "ip": "10.255.0.3/32", "comment": "Spine3 Loopback" }, "sfp-sfpplus1": { "ip": "10.0.2.0/31", "comment": "To Leaf1", "bgp_session_name": "Leaf1", "link_to_device": "6ac9614b-6893-549d-b39c-d4af4320678a", "link_to_interface": "sfp-sfpplus3" }, "sfp-sfpplus4": { "ip": "10.0.2.6/31", "comment": "To Leaf4", "bgp_session_name": "Leaf4", "link_to_device": "03d3c087-da28-539e-aae0-60da7b90bad6", "link_to_interface": "sfp-sfpplus3" } } }, "6ac9614b-6893-549d-b39c-d4af4320678a": { "interfaces": { "lo0": { "ip": "10.255.1.1/32", "comment": "Leaf1 Loopback" }, "sfp-sfpplus1": { "ip": "10.0.0.1/31", "comment": "To Spine1", "bgp_session_name": "Spine1", "link_to_device": "e162b163-6969-512a-8ee9-cce9f0687c64", "link_to_interface": "sfp-sfpplus1" }, "sfp-sfpplus2": { "ip": "10.0.1.1/31", "comment": "To Spine2", "bgp_session_name": "Spine2", "link_to_device": "1f3a8cbe-5826-585b-a207-4826d4ae9a61", "link_to_interface": "sfp-sfpplus1" }, "sfp-sfpplus3": { "ip": "10.0.2.1/31", "comment": "To Spine3", "bgp_session_name": "Spine3", "link_to_device": "81b97fc5-6c85-5d0d-86e2-e00ff04a4740", "link_to_interface": "sfp-sfpplus1" } } }, "03d3c087-da28-539e-aae0-60da7b90bad6": { "interfaces": { "lo0": { "ip": "10.255.1.4/32", "comment": "Leaf4 Loopback" }, "sfp-sfpplus1": { "ip": "10.0.0.7/31", "comment": "To Spine1", "bgp_session_name": "Spine1", "link_to_device": "e162b163-6969-512a-8ee9-cce9f0687c64", "link_to_interface": "sfp-sfpplus4" }, "sfp-sfpplus2": { "ip": "10.0.1.7/31", "comment": "To Spine2", "bgp_session_name": "Spine2", "link_to_device": "1f3a8cbe-5826-585b-a207-4826d4ae9a61", "link_to_interface": "sfp-sfpplus4" }, "sfp-sfpplus3": { "ip": "10.0.2.7/31", "comment": "To Spine3", "bgp_session_name": "Spine3", "link_to_device": "81b97fc5-6c85-5d0d-86e2-e00ff04a4740", "link_to_interface": "sfp-sfpplus4" } } } } }, "vrf_interfaces": { "e162b163-6969-512a-8ee9-cce9f0687c64": [ "sfp-sfpplus1", "sfp-sfpplus4", "lo0" ], "1f3a8cbe-5826-585b-a207-4826d4ae9a61": [ "sfp-sfpplus1", "sfp-sfpplus4", "lo0" ], "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": [ "sfp-sfpplus1", "sfp-sfpplus4", "lo0" ], "6ac9614b-6893-549d-b39c-d4af4320678a": [ "sfp-sfpplus1", "sfp-sfpplus2", "sfp-sfpplus3", "lo0" ], "03d3c087-da28-539e-aae0-60da7b90bad6": [ "sfp-sfpplus1", "sfp-sfpplus2", "sfp-sfpplus3", "lo0" ] }, "tenant_networks": { "default": { "name": "tenant-vni1010", "vlan_id": 10, "vni": 1010, "bridge_name": "br-vni1010", "vxlan_name": "vxlan1010", "evpn_name": "bgp-evpn-1010", "route_target_import": "1010:1010", "route_target_export": "1010:1010", "discovery_mode": "static" } }, "bridge_ports": { "6ac9614b-6893-549d-b39c-d4af4320678a": [ "sfp-sfpplus7" ], "03d3c087-da28-539e-aae0-60da7b90bad6": [ "sfp-sfpplus8" ] }, "static_vteps": { "6ac9614b-6893-549d-b39c-d4af4320678a": [ "10.255.1.4" ], "03d3c087-da28-539e-aae0-60da7b90bad6": [ "10.255.1.1" ] } } ], "spine-leaf": [ { "fabric_id": "core-spine-leaf-evpn-static", "device_roles": { "e162b163-6969-512a-8ee9-cce9f0687c64": "DEVICEROLE_SPINE", "1f3a8cbe-5826-585b-a207-4826d4ae9a61": "DEVICEROLE_SPINE", "81b97fc5-6c85-5d0d-86e2-e00ff04a4740": "DEVICEROLE_SPINE", "6ac9614b-6893-549d-b39c-d4af4320678a": "DEVICEROLE_LEAF", "03d3c087-da28-539e-aae0-60da7b90bad6": "DEVICEROLE_LEAF" }, "settings": { "underlay_type": "bgp", "overlay_type": "vxlan", "underlay_bgp": true, "overlay_bgp": true, "apply_config": true, "spine_count": 3, "leaf_count": 2 } } ] }
src/tests/Spine-Leaf-BGP-test/evpn_vxlan_repeat_benchmark.py +4 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,10 @@ from device.client.DeviceClient import DeviceClient from spine_leaf.client.SpineLeafClient import SpineLeafClient DEFAULT_DESCRIPTOR = 'tmp/fabric-descriptor-spine1-spine2-leaf1-leaf4-evpn-vxlan-static.json' DEFAULT_DESCRIPTOR = ( 'src/tests/Spine-Leaf-BGP-test/data/' 'fabric-descriptor-spine1-spine2-leaf1-leaf4-evpn-vxlan-static.json' ) DEFAULT_DEVICE_UUIDS = [ 'e162b163-6969-512a-8ee9-cce9f0687c64', '1f3a8cbe-5826-585b-a207-4826d4ae9a61', Loading
src/tests/Spine-Leaf-BGP-test/spine-leaf-all-multi-test.py +88 −24 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ import json import logging import os import copy import socket import subprocess from common.proto.context_pb2 import ConfigRule from common.proto.spineleaf_pb2 import DeployDeviceConfigRequest, UnsetDeviceRoleRequest Loading @@ -24,6 +26,7 @@ from common.tools.object_factory.ConfigRule import ( json_config_rule_set, json_config_rule_delete, ) from service.service.tools.object_uuid import get_uuid_from_string from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from spine_leaf.client.SpineLeafClient import SpineLeafClient Loading @@ -38,21 +41,59 @@ LOGGER = logging.getLogger('spineleaf_all_multi_test') # ----------------------------- # ENV # ----------------------------- CONTEXTSERVICE_HOST = os.getenv('CONTEXTSERVICE_SERVICE_HOST', '10.152.183.46') def _resolve_service_host(env_name, service_name, namespace='tfs'): env_value = os.getenv(env_name, '').strip() if env_value: return env_value dns_name = f'{service_name}.{namespace}.svc.cluster.local' try: socket.gethostbyname(dns_name) LOGGER.info('Resolved %s from Kubernetes DNS name %s', env_name, dns_name) return dns_name except OSError: pass try: result = subprocess.run( [ 'microk8s', 'kubectl', 'get', 'svc', service_name, '-n', namespace, '-o', 'jsonpath={.spec.clusterIP}', ], check=True, capture_output=True, text=True, ) cluster_ip = result.stdout.strip() if cluster_ip: LOGGER.info('Resolved %s from Kubernetes service %s/%s => %s', env_name, namespace, service_name, cluster_ip) return cluster_ip except (FileNotFoundError, subprocess.CalledProcessError) as exc: LOGGER.warning('Unable to resolve Kubernetes service %s/%s: %s', namespace, service_name, exc) raise RuntimeError( f'Unable to resolve {service_name}. Set {env_name} explicitly, for example ' f'{env_name}=<current-service-ip-or-hostname>.' ) CONTEXTSERVICE_HOST = _resolve_service_host('CONTEXTSERVICE_SERVICE_HOST', 'contextservice') CONTEXTSERVICE_PORT = int(os.getenv('CONTEXTSERVICE_SERVICE_PORT_GRPC', '1010')) DEVICESERVICE_HOST = os.getenv('DEVICESERVICE_SERVICE_HOST', '10.152.183.102') DEVICESERVICE_HOST = _resolve_service_host('DEVICESERVICE_SERVICE_HOST', 'deviceservice') DEVICESERVICE_PORT = int(os.getenv('DEVICESERVICE_SERVICE_PORT_GRPC', '2020')) SPINE_LEAFSERVICE_HOST = os.getenv('SPINE_LEAFSERVICE_SERVICE_HOST', '10.152.183.147') SPINE_LEAFSERVICE_HOST = _resolve_service_host('SPINE_LEAFSERVICE_SERVICE_HOST', 'spine-leafservice') SPINE_LEAFSERVICE_PORT = int(os.getenv('SPINE_LEAFSERVICE_SERVICE_PORT_GRPC', '10095')) FABRIC_ID = os.getenv( 'FABRIC_ID', '354a08b7-3730-5dd6-9472-47554115818b', SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) DEFAULT_DESCRIPTOR_FILE = os.path.join( SCRIPT_DIR, 'data', 'fabric-descriptor-spine1-spine2-leaf1-leaf4-evpn-vxlan-static.json', ) DESCRIPTOR_FILE = os.getenv('DESCRIPTOR_FILE', '') DESCRIPTOR_FILE = os.getenv('DESCRIPTOR_FILE', DEFAULT_DESCRIPTOR_FILE) DEFAULT_DEVICE_UUIDS = [ 'e162b163-6969-512a-8ee9-cce9f0687c64', Loading Loading @@ -89,6 +130,25 @@ def is_apply_enabled() -> bool: return os.getenv('APPLY_CONFIG', 'false').lower() in ('1', 'true', 'yes') def get_fabric_id() -> str: env_fabric_id = os.getenv('FABRIC_ID', '').strip() if env_fabric_id: return env_fabric_id if DESCRIPTOR_FILE and os.path.exists(DESCRIPTOR_FILE): try: with open(DESCRIPTOR_FILE, 'r', encoding='UTF-8') as f: descriptor = json.load(f) fabric = (descriptor.get('spine-leaf') or [{}])[0] fabric_name = str(fabric.get('fabric_name', fabric.get('fabric_id', '')) or '') if fabric_name: return get_uuid_from_string(fabric_name) except Exception: LOGGER.exception('Could not derive fabric id from descriptor %s', DESCRIPTOR_FILE) return '354a08b7-3730-5dd6-9472-47554115818b' def parse_spineleaf_rule(entry): if not isinstance(entry, (list, tuple)) or len(entry) != 2: return None Loading Loading @@ -144,8 +204,9 @@ def build_descriptor_rules(descriptor_file, device_uuid): settings = fabric.get('settings', {}) store = SpineLeafStateStore() fabric_id_value = get_fabric_id() fabric_id, _, _ = store.create_fabric( FABRIC_ID, fabric_id_value, 'spine_leaf', str(settings.get('underlay_type', 'bgp')), str(settings.get('overlay_type', '')), Loading Loading @@ -255,8 +316,18 @@ class ApplySpineLeafConfig: LOGGER.info('') LOGGER.info('=== DEVICE %s ===', device_uuid) deconfigure = is_deconfigure_enabled() descriptor_rules = build_descriptor_rules(DESCRIPTOR_FILE, device_uuid) if deconfigure and descriptor_rules: payload = {'driver_config_rules': []} LOGGER.info( 'Skipping SpineLeaf DeployDeviceConfig for descriptor-driven deconfigure of %s', device_uuid, ) else: request = DeployDeviceConfigRequest( fabric_id=FABRIC_ID, fabric_id=get_fabric_id(), device_uuid=device_uuid, ) Loading @@ -268,12 +339,9 @@ class ApplySpineLeafConfig: LOGGER.info('Parsed payload keys for %s: %s', device_uuid, list(payload.keys())) deconfigure = is_deconfigure_enabled() set_rules = [] delete_rules = [] driver_config_rules = payload.get('driver_config_rules', []) descriptor_rules = build_descriptor_rules(DESCRIPTOR_FILE, device_uuid) if deconfigure and descriptor_rules: seen_rules = { json.dumps(parse_spineleaf_rule(entry), sort_keys=True) Loading Loading @@ -334,7 +402,7 @@ class ApplySpineLeafConfig: LOGGER.info('DELETE result %s => %s', device_uuid, result) unset_request = UnsetDeviceRoleRequest( fabric_id=FABRIC_ID, fabric_id=get_fabric_id(), device_uuid=device_uuid, ) unset_result = self.spine_leaf_client.UnsetDeviceRole(unset_request) Loading Loading @@ -366,9 +434,5 @@ class ApplySpineLeafConfig: device_client.close() context_client.close() # ----------------------------- # ENTRY # ----------------------------- if __name__ == '__main__': ApplySpineLeafConfig().run()