diff --git a/src/service/service/service_handlers/l3nm_ietfl3vpn/ConfigRules.py b/src/service/service/service_handlers/l3nm_ietfl3vpn/ConfigRules.py index 72f0dfd3153e219d235a6a45c4ee450ad7fbf3d8..7649f166e743ec258f6cf2c1d8f30e4cc4347d24 100644 --- a/src/service/service/service_handlers/l3nm_ietfl3vpn/ConfigRules.py +++ b/src/service/service/service_handlers/l3nm_ietfl3vpn/ConfigRules.py @@ -50,15 +50,14 @@ def setup_config_rules( src_pe_address: str = json_settings["src_pe_address"] src_ce_pe_network_prefix: int = json_settings["src_ce_pe_network_prefix"] src_mtu: int = json_settings["src_mtu"] - src_input_bw: int = json_settings.get("src_input_bw", 1000000000) - src_output_bw: int = json_settings.get("src_input_bw", 1000000000) + src_input_bw: int = json_settings["src_input_bw"] + src_output_bw: int = json_settings["src_input_bw"] src_qos_profile_id = "qos-realtime" src_qos_profile_direction = "ietf-l3vpn-svc:both" - src_qos_profile_latency: int = json_settings.get("src_qos_profile_latency", 10) + src_qos_profile_latency: int = json_settings["src_qos_profile_latency"] src_qos_profile_bw_guarantee: int = json_settings.get( "src_qos_profile_bw_guarantee", 100 ) - dst_device_uuid = json_settings["dst_device_name"] dst_endpoint_uuid = json_settings["dst_endpoint_name"] dst_site_location: str = json_settings["dst_site_location"] @@ -76,11 +75,11 @@ def setup_config_rules( dst_pe_address: str = json_settings["dst_pe_address"] dst_ce_pe_network_prefix: int = json_settings["dst_ce_pe_network_prefix"] dst_mtu: int = json_settings["dst_mtu"] - dst_input_bw: int = json_settings.get("dst_input_bw", 1000000000) - dst_output_bw: int = json_settings.get("dst_output_bw", 1000000000) + dst_input_bw: int = json_settings["dst_input_bw"] + dst_output_bw: int = json_settings["dst_output_bw"] dst_qos_profile_id = "qos-realtime" dst_qos_profile_direction = "ietf-l3vpn-svc:both" - dst_qos_profile_latency: int = json_settings.get("dst_qos_profile_latency", 10) + dst_qos_profile_latency: int = json_settings["dst_qos_profile_latency"] dst_qos_profile_bw_guarantee: int = json_settings.get( "dst_qos_profile_bw_guarantee", 100 ) @@ -257,7 +256,7 @@ def setup_config_rules( return json_config_rules -def teardown_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]: +def teardown_config_rules(service_uuid: str) -> List[Dict]: json_config_rules = [ json_config_rule_delete( "/service[{:s}]/IETFL3VPN".format(service_uuid), diff --git a/src/service/service/service_handlers/l3nm_ietfl3vpn/L3NM_IETFL3VPN_ServiceHandler.py b/src/service/service/service_handlers/l3nm_ietfl3vpn/L3NM_IETFL3VPN_ServiceHandler.py index 2d9f369fa5e4b67fe97b92af9d379a551d72a23a..64423129d5fe45d670e181c2520d896efaf596c4 100644 --- a/src/service/service/service_handlers/l3nm_ietfl3vpn/L3NM_IETFL3VPN_ServiceHandler.py +++ b/src/service/service/service_handlers/l3nm_ietfl3vpn/L3NM_IETFL3VPN_ServiceHandler.py @@ -27,7 +27,6 @@ from common.proto.context_pb2 import ( Service, ServiceConfig, ) -from common.tools.object_factory.ConfigRule import json_config_rule_delete from common.tools.object_factory.Device import json_device_id from common.type_checkers.Checkers import chk_type from service.service.service_handler_api._ServiceHandler import _ServiceHandler @@ -38,7 +37,7 @@ from service.service.service_handler_api.Tools import ( ) from service.service.task_scheduler.TaskExecutor import TaskExecutor -from .ConfigRules import setup_config_rules +from .ConfigRules import setup_config_rules, teardown_config_rules RUNNING_RESOURCE_KEY = "running_ietf_slice" CANDIDATE_RESOURCE_KEY = "candidate_ietf_slice" @@ -62,6 +61,56 @@ class Ipv4Info(TypedDict): vlan: str +class QoSInfo(TypedDict): + src_qos_profile_latency: int + src_input_bw: int + src_output_bw: int + dst_qos_profile_latency: int + dst_input_bw: int + dst_output_bw: int + + +def extract_qos_info_from_connection_group( + src_sdp_id: str, dst_sdp_id: str, connectivity_constructs: dict +) -> QoSInfo: + def extract_qos_info(cc: dict) -> Tuple[int, int]: + for metric_bound in cc["service-slo-sle-policy"]["slo-policy"]["metric-bound"]: + if ( + metric_bound["metric-type"] + == "ietf-network-slice-service:one-way-delay-maximum" + and metric_bound["metric-unit"] == "milliseconds" + ): + max_delay = int(metric_bound["bound"]) + elif ( + metric_bound["metric-type"] + == "ietf-network-slice-service:one-way-bandwidth" + and metric_bound["metric-unit"] == "Mbps" + ): + bandwidth = int(metric_bound["bound"]) * 1e6 + return max_delay, bandwidth + + src_cc = next( + cc + for cc in connectivity_constructs + if cc["p2p-sender-sdp"] == src_sdp_id and cc["p2p-receiver-sdp"] == dst_sdp_id + ) + dst_cc = next( + cc + for cc in connectivity_constructs + if cc["p2p-sender-sdp"] == dst_sdp_id and cc["p2p-receiver-sdp"] == src_sdp_id + ) + src_max_delay, src_bandwidth = extract_qos_info(src_cc) + dst_max_delay, dst_bandwidth = extract_qos_info(dst_cc) + return QoSInfo( + src_qos_profile_latency=src_max_delay, + src_input_bw=dst_bandwidth, + src_output_bw=src_bandwidth, + dst_qos_profile_latency=dst_max_delay, + dst_input_bw=src_bandwidth, + dst_output_bw=dst_bandwidth, + ) + + def get_custom_config_rule( service_config: ServiceConfig, resource_key: str ) -> Optional[ConfigRule]: @@ -226,7 +275,9 @@ class L3NM_IETFL3VPN_ServiceHandler(_ServiceHandler): running_candidate_diff = get_running_candidate_ietf_slice_data_diff( service_config ) - service_id = candidate_resource_value_dict["network-slice-services"]["slice-service"][0]["id"] + service_id = candidate_resource_value_dict["network-slice-services"][ + "slice-service" + ][0]["id"] if not running_candidate_diff: operation_type = "create" elif "values_changed" in running_candidate_diff: @@ -243,6 +294,9 @@ class L3NM_IETFL3VPN_ServiceHandler(_ServiceHandler): connecitivity_construct = connecitivity_constructs[0] src_sdp_idx = connecitivity_construct["p2p-sender-sdp"] dst_sdp_idx = connecitivity_construct["p2p-receiver-sdp"] + qos_info = extract_qos_info_from_connection_group( + src_sdp_idx, dst_sdp_idx, connecitivity_constructs + ) src_sdp = next(sdp for sdp in sdps if sdp["id"] == src_sdp_idx) dst_sdp = next(sdp for sdp in sdps if sdp["id"] == dst_sdp_idx) src_match_criterion = src_sdp["service-match-criteria"]["match-criterion"][ @@ -285,6 +339,9 @@ class L3NM_IETFL3VPN_ServiceHandler(_ServiceHandler): "src_pe_address": src_pe_address, "src_ce_pe_network_prefix": src_ce_address_prefix, "src_mtu": MTU, + "src_qos_profile_latency": qos_info["src_qos_profile_latency"], + "src_input_bw": qos_info["src_input_bw"], + "src_output_bw": qos_info["src_output_bw"], "dst_device_name": dst_device_name, "dst_endpoint_name": dst_endpoint_obj.name, "dst_site_location": dst_endpoint_settings["site_location"], @@ -293,8 +350,13 @@ class L3NM_IETFL3VPN_ServiceHandler(_ServiceHandler): "dst_pe_address": dst_pe_address, "dst_ce_pe_network_prefix": dst_ce_address_prefix, "dst_mtu": MTU, + "dst_qos_profile_latency": qos_info["dst_qos_profile_latency"], + "dst_input_bw": qos_info["dst_input_bw"], + "dst_output_bw": qos_info["dst_output_bw"], } - json_config_rules = setup_config_rules(service_id, resource_value_dict, operation_type) + json_config_rules = setup_config_rules( + service_id, resource_value_dict, operation_type + ) del controller.device_config.config_rules[:] for jcr in json_config_rules: controller.device_config.config_rules.append(ConfigRule(**jcr)) @@ -316,17 +378,16 @@ class L3NM_IETFL3VPN_ServiceHandler(_ServiceHandler): chk_type("endpoints", endpoints, list) if len(endpoints) < 2: return [] - service_config = self.__service.service_config - ietf_slice_candidate_cr = get_custom_config_rule( service_config, CANDIDATE_RESOURCE_KEY ) candidate_resource_value_dict = json.loads( ietf_slice_candidate_cr.custom.resource_value ) - service_id = candidate_resource_value_dict["network-slice-services"]["slice-service"][0]["id"] - + service_id = candidate_resource_value_dict["network-slice-services"][ + "slice-service" + ][0]["id"] results = [] try: src_device_uuid, _ = get_device_endpoint_uuids(endpoints[0]) @@ -346,12 +407,10 @@ class L3NM_IETFL3VPN_ServiceHandler(_ServiceHandler): ): raise Exception("Different Src-Dst devices not supported by now") controller = src_controller - - json_config_rule = json_config_rule_delete( - "/services/service[{:s}]".format(service_id), {"uuid": service_id} - ) + json_config_rules = teardown_config_rules(service_id) del controller.device_config.config_rules[:] - controller.device_config.config_rules.append(ConfigRule(**json_config_rule)) + for jcr in json_config_rules: + controller.device_config.config_rules.append(ConfigRule(**jcr)) self.__task_executor.configure_device(controller) results.append(True) except Exception as e: # pylint: disable=broad-except