Loading proto/context.proto +14 −10 Original line number Diff line number Diff line Loading @@ -199,7 +199,7 @@ message Device { DeviceId controller_id = 9; // Identifier of node controlling the actual device } message Component { //Defined previously to this section - Tested OK message Component { // Defined previously in this section Uuid component_uuid = 1; string name = 2; string type = 3; Loading Loading @@ -271,6 +271,7 @@ enum LinkTypeEnum { LINKTYPE_FIBER = 2; LINKTYPE_RADIO = 3; LINKTYPE_VIRTUAL = 4; LINKTYPE_MANAGEMENT = 5; } message LinkAttributes { Loading Loading @@ -320,11 +321,14 @@ enum ServiceTypeEnum { SERVICETYPE_UNKNOWN = 0; SERVICETYPE_L3NM = 1; SERVICETYPE_L2NM = 2; SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3; SERVICETYPE_TE = 4; SERVICETYPE_E2E = 5; SERVICETYPE_OPTICAL_CONNECTIVITY = 6; SERVICETYPE_QKD = 7; SERVICETYPE_L1NM = 3; SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 4; SERVICETYPE_TE = 5; SERVICETYPE_E2E = 6; SERVICETYPE_OPTICAL_CONNECTIVITY = 7; SERVICETYPE_QKD = 8; SERVICETYPE_INT = 9; SERVICETYPE_ACL = 10; } enum ServiceStatusEnum { Loading src/common/type_checkers/Checkers.py +79 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,8 @@ # limitations under the License. import re import ipaddress from ctypes import c_uint16, sizeof from typing import Any, Container, Dict, List, Optional, Pattern, Set, Sized, Tuple, Union def chk_none(name : str, value : Any, reason=None) -> Any: Loading Loading @@ -107,3 +109,80 @@ def chk_options(name : str, value : Any, options : Container) -> Any: msg = '{}({}) is not one of options({}).' raise ValueError(msg.format(str(name), str(value), str(options))) return value # MAC address checker mac_pattern = re.compile(r"^([\da-fA-F]{2}:){5}([\da-fA-F]{2})$") def chk_address_mac(mac_addr : str): """ Check whether input string is a valid MAC address or not. :param mac_addr: string-based MAC address :return: boolean status """ return mac_pattern.match(mac_addr) is not None # IPv4/IPv6 address checkers IPV4_LOCALHOST = "localhost" def chk_address_ipv4(ip_addr : str): """ Check whether input string is a valid IPv4 address or not. :param ip_addr: string-based IPv4 address :return: boolean status """ if ip_addr == IPV4_LOCALHOST: return True try: addr = ipaddress.ip_address(ip_addr) return isinstance(addr, ipaddress.IPv4Address) except ValueError: return False def chk_address_ipv6(ip_addr : str): """ Check whether input string is a valid IPv6 address or not. :param ip_addr: string-based IPv6 address :return: boolean status """ try: addr = ipaddress.ip_address(ip_addr) return isinstance(addr, ipaddress.IPv6Address) except ValueError: return False # VLAN ID checker VLAN_ID_MIN = 1 VLAN_ID_MAX = 4094 def chk_vlan_id(vlan_id : int): return VLAN_ID_MIN <= vlan_id <= VLAN_ID_MAX # Transport port checker def limits(c_int_type): """ Discover limits of numerical type. :param c_int_type: numerical type :return: tuple of numerical type's limits """ signed = c_int_type(-1).value < c_int_type(0).value bit_size = sizeof(c_int_type) * 8 signed_limit = 2 ** (bit_size - 1) return (-signed_limit, signed_limit - 1) \ if signed else (0, 2 * signed_limit - 1) def chk_transport_port(trans_port : int): """ Check whether input is a valid transport port number or not. :param trans_port: transport port number :return: boolean status """ lim = limits(c_uint16) return lim[0] <= trans_port <= lim[1] src/context/service/database/models/enums/LinkType.py +7 −6 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ from ._GrpcToEnum import grpc_to_enum # IMPORTANT: Entries of enum class ORM_LinkTypeEnum should be named as in # the proto files removing the prefixes. For example, proto item # LinkTypeEnum.DEVICEDRIVER_COPPER should be included as COPPER. # LinkTypeEnum.COPPER should be included as COPPER. # If item name does not match, automatic mapping of proto enums # to database enums will fail. class ORM_LinkTypeEnum(enum.Enum): Loading @@ -27,6 +27,7 @@ class ORM_LinkTypeEnum(enum.Enum): FIBER = LinkTypeEnum.LINKTYPE_FIBER RADIO = LinkTypeEnum.LINKTYPE_RADIO VIRTUAL = LinkTypeEnum.LINKTYPE_VIRTUAL MANAGEMENT = LinkTypeEnum.LINKTYPE_MANAGEMENT grpc_to_enum__link_type_enum = functools.partial( grpc_to_enum, LinkTypeEnum, ORM_LinkTypeEnum Loading src/context/service/database/models/enums/ServiceType.py +3 −0 Original line number Diff line number Diff line Loading @@ -25,11 +25,14 @@ class ORM_ServiceTypeEnum(enum.Enum): UNKNOWN = ServiceTypeEnum.SERVICETYPE_UNKNOWN L3NM = ServiceTypeEnum.SERVICETYPE_L3NM L2NM = ServiceTypeEnum.SERVICETYPE_L2NM L1NM = ServiceTypeEnum.SERVICETYPE_L1NM TAPI_CONNECTIVITY_SERVICE = ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE TE = ServiceTypeEnum.SERVICETYPE_TE E2E = ServiceTypeEnum.SERVICETYPE_E2E OPTICAL_CONNECTIVITY = ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY QKD = ServiceTypeEnum.SERVICETYPE_QKD INT = ServiceTypeEnum.SERVICETYPE_INT ACL = ServiceTypeEnum.SERVICETYPE_ACL grpc_to_enum__service_type = functools.partial( grpc_to_enum, ServiceTypeEnum, ORM_ServiceTypeEnum) src/device/service/drivers/p4/p4_common.py +8 −76 Original line number Diff line number Diff line Loading @@ -23,16 +23,15 @@ as well as static variables used by various P4 driver components. """ import logging import ipaddress import macaddress import math import re import socket import ipaddress from typing import Any, Dict, List, Optional, Tuple from ctypes import c_uint16, sizeof import macaddress from common.type_checkers.Checkers import \ chk_attribute, chk_string, chk_type, chk_issubclass chk_attribute, chk_string, chk_type, chk_issubclass,\ chk_address_mac, chk_address_ipv4, chk_address_ipv6 try: from .p4_exception import UserBadValueError except ImportError: Loading Loading @@ -60,17 +59,6 @@ LOGGER = logging.getLogger(__name__) # MAC address encoding/decoding mac_pattern = re.compile(r"^([\da-fA-F]{2}:){5}([\da-fA-F]{2})$") def matches_mac(mac_addr_string): """ Check whether input string is a valid MAC address or not. :param mac_addr_string: string-based MAC address :return: boolean status """ return mac_pattern.match(mac_addr_string) is not None def encode_mac(mac_addr_string): Loading @@ -94,23 +82,6 @@ def decode_mac(encoded_mac_addr): # IP address encoding/decoding IPV4_LOCALHOST = "localhost" def matches_ipv4(ip_addr_string): """ Check whether input string is a valid IPv4 address or not. :param ip_addr_string: string-based IPv4 address :return: boolean status """ if ip_addr_string == IPV4_LOCALHOST: return True try: addr = ipaddress.ip_address(ip_addr_string) return isinstance(addr, ipaddress.IPv4Address) except ValueError: return False def encode_ipv4(ip_addr_string): Loading @@ -133,20 +104,6 @@ def decode_ipv4(encoded_ip_addr): return socket.inet_ntoa(encoded_ip_addr) def matches_ipv6(ip_addr_string): """ Check whether input string is a valid IPv6 address or not. :param ip_addr_string: string-based IPv6 address :return: boolean status """ try: addr = ipaddress.ip_address(ip_addr_string) return isinstance(addr, ipaddress.IPv6Address) except ValueError: return False def encode_ipv6(ip_addr_string): """ Convert string-based IPv6 address into bytes. Loading @@ -170,31 +127,6 @@ def decode_ipv6(encoded_ip_addr): # Numerical encoding/decoding def limits(c_int_type): """ Discover limits of numerical type. :param c_int_type: numerical type :return: tuple of numerical type's limits """ signed = c_int_type(-1).value < c_int_type(0).value bit_size = sizeof(c_int_type) * 8 signed_limit = 2 ** (bit_size - 1) return (-signed_limit, signed_limit - 1) \ if signed else (0, 2 * signed_limit - 1) def valid_port(port): """ Check whether input is a valid port number or not. :param port: port number :return: boolean status """ lim = limits(c_uint16) return lim[0] <= port <= lim[1] def bitwidth_to_bytes(bitwidth): """ Convert number of bits to number of bytes. Loading Loading @@ -245,11 +177,11 @@ def encode(variable, bitwidth): if isinstance(variable, int): encoded_bytes = encode_num(variable, bitwidth) elif isinstance(variable, str): if matches_mac(variable): if chk_address_mac(variable): encoded_bytes = encode_mac(variable) elif matches_ipv4(variable): elif chk_address_ipv4(variable): encoded_bytes = encode_ipv4(variable) elif matches_ipv6(variable): elif chk_address_ipv6(variable): encoded_bytes = encode_ipv6(variable) else: try: Loading Loading @@ -471,7 +403,7 @@ def parse_integer_list_from_json(resource, resource_list, resource_item): return integers_list def process_optional_string_field( #TODO: Consider adding this in common methdos as it is taken by the Emulated driver #TODO: Consider adding this in common methods as it is taken by the Emulated driver endpoint_data : Dict[str, Any], field_name : str, endpoint_resource_value : Dict[str, Any] ) -> None: field_value = chk_attribute(field_name, endpoint_data, 'endpoint_data', default=None) Loading Loading
proto/context.proto +14 −10 Original line number Diff line number Diff line Loading @@ -199,7 +199,7 @@ message Device { DeviceId controller_id = 9; // Identifier of node controlling the actual device } message Component { //Defined previously to this section - Tested OK message Component { // Defined previously in this section Uuid component_uuid = 1; string name = 2; string type = 3; Loading Loading @@ -271,6 +271,7 @@ enum LinkTypeEnum { LINKTYPE_FIBER = 2; LINKTYPE_RADIO = 3; LINKTYPE_VIRTUAL = 4; LINKTYPE_MANAGEMENT = 5; } message LinkAttributes { Loading Loading @@ -320,11 +321,14 @@ enum ServiceTypeEnum { SERVICETYPE_UNKNOWN = 0; SERVICETYPE_L3NM = 1; SERVICETYPE_L2NM = 2; SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3; SERVICETYPE_TE = 4; SERVICETYPE_E2E = 5; SERVICETYPE_OPTICAL_CONNECTIVITY = 6; SERVICETYPE_QKD = 7; SERVICETYPE_L1NM = 3; SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 4; SERVICETYPE_TE = 5; SERVICETYPE_E2E = 6; SERVICETYPE_OPTICAL_CONNECTIVITY = 7; SERVICETYPE_QKD = 8; SERVICETYPE_INT = 9; SERVICETYPE_ACL = 10; } enum ServiceStatusEnum { Loading
src/common/type_checkers/Checkers.py +79 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,8 @@ # limitations under the License. import re import ipaddress from ctypes import c_uint16, sizeof from typing import Any, Container, Dict, List, Optional, Pattern, Set, Sized, Tuple, Union def chk_none(name : str, value : Any, reason=None) -> Any: Loading Loading @@ -107,3 +109,80 @@ def chk_options(name : str, value : Any, options : Container) -> Any: msg = '{}({}) is not one of options({}).' raise ValueError(msg.format(str(name), str(value), str(options))) return value # MAC address checker mac_pattern = re.compile(r"^([\da-fA-F]{2}:){5}([\da-fA-F]{2})$") def chk_address_mac(mac_addr : str): """ Check whether input string is a valid MAC address or not. :param mac_addr: string-based MAC address :return: boolean status """ return mac_pattern.match(mac_addr) is not None # IPv4/IPv6 address checkers IPV4_LOCALHOST = "localhost" def chk_address_ipv4(ip_addr : str): """ Check whether input string is a valid IPv4 address or not. :param ip_addr: string-based IPv4 address :return: boolean status """ if ip_addr == IPV4_LOCALHOST: return True try: addr = ipaddress.ip_address(ip_addr) return isinstance(addr, ipaddress.IPv4Address) except ValueError: return False def chk_address_ipv6(ip_addr : str): """ Check whether input string is a valid IPv6 address or not. :param ip_addr: string-based IPv6 address :return: boolean status """ try: addr = ipaddress.ip_address(ip_addr) return isinstance(addr, ipaddress.IPv6Address) except ValueError: return False # VLAN ID checker VLAN_ID_MIN = 1 VLAN_ID_MAX = 4094 def chk_vlan_id(vlan_id : int): return VLAN_ID_MIN <= vlan_id <= VLAN_ID_MAX # Transport port checker def limits(c_int_type): """ Discover limits of numerical type. :param c_int_type: numerical type :return: tuple of numerical type's limits """ signed = c_int_type(-1).value < c_int_type(0).value bit_size = sizeof(c_int_type) * 8 signed_limit = 2 ** (bit_size - 1) return (-signed_limit, signed_limit - 1) \ if signed else (0, 2 * signed_limit - 1) def chk_transport_port(trans_port : int): """ Check whether input is a valid transport port number or not. :param trans_port: transport port number :return: boolean status """ lim = limits(c_uint16) return lim[0] <= trans_port <= lim[1]
src/context/service/database/models/enums/LinkType.py +7 −6 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ from ._GrpcToEnum import grpc_to_enum # IMPORTANT: Entries of enum class ORM_LinkTypeEnum should be named as in # the proto files removing the prefixes. For example, proto item # LinkTypeEnum.DEVICEDRIVER_COPPER should be included as COPPER. # LinkTypeEnum.COPPER should be included as COPPER. # If item name does not match, automatic mapping of proto enums # to database enums will fail. class ORM_LinkTypeEnum(enum.Enum): Loading @@ -27,6 +27,7 @@ class ORM_LinkTypeEnum(enum.Enum): FIBER = LinkTypeEnum.LINKTYPE_FIBER RADIO = LinkTypeEnum.LINKTYPE_RADIO VIRTUAL = LinkTypeEnum.LINKTYPE_VIRTUAL MANAGEMENT = LinkTypeEnum.LINKTYPE_MANAGEMENT grpc_to_enum__link_type_enum = functools.partial( grpc_to_enum, LinkTypeEnum, ORM_LinkTypeEnum Loading
src/context/service/database/models/enums/ServiceType.py +3 −0 Original line number Diff line number Diff line Loading @@ -25,11 +25,14 @@ class ORM_ServiceTypeEnum(enum.Enum): UNKNOWN = ServiceTypeEnum.SERVICETYPE_UNKNOWN L3NM = ServiceTypeEnum.SERVICETYPE_L3NM L2NM = ServiceTypeEnum.SERVICETYPE_L2NM L1NM = ServiceTypeEnum.SERVICETYPE_L1NM TAPI_CONNECTIVITY_SERVICE = ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE TE = ServiceTypeEnum.SERVICETYPE_TE E2E = ServiceTypeEnum.SERVICETYPE_E2E OPTICAL_CONNECTIVITY = ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY QKD = ServiceTypeEnum.SERVICETYPE_QKD INT = ServiceTypeEnum.SERVICETYPE_INT ACL = ServiceTypeEnum.SERVICETYPE_ACL grpc_to_enum__service_type = functools.partial( grpc_to_enum, ServiceTypeEnum, ORM_ServiceTypeEnum)
src/device/service/drivers/p4/p4_common.py +8 −76 Original line number Diff line number Diff line Loading @@ -23,16 +23,15 @@ as well as static variables used by various P4 driver components. """ import logging import ipaddress import macaddress import math import re import socket import ipaddress from typing import Any, Dict, List, Optional, Tuple from ctypes import c_uint16, sizeof import macaddress from common.type_checkers.Checkers import \ chk_attribute, chk_string, chk_type, chk_issubclass chk_attribute, chk_string, chk_type, chk_issubclass,\ chk_address_mac, chk_address_ipv4, chk_address_ipv6 try: from .p4_exception import UserBadValueError except ImportError: Loading Loading @@ -60,17 +59,6 @@ LOGGER = logging.getLogger(__name__) # MAC address encoding/decoding mac_pattern = re.compile(r"^([\da-fA-F]{2}:){5}([\da-fA-F]{2})$") def matches_mac(mac_addr_string): """ Check whether input string is a valid MAC address or not. :param mac_addr_string: string-based MAC address :return: boolean status """ return mac_pattern.match(mac_addr_string) is not None def encode_mac(mac_addr_string): Loading @@ -94,23 +82,6 @@ def decode_mac(encoded_mac_addr): # IP address encoding/decoding IPV4_LOCALHOST = "localhost" def matches_ipv4(ip_addr_string): """ Check whether input string is a valid IPv4 address or not. :param ip_addr_string: string-based IPv4 address :return: boolean status """ if ip_addr_string == IPV4_LOCALHOST: return True try: addr = ipaddress.ip_address(ip_addr_string) return isinstance(addr, ipaddress.IPv4Address) except ValueError: return False def encode_ipv4(ip_addr_string): Loading @@ -133,20 +104,6 @@ def decode_ipv4(encoded_ip_addr): return socket.inet_ntoa(encoded_ip_addr) def matches_ipv6(ip_addr_string): """ Check whether input string is a valid IPv6 address or not. :param ip_addr_string: string-based IPv6 address :return: boolean status """ try: addr = ipaddress.ip_address(ip_addr_string) return isinstance(addr, ipaddress.IPv6Address) except ValueError: return False def encode_ipv6(ip_addr_string): """ Convert string-based IPv6 address into bytes. Loading @@ -170,31 +127,6 @@ def decode_ipv6(encoded_ip_addr): # Numerical encoding/decoding def limits(c_int_type): """ Discover limits of numerical type. :param c_int_type: numerical type :return: tuple of numerical type's limits """ signed = c_int_type(-1).value < c_int_type(0).value bit_size = sizeof(c_int_type) * 8 signed_limit = 2 ** (bit_size - 1) return (-signed_limit, signed_limit - 1) \ if signed else (0, 2 * signed_limit - 1) def valid_port(port): """ Check whether input is a valid port number or not. :param port: port number :return: boolean status """ lim = limits(c_uint16) return lim[0] <= port <= lim[1] def bitwidth_to_bytes(bitwidth): """ Convert number of bits to number of bytes. Loading Loading @@ -245,11 +177,11 @@ def encode(variable, bitwidth): if isinstance(variable, int): encoded_bytes = encode_num(variable, bitwidth) elif isinstance(variable, str): if matches_mac(variable): if chk_address_mac(variable): encoded_bytes = encode_mac(variable) elif matches_ipv4(variable): elif chk_address_ipv4(variable): encoded_bytes = encode_ipv4(variable) elif matches_ipv6(variable): elif chk_address_ipv6(variable): encoded_bytes = encode_ipv6(variable) else: try: Loading Loading @@ -471,7 +403,7 @@ def parse_integer_list_from_json(resource, resource_list, resource_item): return integers_list def process_optional_string_field( #TODO: Consider adding this in common methdos as it is taken by the Emulated driver #TODO: Consider adding this in common methods as it is taken by the Emulated driver endpoint_data : Dict[str, Any], field_name : str, endpoint_resource_value : Dict[str, Any] ) -> None: field_value = chk_attribute(field_name, endpoint_data, 'endpoint_data', default=None) Loading