Commit 136ecf97 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Merge branch 'pr_tna' into 'develop'

Resolve "[UBI] Cleaner logs in fabric TNA services"

See merge request !414
parents 9ab5f51b f12e7f59
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -22,12 +22,8 @@ SD-Fabric repo: https://github.com/stratum/fabric-tna
SD-Fabric docs: https://docs.sd-fabric.org/master/index.html
"""

import logging

from service.service.service_handlers.p4_fabric_tna_commons.p4_fabric_tna_commons import *

LOGGER = logging.getLogger(__name__)

# ACL service handler settings
ACL = "acl"
ACTION = "action"
+36 −41
Original line number Diff line number Diff line
@@ -84,8 +84,7 @@ class P4FabricACLServiceHandler(_ServiceHandler):
        chk_type('endpoints', endpoints, list)
        if len(endpoints) == 0: return []

        LOGGER.info("{} - Provision service configuration".format(
            self.__service_label))
        LOGGER.info(f"{self.__service_label} - Provision service configuration")

        visited = set()
        results = []
@@ -94,17 +93,17 @@ class P4FabricACLServiceHandler(_ServiceHandler):
            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
            device_name = device.name

            LOGGER.info("Device {}".format(device_name))
            LOGGER.info("\t | Service endpoint UUID: {}".format(endpoint_uuid))
            LOGGER.info(f"Device {device_name}")
            LOGGER.info(f"\t | Service endpoint UUID: {endpoint_uuid}")

            port_id = find_port_id_in_endpoint_list(device.device_endpoints, endpoint_uuid)
            LOGGER.info("\t | Service port ID: {}".format(port_id))
            LOGGER.info(f"\t | Service port ID: {port_id}")

            try:
                # Check if this port is part of the ACL configuration
                _ = self._get_switch_port_in_port_map(device_name, port_id)
            except Exception:
                LOGGER.warning("Switch {} endpoint {} is not part of the ACL configuration".format(device_name, port_id))
                LOGGER.warning(f"Switch {device_name} endpoint {port_id} is not part of the ACL configuration")
                results.append(False)
                continue

@@ -129,15 +128,14 @@ class P4FabricACLServiceHandler(_ServiceHandler):
                    json_config_rules=rules
                )
            except Exception as ex:
                LOGGER.error("Failed to insert ACL rules on device {} due to {}".format(device.name, ex))
                LOGGER.error(f"Failed to insert ACL rules on device {device.name} due to {ex}")
                results.append(ex)
            finally:
                rules.clear()

            # Ensure correct status
            if (failed_rules == 0) and (applied_rules == actual_rules):
                LOGGER.info("Installed {}/{} ACL rules on device {} and port {}".format(
                    applied_rules, actual_rules, device_name, port_id))
                LOGGER.info(f"Installed {applied_rules}/{actual_rules} ACL rules on device {device_name} and port {port_id}")
                results.append(True)

            # You should no longer visit this device port again
@@ -169,8 +167,7 @@ class P4FabricACLServiceHandler(_ServiceHandler):
        chk_type('endpoints', endpoints, list)
        if len(endpoints) == 0: return []

        LOGGER.info("{} - Deprovision service configuration".format(
            self.__service_label))
        LOGGER.info(f"{self.__service_label} - Deprovision service configuration")

        visited = set()
        results = []
@@ -179,17 +176,17 @@ class P4FabricACLServiceHandler(_ServiceHandler):
            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
            device_name = device.name

            LOGGER.info("Device {}".format(device_name))
            LOGGER.info("\t | Service endpoint UUID: {}".format(endpoint_uuid))
            LOGGER.info(f"Device {device_name}")
            LOGGER.info(f"\t | Service endpoint UUID: {endpoint_uuid}")

            port_id = find_port_id_in_endpoint_list(device.device_endpoints, endpoint_uuid)
            LOGGER.info("\t | Service port ID: {}".format(port_id))
            LOGGER.info(f"\t | Service port ID: {port_id}")

            try:
                # Check if this port is part of the ACL configuration
                _ = self._get_switch_port_in_port_map(device_name, port_id)
            except Exception as ex:
                LOGGER.warning("Switch {} endpoint {} is not part of the ACL configuration".format(device_name, port_id))
                LOGGER.warning(f"Switch {device_name} endpoint {port_id} is not part of the ACL configuration")
                results.append(False)
                continue

@@ -214,15 +211,14 @@ class P4FabricACLServiceHandler(_ServiceHandler):
                    json_config_rules=rules
                )
            except Exception as ex:
                LOGGER.error("Failed to delete ACL rules from device {} due to {}".format(device.name, ex))
                LOGGER.error(f"Failed to delete ACL rules from device {device.name} due to {ex}")
                results.append(ex)
            finally:
                rules.clear()

            # Ensure correct status
            if (failed_rules == 0) and (applied_rules == actual_rules):
                LOGGER.info("Deleted {}/{} ACL rules from device {} and port {}".format(
                    applied_rules, actual_rules, device_name, port_id))
                LOGGER.info(f"Deleted {applied_rules}/{actual_rules} ACL rules from device {device_name} and port {port_id}")
                results.append(True)

            # You should no longer visit this device port again
@@ -333,37 +329,36 @@ class P4FabricACLServiceHandler(_ServiceHandler):

        try:
            self.__settings = self.__settings_handler.get('/settings')
            LOGGER.info("{} with settings: {}".format(self.__service_label, self.__settings))
            LOGGER.info(f"{self.__service_label} with settings: {self.__settings}")
        except Exception as ex:
            LOGGER.error("Failed to retrieve service settings: {}".format(ex))
            LOGGER.error(f"Failed to retrieve service settings: {ex}")
            raise Exception(ex)

    def _parse_settings(self):
        try:
            switch_info = self.__settings.value[SWITCH_INFO]
        except Exception as ex:
            LOGGER.error("Failed to parse service settings: {}".format(ex))
            LOGGER.error(f"Failed to parse service settings: {ex}")
            raise Exception(ex)
        assert isinstance(switch_info, list), "Switch info object must be a list"

        for switch in switch_info:
            for switch_name, sw_info in switch.items():
                assert switch_name, "Invalid P4 switch name"
                assert isinstance(sw_info, dict), "Switch {} info must be a map with arch, dpid, and fwd_list items)"
                assert isinstance(sw_info, dict), f"Switch {switch_name} info must be a map with arch, dpid, and fwd_list items)"
                assert sw_info[ARCH] in SUPPORTED_TARGET_ARCH_LIST, \
                    "Switch {} - Supported P4 architectures are: {}".format(switch_name, ','.join(SUPPORTED_TARGET_ARCH_LIST))
                    f"Switch {switch_name} - Supported P4 architectures are: {','.join(SUPPORTED_TARGET_ARCH_LIST)}"
                switch_dpid = sw_info[DPID]
                assert switch_dpid > 0, "Switch {} - P4 switch dataplane ID must be a positive integer".format(switch_name, sw_info[DPID])
                assert switch_dpid > 0, f"Switch {switch_name} - P4 switch dataplane ID {sw_info[DPID]} must be a positive integer"

                # Access Control list
                acl = sw_info[ACL]
                assert isinstance(acl, list),\
                    "Switch {} access control list must be a list with port_id, [ipv4_dst/src, trn_post_dst/src], and action items)".\
                        format(switch_name)
                    f"Switch {switch_name} access control list must be a list with port_id, [ipv4_dst/src, trn_post_dst/src], and action items)"
                for acl_entry in acl:
                    LOGGER.info("ACL entry: {}".format(acl_entry))
                    LOGGER.info(f"ACL entry: {acl_entry}")
                    port_id = acl_entry[PORT_ID]
                    assert port_id >= 0, "Switch {} - Invalid P4 switch port ID".format(switch_name)
                    assert port_id >= 0, f"Switch {switch_name} - Invalid P4 switch port ID"

                    # Prepare the port map
                    if switch_name not in self.__port_map:
@@ -380,35 +375,35 @@ class P4FabricACLServiceHandler(_ServiceHandler):
                    ipv4_src = ""
                    if IPV4_SRC in acl_entry:
                        ipv4_src = acl_entry[IPV4_SRC]
                        assert chk_address_ipv4(ipv4_src), "Invalid source IPv4 address {}".format(ipv4_dst)
                        assert chk_address_ipv4(ipv4_src), f"Invalid source IPv4 address {ipv4_src}"
                        map_entry[IPV4_SRC] = ipv4_src

                    ipv4_dst = ""
                    if IPV4_DST in acl_entry:
                        ipv4_dst = acl_entry[IPV4_DST]
                        assert chk_address_ipv4(ipv4_dst), "Invalid destination IPv4 address {}".format(ipv4_dst)
                        assert chk_address_ipv4(ipv4_dst), f"Invalid destination IPv4 address {ipv4_dst}"
                        map_entry[IPV4_DST] = ipv4_dst

                    ipv4_prefix_len = -1
                    if ipv4_src or ipv4_dst:
                        ipv4_prefix_len = acl_entry[IPV4_PREFIX_LEN]
                        assert chk_prefix_len_ipv4(ipv4_prefix_len), "Invalid IPv4 address prefix length {}".format(ipv4_prefix_len)
                        assert chk_prefix_len_ipv4(ipv4_prefix_len), f"Invalid IPv4 address prefix length {ipv4_prefix_len}"
                        map_entry[IPV4_PREFIX_LEN] = ipv4_prefix_len

                    trn_port_src = -1
                    if TRN_PORT_SRC in acl_entry:
                        trn_port_src = acl_entry[TRN_PORT_SRC]
                        assert chk_transport_port(trn_port_src), "Invalid source transport port {}".format(trn_port_src)
                        assert chk_transport_port(trn_port_src), f"Invalid source transport port {trn_port_src}"
                        map_entry[TRN_PORT_SRC] = trn_port_src

                    trn_port_dst = -1
                    if TRN_PORT_DST in acl_entry:
                        trn_port_dst = acl_entry[TRN_PORT_DST]
                        assert chk_transport_port(trn_port_dst), "Invalid destination transport port {}".format(trn_port_dst)
                        assert chk_transport_port(trn_port_dst), f"Invalid destination transport port {trn_port_dst}"
                        map_entry[TRN_PORT_DST] = trn_port_dst

                    action = acl_entry[ACTION]
                    assert is_valid_acl_action(action), "Valid actions are: {}".format(','.join(ACTION_LIST))
                    assert is_valid_acl_action(action), f"Valid actions are: {','.join(ACTION_LIST)}"

                    # Retrieve entry from the port map
                    switch_port_entry = self._get_switch_port_in_port_map(switch_name, port_id)
@@ -419,22 +414,22 @@ class P4FabricACLServiceHandler(_ServiceHandler):
                self.__switch_info[switch_name] = sw_info

    def _print_settings(self):
        LOGGER.info("--------------- {} settings ---------------".format(self.__service.name))
        LOGGER.info(f"--------------- {self.__service.name} settings ---------------")
        LOGGER.info("--- Topology info")
        for switch_name, switch_info in self.__switch_info.items():
            LOGGER.info("\t Device {}".format(switch_name))
            LOGGER.info("\t\t| Target P4 architecture: {}".format(switch_info[ARCH]))
            LOGGER.info("\t\t|          Data plane ID: {}".format(switch_info[DPID]))
            LOGGER.info("\t\t|               Port map: {}".format(self.__port_map[switch_name]))
            LOGGER.info(f"\t Device {switch_name}")
            LOGGER.info(f"\t\t| Target P4 architecture: {switch_info[ARCH]}")
            LOGGER.info(f"\t\t|          Data plane ID: {switch_info[DPID]}")
            LOGGER.info(f"\t\t|               Port map: {self.__port_map[switch_name]}")
        LOGGER.info("-------------------------------------------------------")

    def _get_switch_port_in_port_map(self, switch_name : str, port_id : int) -> Dict:
        assert switch_name, "A valid switch name must be used as a key to the port map"
        assert port_id > 0, "A valid switch port ID must be used as a key to a switch's port map"
        switch_entry = self.__port_map[switch_name]
        assert switch_entry, "Switch {} does not exist in the port map".format(switch_name)
        assert switch_entry, f"Switch {switch_name} does not exist in the port map"
        port_key = PORT_PREFIX + str(port_id)
        assert switch_entry[port_key], "Port with ID {} does not exist in the switch map".format(port_id)
        assert switch_entry[port_key], f"Port with ID {port_id} does not exist in the switch map"

        return switch_entry[port_key]

+10 −11
Original line number Diff line number Diff line
@@ -366,7 +366,7 @@ def rules_set_up_port(
            action=action
        )
    )
    LOGGER.debug("Port configured:{}".format(port))
    LOGGER.debug(f"Port configured:{port}")

    return rules_list

@@ -678,8 +678,7 @@ def rules_set_up_report_mirror_flow(
    rules_list = []

    for i, mirror_id in enumerate(report_mirror_id_list):
        LOGGER.debug("Mirror ID:{} - Recirculation port: {}".format(
            mirror_id, recirculation_port_list[i]))
        LOGGER.debug(f"Mirror ID:{mirror_id} - Recirculation port: {recirculation_port_list[i]}")
        rules_list.extend(
            rules_set_up_clone_session(
                session_id=mirror_id,
@@ -836,7 +835,7 @@ def apply_rules(

    # Provision rules one-by-one
    for i, json_config_rule in enumerate(json_config_rules):
        LOGGER.debug("Applying rule #{}: {}".format(i, json_config_rule))
        LOGGER.debug(f"Applying rule #{i}: {json_config_rule}")
        try:
            # Cleanup the rules of this particular object
            del device_obj.device_config.config_rules[:]
@@ -853,11 +852,11 @@ def apply_rules(

            applied_rules += 1
        except Exception as ex:
            LOGGER.error("Error while applying rule #{}: {}".format(i, ex))
            LOGGER.error(f"Error while applying rule #{i}: {ex}")
            failed_rules += 1
            raise Exception(ex)

    LOGGER.debug("Batch rules: {}/{} applied".format(applied_rules, total_rules))
    LOGGER.debug(f"Batch rules: {applied_rules}/{total_rules} applied")

    return applied_rules, failed_rules

@@ -876,7 +875,7 @@ def cache_rule(
    else:
        assert True, "Invalid rule configuration action"

    assert rule_no > 0, "Invalid rule identifier to configure table {}".format(table_name)
    assert rule_no > 0, f"Invalid rule identifier to configure table {table_name}"

    return rule_no

@@ -889,8 +888,8 @@ def add_rule_to_map(table_name : str) -> int:

    # Get a new valid rule index
    new_index = find_minimum_available_rule_index(RULE_ENTRY_MAP[table_name])
    LOGGER.debug("Minimum available rule index for table {} is: {}".format(table_name, new_index))
    assert new_index > 0, "Invalid rule index for table {}".format(table_name)
    LOGGER.debug(f"Minimum available rule index for table {table_name} is: {new_index}")
    assert new_index > 0, f"Invalid rule index for table {table_name}"

    # New entry
    new_rule_entry = table_name+"["+str(new_index)+"]"
@@ -903,7 +902,7 @@ def add_rule_to_map(table_name : str) -> int:

def delete_rule_from_map(table_name : str) -> int:
    if table_name not in RULE_ENTRY_MAP:
        LOGGER.error("Table {} has no entries".format(table_name))
        LOGGER.error(f"Table {table_name} has no entries")
        return -1

    # Current number of rules
@@ -958,4 +957,4 @@ def find_minimum_available_rule_index(rule_entry_list : List) -> int:

def print_rule_map() -> None:
    for k in RULE_ENTRY_MAP.keys():
        LOGGER.info("Table {} entries: {}".format(k, RULE_ENTRY_MAP[k]))
        LOGGER.info(f"Table {k} entries: {RULE_ENTRY_MAP[k]}")
+0 −5
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ SD-Fabric repo: https://github.com/stratum/fabric-tna
SD-Fabric docs: https://docs.sd-fabric.org/master/index.html
"""

import logging
from typing import List, Tuple
from common.proto.context_pb2 import ConfigActionEnum
from common.tools.object_factory.ConfigRule import json_config_rule
@@ -30,8 +29,6 @@ from common.type_checkers.Checkers import chk_address_ipv4, chk_transport_port

from service.service.service_handlers.p4_fabric_tna_commons.p4_fabric_tna_commons import *

LOGGER = logging.getLogger(__name__)

# INT service handler settings
INT_COLLECTOR_INFO = "int_collector_info"
INT_REPORT_MIRROR_ID_LIST = "int_report_mirror_id_list"
@@ -135,8 +132,6 @@ def rules_set_up_int_recirculation_ports(
            )
        )

    LOGGER.debug("INT recirculation ports configured:{}".format(recirculation_port_list))

    return rules_list

def rules_set_up_int_report_flow(
+62 −66

File changed.

Preview size limit exceeded, changes collapsed.

Loading