daemon: removing python tlv related code and tests related to it

This commit is contained in:
Blake Harnden 2022-03-08 14:18:47 -08:00
parent dc7bb37252
commit c8a589ef76
29 changed files with 29 additions and 5439 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,60 +0,0 @@
"""
Defines core server for handling TCP connections.
"""
import socketserver
from core.emulator.coreemu import CoreEmu
class CoreServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
"""
TCP server class, manages sessions and spawns request handlers for
incoming connections.
"""
daemon_threads = True
allow_reuse_address = True
def __init__(self, server_address, handler_class, config=None):
"""
Server class initialization takes configuration data and calls
the socketserver constructor.
:param tuple[str, int] server_address: server host and port to use
:param class handler_class: request handler
:param dict config: configuration setting
"""
self.coreemu = CoreEmu(config)
self.config = config
socketserver.TCPServer.__init__(self, server_address, handler_class)
class CoreUdpServer(socketserver.ThreadingMixIn, socketserver.UDPServer):
"""
UDP server class, manages sessions and spawns request handlers for
incoming connections.
"""
daemon_threads = True
allow_reuse_address = True
def __init__(self, server_address, handler_class, mainserver):
"""
Server class initialization takes configuration data and calls
the SocketServer constructor
:param server_address:
:param class handler_class: request handler
:param mainserver:
"""
self.mainserver = mainserver
socketserver.UDPServer.__init__(self, server_address, handler_class)
def start(self):
"""
Thread target to run concurrently with the TCP server.
:return: nothing
"""
self.serve_forever()

View file

@ -1,178 +0,0 @@
"""
Converts CORE data objects into legacy API messages.
"""
import logging
from collections import OrderedDict
from typing import Dict, List
from core.api.tlv import coreapi, structutils
from core.api.tlv.enumerations import ConfigTlvs, NodeTlvs
from core.config import ConfigGroup, ConfigurableOptions
from core.emulator.data import ConfigData, NodeData
logger = logging.getLogger(__name__)
def convert_node(node_data: NodeData):
"""
Convenience method for converting NodeData to a packed TLV message.
:param core.emulator.data.NodeData node_data: node data to convert
:return: packed node message
"""
node = node_data.node
services = None
if node.services is not None:
services = "|".join([x.name for x in node.services])
server = None
if node.server is not None:
server = node.server.name
tlv_data = structutils.pack_values(
coreapi.CoreNodeTlv,
[
(NodeTlvs.NUMBER, node.id),
(NodeTlvs.TYPE, node.apitype.value),
(NodeTlvs.NAME, node.name),
(NodeTlvs.MODEL, node.type),
(NodeTlvs.EMULATION_SERVER, server),
(NodeTlvs.X_POSITION, int(node.position.x)),
(NodeTlvs.Y_POSITION, int(node.position.y)),
(NodeTlvs.CANVAS, node.canvas),
(NodeTlvs.SERVICES, services),
(NodeTlvs.LATITUDE, str(node.position.lat)),
(NodeTlvs.LONGITUDE, str(node.position.lon)),
(NodeTlvs.ALTITUDE, str(node.position.alt)),
(NodeTlvs.ICON, node.icon),
],
)
return coreapi.CoreNodeMessage.pack(node_data.message_type.value, tlv_data)
def convert_config(config_data):
"""
Convenience method for converting ConfigData to a packed TLV message.
:param core.emulator.data.ConfigData config_data: config data to convert
:return: packed message
"""
session = None
if config_data.session is not None:
session = str(config_data.session)
tlv_data = structutils.pack_values(
coreapi.CoreConfigTlv,
[
(ConfigTlvs.NODE, config_data.node),
(ConfigTlvs.OBJECT, config_data.object),
(ConfigTlvs.TYPE, config_data.type),
(ConfigTlvs.DATA_TYPES, config_data.data_types),
(ConfigTlvs.VALUES, config_data.data_values),
(ConfigTlvs.CAPTIONS, config_data.captions),
(ConfigTlvs.BITMAP, config_data.bitmap),
(ConfigTlvs.POSSIBLE_VALUES, config_data.possible_values),
(ConfigTlvs.GROUPS, config_data.groups),
(ConfigTlvs.SESSION, session),
(ConfigTlvs.IFACE_ID, config_data.iface_id),
(ConfigTlvs.NETWORK_ID, config_data.network_id),
(ConfigTlvs.OPAQUE, config_data.opaque),
],
)
return coreapi.CoreConfMessage.pack(config_data.message_type, tlv_data)
class ConfigShim:
"""
Provides helper methods for converting newer configuration values into TLV
compatible formats.
"""
@classmethod
def str_to_dict(cls, key_values: str) -> Dict[str, str]:
"""
Converts a TLV key/value string into an ordered mapping.
:param key_values:
:return: ordered mapping of key/value pairs
"""
key_values = key_values.split("|")
values = OrderedDict()
for key_value in key_values:
key, value = key_value.split("=", 1)
values[key] = value
return values
@classmethod
def groups_to_str(cls, config_groups: List[ConfigGroup]) -> str:
"""
Converts configuration groups to a TLV formatted string.
:param config_groups: configuration groups to format
:return: TLV configuration group string
"""
group_strings = []
for config_group in config_groups:
group_string = (
f"{config_group.name}:{config_group.start}-{config_group.stop}"
)
group_strings.append(group_string)
return "|".join(group_strings)
@classmethod
def config_data(
cls,
flags: int,
node_id: int,
type_flags: int,
configurable_options: ConfigurableOptions,
config: Dict[str, str],
) -> ConfigData:
"""
Convert this class to a Config API message. Some TLVs are defined
by the class, but node number, conf type flags, and values must
be passed in.
:param flags: message flags
:param node_id: node id
:param type_flags: type flags
:param configurable_options: options to create config data for
:param config: configuration values for options
:return: configuration data object
"""
key_values = None
captions = None
data_types = []
possible_values = []
logger.debug("configurable: %s", configurable_options)
logger.debug("configuration options: %s", configurable_options.configurations)
logger.debug("configuration data: %s", config)
for configuration in configurable_options.configurations():
if not captions:
captions = configuration.label
else:
captions += f"|{configuration.label}"
data_types.append(configuration.type.value)
options = ",".join(configuration.options)
possible_values.append(options)
_id = configuration.id
config_value = config.get(_id, configuration.default)
key_value = f"{_id}={config_value}"
if not key_values:
key_values = key_value
else:
key_values += f"|{key_value}"
groups_str = cls.groups_to_str(configurable_options.config_groups())
return ConfigData(
message_type=flags,
node=node_id,
object=configurable_options.name,
type=type_flags,
data_types=tuple(data_types),
data_values=key_values,
captions=captions,
possible_values="|".join(possible_values),
bitmap=configurable_options.bitmap,
groups=groups_str,
)

View file

@ -1,212 +0,0 @@
"""
Enumerations specific to the CORE TLV API.
"""
from enum import Enum
CORE_API_PORT = 4038
class MessageTypes(Enum):
"""
CORE message types.
"""
NODE = 0x01
LINK = 0x02
EXECUTE = 0x03
REGISTER = 0x04
CONFIG = 0x05
FILE = 0x06
INTERFACE = 0x07
EVENT = 0x08
SESSION = 0x09
EXCEPTION = 0x0A
class NodeTlvs(Enum):
"""
Node type, length, value enumerations.
"""
NUMBER = 0x01
TYPE = 0x02
NAME = 0x03
IP_ADDRESS = 0x04
MAC_ADDRESS = 0x05
IP6_ADDRESS = 0x06
MODEL = 0x07
EMULATION_SERVER = 0x08
SESSION = 0x0A
X_POSITION = 0x20
Y_POSITION = 0x21
CANVAS = 0x22
EMULATION_ID = 0x23
NETWORK_ID = 0x24
SERVICES = 0x25
LATITUDE = 0x30
LONGITUDE = 0x31
ALTITUDE = 0x32
ICON = 0x42
OPAQUE = 0x50
class LinkTlvs(Enum):
"""
Link type, length, value enumerations.
"""
N1_NUMBER = 0x01
N2_NUMBER = 0x02
DELAY = 0x03
BANDWIDTH = 0x04
LOSS = 0x05
DUP = 0x06
JITTER = 0x07
MER = 0x08
BURST = 0x09
SESSION = 0x0A
MBURST = 0x10
TYPE = 0x20
GUI_ATTRIBUTES = 0x21
UNIDIRECTIONAL = 0x22
EMULATION_ID = 0x23
NETWORK_ID = 0x24
KEY = 0x25
IFACE1_NUMBER = 0x30
IFACE1_IP4 = 0x31
IFACE1_IP4_MASK = 0x32
IFACE1_MAC = 0x33
IFACE1_IP6 = 0x34
IFACE1_IP6_MASK = 0x35
IFACE2_NUMBER = 0x36
IFACE2_IP4 = 0x37
IFACE2_IP4_MASK = 0x38
IFACE2_MAC = 0x39
IFACE2_IP6 = 0x40
IFACE2_IP6_MASK = 0x41
IFACE1_NAME = 0x42
IFACE2_NAME = 0x43
OPAQUE = 0x50
class ExecuteTlvs(Enum):
"""
Execute type, length, value enumerations.
"""
NODE = 0x01
NUMBER = 0x02
TIME = 0x03
COMMAND = 0x04
RESULT = 0x05
STATUS = 0x06
SESSION = 0x0A
class ConfigTlvs(Enum):
"""
Configuration type, length, value enumerations.
"""
NODE = 0x01
OBJECT = 0x02
TYPE = 0x03
DATA_TYPES = 0x04
VALUES = 0x05
CAPTIONS = 0x06
BITMAP = 0x07
POSSIBLE_VALUES = 0x08
GROUPS = 0x09
SESSION = 0x0A
IFACE_ID = 0x0B
NETWORK_ID = 0x24
OPAQUE = 0x50
class ConfigFlags(Enum):
"""
Configuration flags.
"""
NONE = 0x00
REQUEST = 0x01
UPDATE = 0x02
RESET = 0x03
class FileTlvs(Enum):
"""
File type, length, value enumerations.
"""
NODE = 0x01
NAME = 0x02
MODE = 0x03
NUMBER = 0x04
TYPE = 0x05
SOURCE_NAME = 0x06
SESSION = 0x0A
DATA = 0x10
COMPRESSED_DATA = 0x11
class InterfaceTlvs(Enum):
"""
Interface type, length, value enumerations.
"""
NODE = 0x01
NUMBER = 0x02
NAME = 0x03
IP_ADDRESS = 0x04
MASK = 0x05
MAC_ADDRESS = 0x06
IP6_ADDRESS = 0x07
IP6_MASK = 0x08
TYPE = 0x09
SESSION = 0x0A
STATE = 0x0B
EMULATION_ID = 0x23
NETWORK_ID = 0x24
class EventTlvs(Enum):
"""
Event type, length, value enumerations.
"""
NODE = 0x01
TYPE = 0x02
NAME = 0x03
DATA = 0x04
TIME = 0x05
SESSION = 0x0A
class SessionTlvs(Enum):
"""
Session type, length, value enumerations.
"""
NUMBER = 0x01
NAME = 0x02
FILE = 0x03
NODE_COUNT = 0x04
DATE = 0x05
THUMB = 0x06
USER = 0x07
OPAQUE = 0x0A
class ExceptionTlvs(Enum):
"""
Exception type, length, value enumerations.
"""
NODE = 0x01
SESSION = 0x02
LEVEL = 0x03
SOURCE = 0x04
DATE = 0x05
TEXT = 0x06
OPAQUE = 0x0A

View file

@ -1,45 +0,0 @@
"""
Utilities for working with python struct data.
"""
import logging
logger = logging.getLogger(__name__)
def pack_values(clazz, packers):
"""
Pack values for a given legacy class.
:param class clazz: class that will provide a pack method
:param list packers: a list of tuples that are used to pack values and transform them
:return: packed data string of all values
"""
# iterate through tuples of values to pack
logger.debug("packing: %s", packers)
data = b""
for packer in packers:
# check if a transformer was provided for valid values
transformer = None
if len(packer) == 2:
tlv_type, value = packer
elif len(packer) == 3:
tlv_type, value, transformer = packer
else:
raise RuntimeError("packer had more than 3 arguments")
# only pack actual values and avoid packing empty strings
# protobuf defaults to empty strings and does no imply a value to set
if value is None or (isinstance(value, str) and not value):
continue
# transform values as needed
if transformer:
value = transformer(value)
# pack and add to existing data
logger.debug("packing: %s - %s type(%s)", tlv_type, value, type(value))
data += clazz.pack(tlv_type.value, value)
return data