Loading src/service/service/service_handlers/l3slice_ietfslice/ConfigRules.py +163 −139 Original line number Diff line number Diff line # Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) # Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (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. Loading @@ -22,8 +22,114 @@ from common.tools.object_factory.ConfigRule import ( from context.client.ContextClient import ContextClient def build_match_criterion( vlan: str, src_ip: str, src_port: str, dst_ip: str, dst_port: str, target_conn_group_id: str = "line1", index: int = 1, ) -> Dict: """ Build the match-criterion structure used in the 'service-match-criteria'. """ return { "index": index, "match-type": [ {"type": "ietf-network-slice-service:vlan", "value": [vlan]}, { "type": "ietf-network-slice-service:source-ip-prefix", "value": [src_ip], }, { "type": "ietf-network-slice-service:source-tcp-port", "value": [src_port], }, { "type": "ietf-network-slice-service:destination-ip-prefix", "value": [dst_ip], }, { "type": "ietf-network-slice-service:destination-tcp-port", "value": [dst_port], }, ], "target-connection-group-id": target_conn_group_id, } def build_sdp( sdp_id: str, node_id: str, mgmt_ip: str, ac_node_id: str, ac_ep_id: str, match_criterion: Dict, attachment_id: str = "0", attachment_description: str = "dsc", ) -> Dict: """ Build the sdp structure used in the 'slice_service' dictionary. """ return { "id": sdp_id, "node-id": node_id, "sdp-ip-address": [mgmt_ip], "service-match-criteria": {"match-criterion": [match_criterion]}, "attachment-circuits": { "attachment-circuit": [ { "id": attachment_id, "description": attachment_description, "ac-node-id": ac_node_id, "ac-tp-id": ac_ep_id, } ] }, } def build_slo_policy_bound( one_way_delay: int, one_way_bandwidth: int, one_way_packet_loss: float ) -> List[Dict]: """ Build the 'metric-bound' portion of the 'slo-policy' dictionary. """ return [ { "metric-type": "ietf-network-slice-service:one-way-delay-maximum", "metric-unit": "milliseconds", "bound": one_way_delay, }, { "metric-type": "ietf-network-slice-service:one-way-bandwidth", "metric-unit": "Mbps", "bound": one_way_bandwidth, }, { "metric-type": "ietf-network-slice-service:two-way-packet-loss", "metric-unit": "percentage", "percentile-value": one_way_packet_loss, }, ] def _get_device_endpoint_name(device_obj, endpoint_uuid: str) -> str: """ Given a device object and an endpoint UUID, return the device endpoint name. Raises an exception if not found. """ for d_ep in device_obj.device_endpoints: if d_ep.endpoint_id.endpoint_uuid.uuid == endpoint_uuid: return d_ep.name raise Exception("Endpoint not found") def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: operation_type: str = json_settings["operation_type"] # Source parameters src_node_id: str = json_settings["src_node_id"] src_mgmt_ip_address: str = json_settings["src_mgmt_ip_address"] src_ac_node_id: str = json_settings["src_ac_node_id"] Loading @@ -38,6 +144,8 @@ def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: source_one_way_packet_loss: float = float( json_settings["source_one_way_packet_loss"] ) # Destination parameters dst_node_id: str = json_settings["dst_node_id"] dst_mgmt_ip_address: str = json_settings["dst_mgmt_ip_address"] dst_ac_node_id: str = json_settings["dst_ac_node_id"] Loading @@ -54,101 +162,47 @@ def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: destination_one_way_packet_loss: float = float( json_settings["destination_one_way_packet_loss"] ) # Slice ID slice_id: str = json_settings["slice_id"] sdps = [ { "id": "1", "node-id": src_node_id, "sdp-ip-address": [src_mgmt_ip_address], "service-match-criteria": { "match-criterion": [ { "index": 1, "match-type": [ { "type": "ietf-network-slice-service:vlan", "value": [src_vlan], }, { "type": "ietf-network-slice-service:source-ip-prefix", "value": [src_source_ip_prefix], }, { "type": "ietf-network-slice-service:source-tcp-port", "value": [src_source_tcp_port], }, { "type": "ietf-network-slice-service:destination-ip-prefix", "value": [src_destination_ip_prefix], }, { "type": "ietf-network-slice-service:destination-tcp-port", "value": [src_destination_tcp_port], }, ], "target-connection-group-id": "line1", } ] }, "attachment-circuits": { "attachment-circuit": [ { "id": "0", "description": "dsc", "ac-node-id": src_ac_node_id, "ac-tp-id": src_ac_ep_id, } ] }, }, { "id": "2", "node-id": dst_node_id, "sdp-ip-address": [dst_mgmt_ip_address], "service-match-criteria": { "match-criterion": [ { "index": 1, "match-type": [ { "type": "ietf-network-slice-service:vlan", "value": [dst_vlan], }, { "type": "ietf-network-slice-service:source-ip-prefix", "value": [dst_source_ip_prefix], }, { "type": "ietf-network-slice-service:source-tcp-port", "value": [dst_source_tcp_port], }, { "type": "ietf-network-slice-service:destination-ip-prefix", "value": [dst_destination_ip_prefix], }, { "type": "ietf-network-slice-service:destination-tcp-port", "value": [dst_destination_tcp_port], }, ], "target-connection-group-id": "line1", } ] }, "attachment-circuits": { "attachment-circuit": [ { "id": "0", "description": "dsc", "ac-node-id": dst_ac_node_id, "ac-tp-id": dst_ac_ep_id, } ] }, }, ] # build source & destination match criteria src_match_criterion = build_match_criterion( vlan=src_vlan, src_ip=src_source_ip_prefix, src_port=src_source_tcp_port, dst_ip=src_destination_ip_prefix, dst_port=src_destination_tcp_port, ) dst_match_criterion = build_match_criterion( vlan=dst_vlan, src_ip=dst_source_ip_prefix, src_port=dst_source_tcp_port, dst_ip=dst_destination_ip_prefix, dst_port=dst_destination_tcp_port, ) # Build SDPs sdp_src = build_sdp( sdp_id="1", node_id=src_node_id, mgmt_ip=src_mgmt_ip_address, ac_node_id=src_ac_node_id, ac_ep_id=src_ac_ep_id, match_criterion=src_match_criterion, ) sdp_dst = build_sdp( sdp_id="2", node_id=dst_node_id, mgmt_ip=dst_mgmt_ip_address, ac_node_id=dst_ac_node_id, ac_ep_id=dst_ac_ep_id, match_criterion=dst_match_criterion, ) sdps = [sdp_src, sdp_dst] # Build connection-groups connection_groups = [ { "id": "line1", Loading @@ -160,23 +214,11 @@ def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: "p2p-receiver-sdp": "2", "service-slo-sle-policy": { "slo-policy": { "metric-bound": [ { "metric-type": "ietf-network-slice-service:one-way-delay-maximum", "metric-unit": "milliseconds", "bound": source_one_way_delay, }, { "metric-type": "ietf-network-slice-service:one-way-bandwidth", "metric-unit": "Mbps", "bound": source_one_way_bandwidth, }, { "metric-type": "ietf-network-slice-service:two-way-packet-loss", "metric-unit": "percentage", "percentile-value": source_one_way_packet_loss, }, ] "metric-bound": build_slo_policy_bound( one_way_delay=source_one_way_delay, one_way_bandwidth=source_one_way_bandwidth, one_way_packet_loss=source_one_way_packet_loss, ) } }, }, Loading @@ -186,29 +228,18 @@ def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: "p2p-receiver-sdp": "1", "service-slo-sle-policy": { "slo-policy": { "metric-bound": [ { "metric-type": "ietf-network-slice-service:one-way-delay-maximum", "metric-unit": "milliseconds", "bound": destination_one_way_delay, }, { "metric-type": "ietf-network-slice-service:one-way-bandwidth", "metric-unit": "Mbps", "bound": destination_one_way_bandwidth, }, { "metric-type": "ietf-network-slice-service:two-way-packet-loss", "metric-unit": "percentage", "percentile-value": destination_one_way_packet_loss, }, ] "metric-bound": build_slo_policy_bound( one_way_delay=destination_one_way_delay, one_way_bandwidth=destination_one_way_bandwidth, one_way_packet_loss=destination_one_way_packet_loss, ) } }, }, ], } ] slice_service = { "id": slice_id, "description": "dsc", Loading @@ -216,6 +247,7 @@ def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: "connection-groups": {"connection-group": connection_groups}, } slice_data_model = {"network-slice-services": {"slice-service": [slice_service]}} json_config_rules = [ json_config_rule_set( "/service[{:s}]/IETFSlice".format(service_uuid), Loading Loading @@ -250,23 +282,15 @@ def get_link_ep_device_names( ep_device_id_1 = ep_ids[0].device_id ep_uuid_1 = ep_ids[0].endpoint_uuid.uuid device_obj_1 = context_client.GetDevice(ep_device_id_1) for d_ep in device_obj_1.device_endpoints: if d_ep.endpoint_id.endpoint_uuid.uuid == ep_uuid_1: ep_name_1 = d_ep.name break else: raise Exception("endpoint not found") ep_name_1 = _get_device_endpoint_name(device_obj_1, ep_uuid_1) device_obj_name_1 = device_obj_1.name ep_device_id_2 = ep_ids[1].device_id ep_uuid_2 = ep_ids[1].endpoint_uuid.uuid device_obj_2 = context_client.GetDevice(ep_device_id_2) for d_ep in device_obj_2.device_endpoints: if d_ep.endpoint_id.endpoint_uuid.uuid == ep_uuid_2: ep_name_2 = d_ep.name break else: raise Exception("endpoint not found") ep_name_2 = _get_device_endpoint_name(device_obj_2, ep_uuid_2) device_obj_name_2 = device_obj_2.name return ( device_obj_name_1, ep_name_1, Loading src/service/service/service_handlers/l3slice_ietfslice/L3SliceIETFSliceServiceHandler.py +256 −199 File changed.Preview size limit exceeded, changes collapsed. Show changes src/service/service/service_handlers/l3slice_ietfslice/__init__.py +1 −1 Original line number Diff line number Diff line # Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) # Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (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. Loading Loading
src/service/service/service_handlers/l3slice_ietfslice/ConfigRules.py +163 −139 Original line number Diff line number Diff line # Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) # Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (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. Loading @@ -22,8 +22,114 @@ from common.tools.object_factory.ConfigRule import ( from context.client.ContextClient import ContextClient def build_match_criterion( vlan: str, src_ip: str, src_port: str, dst_ip: str, dst_port: str, target_conn_group_id: str = "line1", index: int = 1, ) -> Dict: """ Build the match-criterion structure used in the 'service-match-criteria'. """ return { "index": index, "match-type": [ {"type": "ietf-network-slice-service:vlan", "value": [vlan]}, { "type": "ietf-network-slice-service:source-ip-prefix", "value": [src_ip], }, { "type": "ietf-network-slice-service:source-tcp-port", "value": [src_port], }, { "type": "ietf-network-slice-service:destination-ip-prefix", "value": [dst_ip], }, { "type": "ietf-network-slice-service:destination-tcp-port", "value": [dst_port], }, ], "target-connection-group-id": target_conn_group_id, } def build_sdp( sdp_id: str, node_id: str, mgmt_ip: str, ac_node_id: str, ac_ep_id: str, match_criterion: Dict, attachment_id: str = "0", attachment_description: str = "dsc", ) -> Dict: """ Build the sdp structure used in the 'slice_service' dictionary. """ return { "id": sdp_id, "node-id": node_id, "sdp-ip-address": [mgmt_ip], "service-match-criteria": {"match-criterion": [match_criterion]}, "attachment-circuits": { "attachment-circuit": [ { "id": attachment_id, "description": attachment_description, "ac-node-id": ac_node_id, "ac-tp-id": ac_ep_id, } ] }, } def build_slo_policy_bound( one_way_delay: int, one_way_bandwidth: int, one_way_packet_loss: float ) -> List[Dict]: """ Build the 'metric-bound' portion of the 'slo-policy' dictionary. """ return [ { "metric-type": "ietf-network-slice-service:one-way-delay-maximum", "metric-unit": "milliseconds", "bound": one_way_delay, }, { "metric-type": "ietf-network-slice-service:one-way-bandwidth", "metric-unit": "Mbps", "bound": one_way_bandwidth, }, { "metric-type": "ietf-network-slice-service:two-way-packet-loss", "metric-unit": "percentage", "percentile-value": one_way_packet_loss, }, ] def _get_device_endpoint_name(device_obj, endpoint_uuid: str) -> str: """ Given a device object and an endpoint UUID, return the device endpoint name. Raises an exception if not found. """ for d_ep in device_obj.device_endpoints: if d_ep.endpoint_id.endpoint_uuid.uuid == endpoint_uuid: return d_ep.name raise Exception("Endpoint not found") def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: operation_type: str = json_settings["operation_type"] # Source parameters src_node_id: str = json_settings["src_node_id"] src_mgmt_ip_address: str = json_settings["src_mgmt_ip_address"] src_ac_node_id: str = json_settings["src_ac_node_id"] Loading @@ -38,6 +144,8 @@ def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: source_one_way_packet_loss: float = float( json_settings["source_one_way_packet_loss"] ) # Destination parameters dst_node_id: str = json_settings["dst_node_id"] dst_mgmt_ip_address: str = json_settings["dst_mgmt_ip_address"] dst_ac_node_id: str = json_settings["dst_ac_node_id"] Loading @@ -54,101 +162,47 @@ def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: destination_one_way_packet_loss: float = float( json_settings["destination_one_way_packet_loss"] ) # Slice ID slice_id: str = json_settings["slice_id"] sdps = [ { "id": "1", "node-id": src_node_id, "sdp-ip-address": [src_mgmt_ip_address], "service-match-criteria": { "match-criterion": [ { "index": 1, "match-type": [ { "type": "ietf-network-slice-service:vlan", "value": [src_vlan], }, { "type": "ietf-network-slice-service:source-ip-prefix", "value": [src_source_ip_prefix], }, { "type": "ietf-network-slice-service:source-tcp-port", "value": [src_source_tcp_port], }, { "type": "ietf-network-slice-service:destination-ip-prefix", "value": [src_destination_ip_prefix], }, { "type": "ietf-network-slice-service:destination-tcp-port", "value": [src_destination_tcp_port], }, ], "target-connection-group-id": "line1", } ] }, "attachment-circuits": { "attachment-circuit": [ { "id": "0", "description": "dsc", "ac-node-id": src_ac_node_id, "ac-tp-id": src_ac_ep_id, } ] }, }, { "id": "2", "node-id": dst_node_id, "sdp-ip-address": [dst_mgmt_ip_address], "service-match-criteria": { "match-criterion": [ { "index": 1, "match-type": [ { "type": "ietf-network-slice-service:vlan", "value": [dst_vlan], }, { "type": "ietf-network-slice-service:source-ip-prefix", "value": [dst_source_ip_prefix], }, { "type": "ietf-network-slice-service:source-tcp-port", "value": [dst_source_tcp_port], }, { "type": "ietf-network-slice-service:destination-ip-prefix", "value": [dst_destination_ip_prefix], }, { "type": "ietf-network-slice-service:destination-tcp-port", "value": [dst_destination_tcp_port], }, ], "target-connection-group-id": "line1", } ] }, "attachment-circuits": { "attachment-circuit": [ { "id": "0", "description": "dsc", "ac-node-id": dst_ac_node_id, "ac-tp-id": dst_ac_ep_id, } ] }, }, ] # build source & destination match criteria src_match_criterion = build_match_criterion( vlan=src_vlan, src_ip=src_source_ip_prefix, src_port=src_source_tcp_port, dst_ip=src_destination_ip_prefix, dst_port=src_destination_tcp_port, ) dst_match_criterion = build_match_criterion( vlan=dst_vlan, src_ip=dst_source_ip_prefix, src_port=dst_source_tcp_port, dst_ip=dst_destination_ip_prefix, dst_port=dst_destination_tcp_port, ) # Build SDPs sdp_src = build_sdp( sdp_id="1", node_id=src_node_id, mgmt_ip=src_mgmt_ip_address, ac_node_id=src_ac_node_id, ac_ep_id=src_ac_ep_id, match_criterion=src_match_criterion, ) sdp_dst = build_sdp( sdp_id="2", node_id=dst_node_id, mgmt_ip=dst_mgmt_ip_address, ac_node_id=dst_ac_node_id, ac_ep_id=dst_ac_ep_id, match_criterion=dst_match_criterion, ) sdps = [sdp_src, sdp_dst] # Build connection-groups connection_groups = [ { "id": "line1", Loading @@ -160,23 +214,11 @@ def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: "p2p-receiver-sdp": "2", "service-slo-sle-policy": { "slo-policy": { "metric-bound": [ { "metric-type": "ietf-network-slice-service:one-way-delay-maximum", "metric-unit": "milliseconds", "bound": source_one_way_delay, }, { "metric-type": "ietf-network-slice-service:one-way-bandwidth", "metric-unit": "Mbps", "bound": source_one_way_bandwidth, }, { "metric-type": "ietf-network-slice-service:two-way-packet-loss", "metric-unit": "percentage", "percentile-value": source_one_way_packet_loss, }, ] "metric-bound": build_slo_policy_bound( one_way_delay=source_one_way_delay, one_way_bandwidth=source_one_way_bandwidth, one_way_packet_loss=source_one_way_packet_loss, ) } }, }, Loading @@ -186,29 +228,18 @@ def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: "p2p-receiver-sdp": "1", "service-slo-sle-policy": { "slo-policy": { "metric-bound": [ { "metric-type": "ietf-network-slice-service:one-way-delay-maximum", "metric-unit": "milliseconds", "bound": destination_one_way_delay, }, { "metric-type": "ietf-network-slice-service:one-way-bandwidth", "metric-unit": "Mbps", "bound": destination_one_way_bandwidth, }, { "metric-type": "ietf-network-slice-service:two-way-packet-loss", "metric-unit": "percentage", "percentile-value": destination_one_way_packet_loss, }, ] "metric-bound": build_slo_policy_bound( one_way_delay=destination_one_way_delay, one_way_bandwidth=destination_one_way_bandwidth, one_way_packet_loss=destination_one_way_packet_loss, ) } }, }, ], } ] slice_service = { "id": slice_id, "description": "dsc", Loading @@ -216,6 +247,7 @@ def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: "connection-groups": {"connection-group": connection_groups}, } slice_data_model = {"network-slice-services": {"slice-service": [slice_service]}} json_config_rules = [ json_config_rule_set( "/service[{:s}]/IETFSlice".format(service_uuid), Loading Loading @@ -250,23 +282,15 @@ def get_link_ep_device_names( ep_device_id_1 = ep_ids[0].device_id ep_uuid_1 = ep_ids[0].endpoint_uuid.uuid device_obj_1 = context_client.GetDevice(ep_device_id_1) for d_ep in device_obj_1.device_endpoints: if d_ep.endpoint_id.endpoint_uuid.uuid == ep_uuid_1: ep_name_1 = d_ep.name break else: raise Exception("endpoint not found") ep_name_1 = _get_device_endpoint_name(device_obj_1, ep_uuid_1) device_obj_name_1 = device_obj_1.name ep_device_id_2 = ep_ids[1].device_id ep_uuid_2 = ep_ids[1].endpoint_uuid.uuid device_obj_2 = context_client.GetDevice(ep_device_id_2) for d_ep in device_obj_2.device_endpoints: if d_ep.endpoint_id.endpoint_uuid.uuid == ep_uuid_2: ep_name_2 = d_ep.name break else: raise Exception("endpoint not found") ep_name_2 = _get_device_endpoint_name(device_obj_2, ep_uuid_2) device_obj_name_2 = device_obj_2.name return ( device_obj_name_1, ep_name_1, Loading
src/service/service/service_handlers/l3slice_ietfslice/L3SliceIETFSliceServiceHandler.py +256 −199 File changed.Preview size limit exceeded, changes collapsed. Show changes
src/service/service/service_handlers/l3slice_ietfslice/__init__.py +1 −1 Original line number Diff line number Diff line # Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) # Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (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. Loading