diff --git a/test_pathcomp/ComputeSubServices.py b/test_pathcomp/ComputeSubServices.py new file mode 100644 index 0000000000000000000000000000000000000000..e0b229625838dd3f9300f4fde774b310c7511f53 --- /dev/null +++ b/test_pathcomp/ComputeSubServices.py @@ -0,0 +1,255 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Convert the path defined as explicit hops with ingress and egress endpoints per device into a set of connections and +# compute the dependencies among them. +# +# Example: +# o-- int DC1 eth1 -- 10/1 CS1 1/2 -- 1/2 R2 2/1 -- a7.. OLS 60.. -- 2/1 R3 1/1 -- 1/1 CS2 10/1 -- eth1 DC2 int --o +# APP PKT PKT CTRL PKT PKT APP +# +# path_hops = [ +# {'device': 'DC1-GW', 'ingress_ep': 'int', 'egress_ep': 'eth1'}, +# {'device': 'CS1-GW1', 'ingress_ep': '10/1', 'egress_ep': '1/2'}, +# {'device': 'TN-R2', 'ingress_ep': '1/2', 'egress_ep': '2/1'}, +# {'device': 'TN-OLS', 'ingress_ep': 'a7a80b23a703', 'egress_ep': '60519106029e'}, +# {'device': 'TN-R3', 'ingress_ep': '2/1', 'egress_ep': '1/1'}, +# {'device': 'CS2-GW1', 'ingress_ep': '1/1', 'egress_ep': '10/1'}, +# {'device': 'DC2-GW', 'ingress_ep': 'eth1', 'egress_ep': 'int'} +# ] +# +# connections=[ +# (UUID('7548edf7-ee7c-4adf-ac0f-c7a0c0dfba8e'), <DeviceLayerEnum.OPTICAL_CONTROLLER: 1>, [ +# {'device': 'TN-OLS', 'ingress_ep': '833760219d0f', 'egress_ep': 'cf176771a4b9'} +# ], []), +# (UUID('c2e57966-5d82-4705-a5fe-44cf6487219e'), <DeviceLayerEnum.PACKET_DEVICE: 30>, [ +# {'device': 'CS1-GW1', 'ingress_ep': '10/1', 'egress_ep': '1/2'}, +# {'device': 'TN-R2', 'ingress_ep': '1/2', 'egress_ep': '2/1'}, +# {'device': 'TN-R3', 'ingress_ep': '2/1', 'egress_ep': '1/1'}, +# {'device': 'CS2-GW1', 'ingress_ep': '1/1', 'egress_ep': '10/1'} +# ], [UUID('7548edf7-ee7c-4adf-ac0f-c7a0c0dfba8e')]), +# (UUID('1e205c82-f6ea-4977-9e97-dc27ef1f4802'), <DeviceLayerEnum.APPLICATION_DEVICE: 40>, [ +# {'device': 'DC1-GW', 'ingress_ep': 'int', 'egress_ep': 'eth1'}, +# {'device': 'DC2-GW', 'ingress_ep': 'eth1', 'egress_ep': 'int'} +# ], [UUID('c2e57966-5d82-4705-a5fe-44cf6487219e')]) +# ] + +import enum, json, queue, uuid +from typing import Dict, List, Optional, Tuple +from common.DeviceTypes import DeviceTypeEnum +from common.proto.context_pb2 import Device, ServiceTypeEnum #, DeviceDriverEnum as grpc_DeviceDriverEnum +#from .ConstantsMappings import DEVICE_TYPE_TO_LAYER, DeviceLayerEnum + +class StackActionEnum(enum.Enum): + PATH_INGRESS = 'ingress' + CREATE_CONNECTION = 'create' + APPEND_PATH_HOP = 'append' + CHAIN_CONNECTION = 'chain' + TERMINATE_CONNECTION = 'terminate' + +#class DeviceDriverEnum(enum.IntEnum): +# EMULATED = grpc_DeviceDriverEnum.DEVICEDRIVER_UNDEFINED +# OPENCONFIG = grpc_DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG +# TRANSPORT_API = grpc_DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API +# P4 = grpc_DeviceDriverEnum.DEVICEDRIVER_P4 +# IETF_NETWORK_TOPOLOGY = grpc_DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY +# ONF_TR_352 = grpc_DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352 +# XR = grpc_DeviceDriverEnum.DEVICEDRIVER_XR +# IETF_L2VPN = grpc_DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN + +def is_datacenter(dev_type : Optional[DeviceTypeEnum]) -> bool: + return dev_type in {DeviceTypeEnum.DATACENTER, DeviceTypeEnum.EMULATED_DATACENTER} + +def is_packet_router(dev_type : Optional[DeviceTypeEnum]) -> bool: + return dev_type in {DeviceTypeEnum.PACKET_ROUTER, DeviceTypeEnum.EMULATED_PACKET_ROUTER} + +def is_packet_switch(dev_type : Optional[DeviceTypeEnum]) -> bool: + return dev_type in {DeviceTypeEnum.PACKET_SWITCH, DeviceTypeEnum.EMULATED_PACKET_SWITCH} + +def is_packet_device(dev_type : Optional[DeviceTypeEnum]) -> bool: + return is_packet_router(dev_type) or is_packet_switch(dev_type) + +def is_tfs_controller(dev_type : Optional[DeviceTypeEnum]) -> bool: + return dev_type in {DeviceTypeEnum.TERAFLOWSDN_CONTROLLER} + +def is_mw_controller(dev_type : Optional[DeviceTypeEnum]) -> bool: + return dev_type in {DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM, DeviceTypeEnum.EMULATED_MICROWAVE_RADIO_SYSTEM} + +def is_ipm_controller(dev_type : Optional[DeviceTypeEnum]) -> bool: + return dev_type in {DeviceTypeEnum.XR_CONSTELLATION, DeviceTypeEnum.EMULATED_XR_CONSTELLATION} + +def is_ols_controller(dev_type : Optional[DeviceTypeEnum]) -> bool: + return dev_type in {DeviceTypeEnum.OPEN_LINE_SYSTEM, DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM} + +def is_subdevice(dev_manager : Optional[str]) -> bool: + return dev_manager is not None + +def is_subdevice_equal(dev_manager_a : Optional[str], dev_manager_b : Optional[str]) -> bool: + if dev_manager_a is None and dev_manager_b is None: return True + if dev_manager_a is not None and dev_manager_b is not None: return dev_manager_a == dev_manager_b + return False + +#def has_driver(dev_drivers : List[DeviceDriverEnum], dev_driver : DeviceDriverEnum) -> bool: +# return dev_driver in dev_drivers + +def get_action( + prv_type : Optional[DeviceTypeEnum], prv_manager : Optional[str], + cur_type : DeviceTypeEnum, cur_manager : Optional[str] +) -> StackActionEnum: + if prv_type is None: + return StackActionEnum.PATH_INGRESS + + if is_datacenter(prv_type): + if is_packet_device(cur_type): return StackActionEnum.CREATE_CONNECTION + if is_tfs_controller(cur_type): return StackActionEnum.CREATE_CONNECTION + + if is_packet_device(prv_type): + if is_datacenter(cur_type): return StackActionEnum.TERMINATE_CONNECTION + if is_packet_device(cur_type): + if is_subdevice_equal(cur_manager, prv_manager): return StackActionEnum.APPEND_PATH_HOP + if is_subdevice(prv_manager) and not is_subdevice(cur_manager): return StackActionEnum.TERMINATE_CONNECTION + if not is_subdevice(prv_manager) and is_subdevice(cur_manager): return StackActionEnum.CREATE_CONNECTION + + if is_mw_controller(cur_type) and not is_subdevice(cur_manager): return StackActionEnum.CREATE_CONNECTION + if is_ols_controller(cur_type) and not is_subdevice(cur_manager): return StackActionEnum.CREATE_CONNECTION + if is_tfs_controller(cur_type) and is_subdevice(cur_manager): return StackActionEnum.CREATE_CONNECTION + + if is_mw_controller(prv_type) or is_ols_controller(prv_type): + if is_packet_device(cur_type): return StackActionEnum.TERMINATE_CONNECTION + + if is_tfs_controller(prv_type): + if is_tfs_controller(cur_type) and is_subdevice_equal(prv_manager, cur_manager): return StackActionEnum.APPEND_PATH_HOP + if is_datacenter(cur_type): return StackActionEnum.TERMINATE_CONNECTION + if is_packet_device(cur_type): return StackActionEnum.TERMINATE_CONNECTION + if is_mw_controller(cur_type) or is_ols_controller(cur_type): return StackActionEnum.CHAIN_CONNECTION + + str_fields = ', '.join([ + 'prv_type={:s}'.format(str(prv_type)), 'prv_manager={:s}'.format(str(prv_manager)), + 'cur_type={:s}'.format(str(cur_type)), 'cur_manager={:s}'.format(str(cur_manager)), + ]) + raise Exception('Undefined Action for ({:s})'.format(str_fields)) + +def get_device_manager_uuid(device : Device) -> Optional[str]: + for config_rule in device.device_config.config_rules: + if config_rule.WhichOneof('config_rule') != 'custom': continue + if config_rule.custom.resource_key != '_manager': continue + device_manager_id = json.loads(config_rule.custom.resource_value) + return device_manager_id['uuid'] + return None + +def get_device_type( + grpc_device : Device, device_dict : Dict[str, Tuple[Dict, Device]], device_manager_uuid : Optional[str] +) -> DeviceTypeEnum: + if device_manager_uuid is None: + return DeviceTypeEnum._value2member_map_[grpc_device.device_type] # pylint: disable=no-member + device_manager_tuple = device_dict.get(device_manager_uuid) + if device_manager_tuple is None: raise Exception('Device({:s}) not found'.format(str(device_manager_uuid))) + _,grpc_device = device_manager_tuple + return DeviceTypeEnum._value2member_map_[grpc_device.device_type] # pylint: disable=no-member + + #manager_drivers = set(grpc_device.device_drivers) + #if DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN in manager_drivers: + # device_layer = DeviceLayerEnum.MAC_LAYER_CONTROLLER + #else: + # device_type = json_device['device_type'] + # device_layer = DEVICE_TYPE_TO_LAYER.get(device_type) + # if device_layer is None: raise Exception('Undefined Layer for DeviceType({:s})'.format(str(device_type))) + +SERVICE_TYPE_LXNM = {ServiceTypeEnum.SERVICETYPE_L3NM, ServiceTypeEnum.SERVICETYPE_L2NM} + +def get_service_type(device_type : DeviceTypeEnum, prv_service_type : ServiceTypeEnum) -> ServiceTypeEnum: + if is_tfs_controller(device_type) or is_packet_router(device_type): + if prv_service_type in SERVICE_TYPE_LXNM: return prv_service_type + if is_packet_switch(device_type) or is_mw_controller(device_type): + if prv_service_type == ServiceTypeEnum.SERVICETYPE_L2NM: return prv_service_type + if is_ols_controller(device_type) or is_ipm_controller(device_type): + return ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE + + str_fields = ', '.join([ + 'device_type={:s}'.format(str(device_type)), + ]) + raise Exception('Undefined Service Type for ({:s})'.format(str_fields)) + +def convert_explicit_path_hops_to_connections( + path_hops : List[Dict], device_dict : Dict[str, Tuple[Dict, Device]], + main_service_uuid : str, main_service_type : ServiceTypeEnum +) -> List[Tuple[str, int, List[str], List[str]]]: + + connection_stack = queue.LifoQueue() + connections : List[Tuple[str, int, List[str], List[str]]] = list() + prv_device_uuid = None + prv_device_type = None + prv_manager_uuid = None + + for path_hop in path_hops: + device_uuid = path_hop['device'] + if prv_device_uuid == device_uuid: continue + device_tuple = device_dict.get(device_uuid) + if device_tuple is None: raise Exception('Device({:s}) not found'.format(str(device_uuid))) + _,grpc_device = device_tuple + + manager_uuid = get_device_manager_uuid(grpc_device) + device_type = get_device_type(grpc_device, device_dict, manager_uuid) + action = get_action(prv_device_type, prv_manager_uuid, device_type, manager_uuid) + + if action == StackActionEnum.PATH_INGRESS: + connection_stack.put((main_service_uuid, main_service_type, [path_hop], [])) + elif action == StackActionEnum.CREATE_CONNECTION: + connection_uuid = str(uuid.uuid4()) + prv_service_type = connection_stack.queue[-1][1] + service_type = get_service_type(device_type, prv_service_type) + connection_stack.put((connection_uuid, service_type, [path_hop], [])) + elif action == StackActionEnum.APPEND_PATH_HOP: + connection_stack.queue[-1][2].append(path_hop) + elif action == StackActionEnum.CHAIN_CONNECTION: + connection = connection_stack.get() + connections.append(connection) + connection_stack.queue[-1][3].append(connection[0]) + + connection_uuid = str(uuid.uuid4()) + prv_service_type = connection_stack.queue[-1][1] + service_type = get_service_type(device_type, prv_service_type) + connection_stack.put((connection_uuid, service_type, [path_hop], [])) + elif action == StackActionEnum.TERMINATE_CONNECTION: + connection = connection_stack.get() + connections.append(connection) + connection_stack.queue[-1][3].append(connection[0]) + connection_stack.queue[-1][2].append(path_hop) + else: + raise Exception('Uncontrolled condition') + + prv_device_uuid = device_uuid + prv_device_type = device_type + prv_manager_uuid = manager_uuid + + # path egress + connections.append(connection_stack.get()) + assert connection_stack.empty() + return connections + +def convert_explicit_path_hops_to_plain_connection( + path_hops : List[Dict], main_service_uuid : str, main_service_type : ServiceTypeEnum +) -> List[Tuple[str, int, List[str], List[str]]]: + + connection : Tuple[str, int, List[str], List[str]] = \ + (main_service_uuid, main_service_type, [], []) + + prv_device_uuid = None + for path_hop in path_hops: + device_uuid = path_hop['device'] + if prv_device_uuid == device_uuid: continue + connection[2].append(path_hop) + prv_device_uuid = device_uuid + + return [connection] diff --git a/test_pathcomp/__init__.py b/test_pathcomp/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612 --- /dev/null +++ b/test_pathcomp/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + diff --git a/test_pathcomp/__main__.py b/test_pathcomp/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..6af584fe92748a54b6dd47c3965339577fabace0 --- /dev/null +++ b/test_pathcomp/__main__.py @@ -0,0 +1,33 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import logging, sys +from common.proto.context_pb2 import ServiceTypeEnum +from .data import path_hops, device_dict +from .ComputeSubServices import convert_explicit_path_hops_to_connections + +logging.basicConfig(level=logging.DEBUG) +LOGGER = logging.getLogger(__name__) + +def main(): + service_uuid = 'dc-2-dc-svc' + service_type = ServiceTypeEnum.SERVICETYPE_L2NM + connections = convert_explicit_path_hops_to_connections(path_hops, device_dict, service_uuid, service_type) + str_connections = '\n'.join([' ' + str(connection) for connection in connections]) + LOGGER.debug('connections = [\n{:s}\n]'.format(str_connections)) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/test_pathcomp/data.py b/test_pathcomp/data.py new file mode 100644 index 0000000000000000000000000000000000000000..5e94d969e31e86a572300483ca9b603cbf1d1417 --- /dev/null +++ b/test_pathcomp/data.py @@ -0,0 +1,115 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +from typing import Dict, Tuple +from common.proto.context_pb2 import ConfigActionEnum, Device + +path_hops = [ + {'device': 'DC1', 'ingress_ep': 'int', 'egress_ep': 'eth1'}, + {'device': 'PE1', 'ingress_ep': '1/1', 'egress_ep': '1/2'}, + {'device': 'MW1-2', 'ingress_ep': '172.18.0.1:1', 'egress_ep': '172.18.0.2:1'}, + {'device': 'R1', 'ingress_ep': '1/1', 'egress_ep': '1/3'}, + {'device': 'OLS', 'ingress_ep': 'aade6001-f00b-5e2f-a357-6a0a9d3de870', 'egress_ep': '0ef74f99-1acc-57bd-ab9d-4b958b06c513'}, + {'device': 'R2', 'ingress_ep': '1/1', 'egress_ep': '1/2'}, + {'device': 'PE3', 'ingress_ep': '1/1', 'egress_ep': '1/2'}, + {'device': 'DC2', 'ingress_ep': 'eth1', 'egress_ep': 'int'} +] + +device_dict = { + 'R3': {'device_Id': 'R3', 'device_type': 'emu-packet-router', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'R3', 'endpoint_uuid': '1/1'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'R3', 'endpoint_uuid': '1/2'}, 'endpoint_type': 'copper/internal'} + ]}, + 'PE4': {'device_Id': 'PE4', 'device_type': 'emu-packet-router', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'PE4', 'endpoint_uuid': 'mgmt'}, 'endpoint_type': 'mgmt'}, + {'endpoint_id': {'device_id': 'PE4', 'endpoint_uuid': '1/1'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'PE4', 'endpoint_uuid': '1/2'}, 'endpoint_type': 'copper/internal'} + ]}, + 'PE2': {'device_Id': 'PE2', 'device_type': 'emu-packet-router', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'PE2', 'endpoint_uuid': '1/1'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'PE2', 'endpoint_uuid': 'mgmt'}, 'endpoint_type': 'mgmt'}, + {'endpoint_id': {'device_id': 'PE2', 'endpoint_uuid': '1/2'}, 'endpoint_type': 'copper/internal'} + ]}, + 'R1': {'device_Id': 'R1', 'device_type': 'emu-packet-router', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'R1', 'endpoint_uuid': '1/1'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'R1', 'endpoint_uuid': '1/3'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'R1', 'endpoint_uuid': '1/2'}, 'endpoint_type': 'copper/internal'} + ]}, + 'PE3': {'device_Id': 'PE3', 'device_type': 'emu-packet-router', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'PE3', 'endpoint_uuid': '1/1'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'PE3', 'endpoint_uuid': '1/2'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'PE3', 'endpoint_uuid': 'mgmt'}, 'endpoint_type': 'mgmt'} + ]}, + 'OLS': {'device_Id': 'OLS', 'device_type': 'emu-open-line-system', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'OLS', 'endpoint_uuid': '0ef74f99-1acc-57bd-ab9d-4b958b06c513'}, 'endpoint_type': 'optical'}, + {'endpoint_id': {'device_id': 'OLS', 'endpoint_uuid': '50296d99-58cc-5ce7-82f5-fc8ee4eec2ec'}, 'endpoint_type': 'optical'}, + {'endpoint_id': {'device_id': 'OLS', 'endpoint_uuid': 'aade6001-f00b-5e2f-a357-6a0a9d3de870'}, 'endpoint_type': 'optical'}, + {'endpoint_id': {'device_id': 'OLS', 'endpoint_uuid': 'eb287d83-f05e-53ec-ab5a-adf6bd2b5418'}, 'endpoint_type': 'optical'} + ]}, + 'PE1': {'device_Id': 'PE1', 'device_type': 'emu-packet-router', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'PE1', 'endpoint_uuid': '1/2'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'PE1', 'endpoint_uuid': 'mgmt'}, 'endpoint_type': 'mgmt'}, + {'endpoint_id': {'device_id': 'PE1', 'endpoint_uuid': '1/1'}, 'endpoint_type': 'copper/internal'} + ]}, + 'DC2': {'device_Id': 'DC2', 'device_type': 'emu-datacenter', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'DC2', 'endpoint_uuid': 'eth1'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'DC2', 'endpoint_uuid': 'eth2'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'DC2', 'endpoint_uuid': 'int'}, 'endpoint_type': 'copper/internal'} + ]}, + 'MW1-2': {'device_Id': 'MW1-2', 'device_type': 'emu-microwave-radio-system', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'MW1-2', 'endpoint_uuid': '172.18.0.1:1'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'MW1-2', 'endpoint_uuid': '172.18.0.2:1'}, 'endpoint_type': 'copper/internal'} + ]}, + 'MW3-4': {'device_Id': 'MW3-4', 'device_type': 'emu-microwave-radio-system', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'MW3-4', 'endpoint_uuid': '172.18.0.3:1'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'MW3-4', 'endpoint_uuid': '172.18.0.4:1'}, 'endpoint_type': 'copper/internal'} + ]}, + 'TFS': {'device_Id': 'TFS', 'device_type': 'teraflowsdn', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'TFS', 'endpoint_uuid': 'mgmt'}, 'endpoint_type': 'mgmt'} + ]}, + 'R2': {'device_Id': 'R2', 'device_type': 'emu-packet-router', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'R2', 'endpoint_uuid': '1/2'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'R2', 'endpoint_uuid': '1/1'}, 'endpoint_type': 'copper/internal'} + ]}, + 'DC1': {'device_Id': 'DC1', 'device_type': 'emu-datacenter', 'device_endpoints': [ + {'endpoint_id': {'device_id': 'DC1', 'endpoint_uuid': 'int'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'DC1', 'endpoint_uuid': 'eth1'}, 'endpoint_type': 'copper/internal'}, + {'endpoint_id': {'device_id': 'DC1', 'endpoint_uuid': 'eth2'}, 'endpoint_type': 'copper/internal'} + ]}, +} + +MANAGED_DEVICES = {'PE1', 'PE2', 'PE3', 'PE4'} +MANAGER = 'TFS' + +def process_device(json_device) -> Tuple[Dict, Device]: + device_uuid = json_device['device_Id'] + + grpc_device = Device() + grpc_device.device_id.device_uuid.uuid = device_uuid + grpc_device.device_type = json_device['device_type'] + + if device_uuid in MANAGED_DEVICES: + config_rule = grpc_device.device_config.config_rules.add() + config_rule.action = ConfigActionEnum.CONFIGACTION_SET + config_rule.custom.resource_key = '_manager' + config_rule.custom.resource_value = json.dumps({'uuid': MANAGER}) + + return json_device, grpc_device + +device_dict = { + device_uuid:process_device(json_device) + for device_uuid,json_device in device_dict.items() +} diff --git a/test_pathcomp/format.sh b/test_pathcomp/format.sh new file mode 100755 index 0000000000000000000000000000000000000000..ceeea5d3165213ab25f07512e64cfc5e75346408 --- /dev/null +++ b/test_pathcomp/format.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +sed -i 's#0dff8c06-873b-5799-ac54-c0452252bae1#R3#g' log.txt +sed -i 's#1102e0b5-824b-57eb-86a1-d247e2deaf68#PE4#g' log.txt +sed -i 's#29d766ca-d222-5257-bab3-6a060719270a#PE2#g' log.txt +sed -i 's#68741528-2e94-5274-ab3c-fddcd8dc05ef#R1#g' log.txt +sed -i 's#69a3a3f0-5237-5f9e-bc96-d450d0c6c02a#PE3#g' log.txt +sed -i 's#6ab8fa38-ec20-5c32-8d9b-4fd86fce2555#OLS#g' log.txt +sed -i 's#7faa13eb-903d-58f5-936b-1a1174fe98fd#PE1#g' log.txt +sed -i 's#800d5bd4-a7a3-5a66-82ab-d399767ca3d8#DC2#g' log.txt +sed -i 's#90c22ce2-4f8d-51b4-8d7a-762eea9b310a#MW#g' log.txt +sed -i 's#a23cdc36-074d-5423-8abd-4a167a6e6fbc#TFS#g' log.txt +sed -i 's#c944aaeb-bbdf-5f2d-b31c-8cc8903045b6#R2#g' log.txt +sed -i 's#cda90d2f-e7b0-5837-8f2e-2fb29dd9b367#DC1#g' log.txt +sed -i 's#79f4184c-d375-5e2c-a3df-1ae64537c95c#1/1#g' log.txt +sed -i 's#93c853c2-429c-52e8-9ba9-454fcedb9090#1/2#g' log.txt +sed -i 's#1fe2ee1a-fe92-57c9-afd9-260e6f0ecc54#mgmt#g' log.txt +sed -i 's#cd378805-d73e-5681-8514-1d33e656c0e9#1/1#g' log.txt +sed -i 's#e502e939-3ab8-5fee-8277-7fd1c1c0fa93#1/2#g' log.txt +sed -i 's#780f6929-a863-5e6a-a046-3dac2e24bf58#1/1#g' log.txt +sed -i 's#f1082088-a304-587b-a230-b8ce10e5a148#mgmt#g' log.txt +sed -i 's#ffdfb0ce-1684-5d39-bad3-9ff1eb4ffbf8#1/2#g' log.txt +sed -i 's#268b735d-c861-5319-88a4-2ea498f96a04#1/1#g' log.txt +sed -i 's#62c0cba1-9ee8-5db5-82da-ce96d7e0f39f#1/3#g' log.txt +sed -i 's#7d1bf45c-5ab2-525e-87a4-c0ddcd5c18e4#1/2#g' log.txt +sed -i 's#2b11934b-dfd7-5267-87b9-7306a24e0182#1/1#g' log.txt +sed -i 's#ca92338e-2038-5d74-8ef1-2b20a234a8b9#1/2#g' log.txt +sed -i 's#f8955e74-4e93-5d43-a968-9626ee5c9b53#mgmt#g' log.txt +sed -i 's#2b75d88d-095f-5752-a10a-1ff69df8008d#1/2#g' log.txt +sed -i 's#bf0d75db-acf8-53cb-b6db-32d9dc0878c4#mgmt#g' log.txt +sed -i 's#eeade85a-03df-55d2-bfc2-2af7267bbcf3#1/1#g' log.txt +sed -i 's#06bb0b92-8783-5599-aa20-15bfbe241348#eth1#g' log.txt +sed -i 's#6a6859c3-4a13-513c-a7dd-490c8b2931b1#eth2#g' log.txt +sed -i 's#97f57787-cfec-5315-9718-7e850905f11a#int#g' log.txt +sed -i 's#659c63c9-9197-54a2-af34-48275e736aac#192.168.27.140:8#g' log.txt +sed -i 's#fed79944-3444-54ee-8335-efbe6590434b#192.168.27.139:10#g' log.txt +sed -i 's#85bb83b0-8d96-5e76-9959-97c35036d4f9#mgmt#g' log.txt +sed -i 's#313fb1ed-5dee-5e49-884a-cbb3b1e00073#1/2#g' log.txt +sed -i 's#79699f56-df25-5188-a389-04606c24fbfc#1/1#g' log.txt +sed -i 's#37ab67ef-0064-54e3-ae9b-d40100953834#int#g' log.txt +sed -i 's#55e88b6b-ccf7-538f-a062-a41219292ea1#eth1#g' log.txt +sed -i 's#68b5972b-3630-53a8-ba9b-cc54dd31f8b8#eth2#g' log.txt