From 49a4e1fb5655f83d2d13437927bff71148d30c57 Mon Sep 17 00:00:00 2001 From: Czar Echavez Date: Thu, 29 Feb 2024 15:20:54 +0000 Subject: [PATCH] #2257: added common node attributes page + ability to set node operating state via config + tests --- .../simulation/nodes/common/common.rst | 35 ++++++++ .../common/common_host_node_attributes.rst | 9 +- .../common/common_network_node_attributes.rst | 2 + .../nodes/common/common_node_attributes.rst | 42 ++++++++++ .../network/base_hardware.rst | 22 ++--- .../applications/data_manipulation_bot.rst | 2 +- .../system/applications/database_client.rst | 6 -- .../system/list_of_system_applications.rst | 2 +- .../system/list_of_system_services.rst | 2 +- .../simulation_components/system/software.rst | 2 +- src/primaite/game/game.py | 16 +++- src/primaite/simulator/core.py | 4 +- .../network/hardware/nodes/host/host_node.py | 25 +++--- .../hardware/nodes/network/firewall.py | 83 +++++++++++++++---- .../network/hardware/nodes/network/router.py | 4 +- .../configs/basic_switched_network.yaml | 11 +++ .../nodes/test_node_config.py | 20 ++++- ...software_installation_and_configuration.py | 10 ++- 18 files changed, 227 insertions(+), 70 deletions(-) create mode 100644 docs/source/configuration/simulation/nodes/common/common.rst diff --git a/docs/source/configuration/simulation/nodes/common/common.rst b/docs/source/configuration/simulation/nodes/common/common.rst new file mode 100644 index 00000000..d1c8f307 --- /dev/null +++ b/docs/source/configuration/simulation/nodes/common/common.rst @@ -0,0 +1,35 @@ +.. only:: comment + + © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK + +.. _Node Attributes: + +Common Attributes +################# + +Node Attributes +=============== + +Attributes that are shared by all nodes. + +.. include:: common_node_attributes.rst + +.. _Network Node Attributes: + +Network Node Attributes +======================= + +Attributes that are shared by nodes that inherit from :py:mod:`primaite.simulator.network.hardware.nodes.network.network_node.NetworkNode` + +.. include:: common_host_node_attributes.rst + +.. _Host Node Attributes: + +Host Node Attributes +==================== + +Attributes that are shared by nodes that inherit from :py:mod:`primaite.simulator.network.hardware.nodes.host.host_node.HostNode` + +.. include:: common_host_node_attributes.rst + +.. |NODE| replace:: node diff --git a/docs/source/configuration/simulation/nodes/common/common_host_node_attributes.rst b/docs/source/configuration/simulation/nodes/common/common_host_node_attributes.rst index b9f173c6..929d5714 100644 --- a/docs/source/configuration/simulation/nodes/common/common_host_node_attributes.rst +++ b/docs/source/configuration/simulation/nodes/common/common_host_node_attributes.rst @@ -2,6 +2,8 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _common_host_node_attributes: + ``ip_address`` -------------- @@ -19,13 +21,6 @@ The subnet mask for the |NODE| to use. The IP address that the |NODE| will use as the default gateway. Typically, this is the IP address of the closest router that the |NODE| is connected to. -``dns_server`` --------------- - -Optional. Default value is ``None`` - -The IP address of the node which holds an instance of the :ref:`DNSServer`. Some applications may use a domain name e.g. the :ref:`WebBrowser` - .. include:: ../software/applications.rst .. include:: ../software/services.rst diff --git a/docs/source/configuration/simulation/nodes/common/common_network_node_attributes.rst b/docs/source/configuration/simulation/nodes/common/common_network_node_attributes.rst index d0b3e65b..1161059f 100644 --- a/docs/source/configuration/simulation/nodes/common/common_network_node_attributes.rst +++ b/docs/source/configuration/simulation/nodes/common/common_network_node_attributes.rst @@ -2,6 +2,8 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _common_network_node_attributes: + ``routes`` ---------- diff --git a/docs/source/configuration/simulation/nodes/common/common_node_attributes.rst b/docs/source/configuration/simulation/nodes/common/common_node_attributes.rst index c1523518..34519adc 100644 --- a/docs/source/configuration/simulation/nodes/common/common_node_attributes.rst +++ b/docs/source/configuration/simulation/nodes/common/common_node_attributes.rst @@ -2,6 +2,8 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _common_node_attributes: + ``ref`` ------- @@ -11,3 +13,43 @@ Human readable name used as reference for the |NODE|. Not used in code. ------------ The hostname of the |NODE|. This will be used to reference the |NODE|. + +``operating_state`` +------------------- + +The initial operating state of the node. + +Optional. Default value is ``ON``. + +Options available are: + +- ``ON`` +- ``OFF`` +- ``BOOTING`` +- ``SHUTTING_DOWN`` + +Note that YAML may assume non quoted ``ON`` and ``OFF`` as ``True`` and ``False`` respectively. To prevent this, use ``"ON"`` or ``"OFF"`` + +See :py:mod:`primaite.simulator.network.hardware.node_operating_state.NodeOperatingState` + + +``dns_server`` +-------------- + +Optional. Default value is ``None``. + +The IP address of the node which holds an instance of the :ref:`DNSServer`. Some applications may use a domain name e.g. the :ref:`WebBrowser` + +``start_up_duration`` +--------------------- + +Optional. Default value is ``3``. + +The number of time steps required to occur in order for the node to cycle from ``OFF`` to ``BOOTING_UP`` and then finally ``ON``. + +``shut_down_duration`` +---------------------- + +Optional. Default value is ``3``. + +The number of time steps required to occur in order for the node to cycle from ``ON`` to ``SHUTTING_DOWN`` and then finally ``OFF``. diff --git a/docs/source/simulation_components/network/base_hardware.rst b/docs/source/simulation_components/network/base_hardware.rst index 3aa6b073..1b83f3f4 100644 --- a/docs/source/simulation_components/network/base_hardware.rst +++ b/docs/source/simulation_components/network/base_hardware.rst @@ -12,34 +12,22 @@ complex, specialized hardware components inherit from and build upon. The key elements defined in ``base.py`` are: -NetworkInterface -================ +``NetworkInterface`` +==================== - Abstract base class for network interfaces like NICs. Defines common attributes like MAC address, speed, MTU. - Requires subclasses to implement ``enable()``, ``disable()``, ``send_frame()`` and ``receive_frame()``. - Provides basic state description and request handling capabilities. -Node -==== +``Node`` +======== The Node class stands as a central component in ``base.py``, acting as the superclass for all network nodes within a PrimAITE simulation. - - Node Attributes --------------- - -- **hostname**: The network hostname of the node. -- **operating_state**: Indicates the current hardware state of the node. -- **network_interfaces**: Maps interface names to NetworkInterface objects on the node. -- **network_interface**: Maps port IDs to ``NetworkInterface`` objects on the node. -- **dns_server**: Specifies DNS servers for domain name resolution. -- **start_up_duration**: The time it takes for the node to become fully operational after being powered on. -- **shut_down_duration**: The time required for the node to properly shut down. -- **sys_log**: A system log for recording events related to the node. -- **session_manager**: Manages user sessions within the node. -- **software_manager**: Controls the installation and management of software and services on the node. +See :ref:`Node Attributes` .. _Node Start up and Shut down: diff --git a/docs/source/simulation_components/system/applications/data_manipulation_bot.rst b/docs/source/simulation_components/system/applications/data_manipulation_bot.rst index d67e82d4..304621dd 100644 --- a/docs/source/simulation_components/system/applications/data_manipulation_bot.rst +++ b/docs/source/simulation_components/system/applications/data_manipulation_bot.rst @@ -79,7 +79,7 @@ Python data_manipulation_bot.configure(server_ip_address=IPv4Address("192.168.1.14"), payload="DELETE") data_manipulation_bot.run() -This would connect to the database service at 192.168.1.14, authenticate, and execute the SQL statement to drop the 'users' table. +This would connect to the database service at 192.168.1.14, authenticate, and execute the SQL statement to delete database contents. Example with ``DataManipulationAgent`` """""""""""""""""""""""""""""""""""""" diff --git a/docs/source/simulation_components/system/applications/database_client.rst b/docs/source/simulation_components/system/applications/database_client.rst index 61d955f2..ddf6db11 100644 --- a/docs/source/simulation_components/system/applications/database_client.rst +++ b/docs/source/simulation_components/system/applications/database_client.rst @@ -24,12 +24,6 @@ Usage - Retrieve results in a dictionary. - Disconnect when finished. -To create database backups: - -- Configure the backup server on the :ref:`DatabaseService` by providing the Backup server ``IPv4Address`` with ``configure_backup`` -- Create a backup using ``backup_database``. This fails if the backup server is not configured. -- Restore a backup using ``restore_backup``. By default, this uses the database created via ``backup_database``. - Implementation ============== diff --git a/docs/source/simulation_components/system/list_of_system_applications.rst b/docs/source/simulation_components/system/list_of_system_applications.rst index fae0f5d4..193b3dc6 100644 --- a/docs/source/simulation_components/system/list_of_system_applications.rst +++ b/docs/source/simulation_components/system/list_of_system_applications.rst @@ -13,4 +13,4 @@ The list of applications that are considered system software are: - ``WebBrowser`` -More info :py:mod:`primaite.simulator.network.hardware.nodes.host.host_node.SYSTEM_SOFTWARE` +More info :py:mod:`primaite.simulator.network.hardware.nodes.host.host_node.HostNode.SYSTEM_SOFTWARE` diff --git a/docs/source/simulation_components/system/list_of_system_services.rst b/docs/source/simulation_components/system/list_of_system_services.rst index 4ff6f245..5acfc12e 100644 --- a/docs/source/simulation_components/system/list_of_system_services.rst +++ b/docs/source/simulation_components/system/list_of_system_services.rst @@ -15,4 +15,4 @@ The list of services that are considered system software are: - ``FTPClient`` - ``NTPClient`` -More info :py:mod:`primaite.simulator.network.hardware.nodes.host.host_node.SYSTEM_SOFTWARE` +More info :py:mod:`primaite.simulator.network.hardware.nodes.host.host_node.HostNode.SYSTEM_SOFTWARE` diff --git a/docs/source/simulation_components/system/software.rst b/docs/source/simulation_components/system/software.rst index 459064f0..2ba8e841 100644 --- a/docs/source/simulation_components/system/software.rst +++ b/docs/source/simulation_components/system/software.rst @@ -10,7 +10,7 @@ Software Base Software ------------- -All software which inherits ``IOSoftware`` installed on a node will not work unless the node has been turned on. +Software which inherits ``IOSoftware`` installed on a node will not work unless the node has been turned on. See :ref:`Node Start up and Shut down` diff --git a/src/primaite/game/game.py b/src/primaite/game/game.py index 8d272418..42d998c7 100644 --- a/src/primaite/game/game.py +++ b/src/primaite/game/game.py @@ -234,7 +234,9 @@ class PrimaiteGame: subnet_mask=IPv4Address(node_cfg.get("subnet_mask", "255.255.255.0")), default_gateway=node_cfg["default_gateway"], dns_server=node_cfg.get("dns_server", None), - operating_state=NodeOperatingState.ON, + operating_state=NodeOperatingState.ON + if not (p := node_cfg.get("operating_state")) + else NodeOperatingState[p.upper()], ) elif n_type == "server": new_node = Server( @@ -243,13 +245,17 @@ class PrimaiteGame: subnet_mask=IPv4Address(node_cfg.get("subnet_mask", "255.255.255.0")), default_gateway=node_cfg["default_gateway"], dns_server=node_cfg.get("dns_server", None), - operating_state=NodeOperatingState.ON, + operating_state=NodeOperatingState.ON + if not (p := node_cfg.get("operating_state")) + else NodeOperatingState[p.upper()], ) elif n_type == "switch": new_node = Switch( hostname=node_cfg["hostname"], num_ports=int(node_cfg.get("num_ports", "8")), - operating_state=NodeOperatingState.ON, + operating_state=NodeOperatingState.ON + if not (p := node_cfg.get("operating_state")) + else NodeOperatingState[p.upper()], ) elif n_type == "router": new_node = Router.from_config(node_cfg) @@ -359,7 +365,9 @@ class PrimaiteGame: new_node.shut_down_duration = 0 net.add_node(new_node) - new_node.power_on() + # run through the power on step if the node is to be turned on at the start + if new_node.operating_state == NodeOperatingState.ON: + new_node.power_on() game.ref_map_nodes[node_ref] = new_node.uuid # set start up and shut down duration diff --git a/src/primaite/simulator/core.py b/src/primaite/simulator/core.py index 99e9be7f..6ab7c6e3 100644 --- a/src/primaite/simulator/core.py +++ b/src/primaite/simulator/core.py @@ -1,7 +1,7 @@ # flake8: noqa """Core of the PrimAITE Simulator.""" -from abc import ABC, abstractmethod -from typing import Callable, ClassVar, Dict, List, Optional, Union +from abc import abstractmethod +from typing import Callable, Dict, List, Optional, Union from uuid import uuid4 from pydantic import BaseModel, ConfigDict, Field diff --git a/src/primaite/simulator/network/hardware/nodes/host/host_node.py b/src/primaite/simulator/network/hardware/nodes/host/host_node.py index cb3c1bd7..703c2538 100644 --- a/src/primaite/simulator/network/hardware/nodes/host/host_node.py +++ b/src/primaite/simulator/network/hardware/nodes/host/host_node.py @@ -1,7 +1,7 @@ from __future__ import annotations from ipaddress import IPv4Address -from typing import Any, Dict, Optional +from typing import Any, ClassVar, Dict, Optional from primaite import getLogger from primaite.simulator.network.hardware.base import IPWiredNetworkInterface, Link, Node @@ -253,17 +253,6 @@ class NIC(IPWiredNetworkInterface): return f"Port {self.port_num}: {self.mac_address}/{self.ip_address}" -SYSTEM_SOFTWARE = { - "HostARP": HostARP, - "ICMP": ICMP, - "DNSClient": DNSClient, - "FTPClient": FTPClient, - "NTPClient": NTPClient, - "WebBrowser": WebBrowser, -} -"""List of system software that is automatically installed on nodes.""" - - class HostNode(Node): """ Represents a host node in the network. @@ -308,6 +297,16 @@ class HostNode(Node): * Web Browser: Provides web browsing capabilities. """ + SYSTEM_SOFTWARE: ClassVar[Dict] = { + "HostARP": HostARP, + "ICMP": ICMP, + "DNSClient": DNSClient, + "FTPClient": FTPClient, + "NTPClient": NTPClient, + "WebBrowser": WebBrowser, + } + """List of system software that is automatically installed on nodes.""" + network_interfaces: Dict[str, NIC] = {} "The Network Interfaces on the node." network_interface: Dict[int, NIC] = {} @@ -324,7 +323,7 @@ class HostNode(Node): This method equips the host with essential network services and applications, preparing it for various network-related tasks and operations. """ - for _, software_class in SYSTEM_SOFTWARE.items(): + for _, software_class in self.SYSTEM_SOFTWARE.items(): self.software_manager.install(software_class) super()._install_system_software() diff --git a/src/primaite/simulator/network/hardware/nodes/network/firewall.py b/src/primaite/simulator/network/hardware/nodes/network/firewall.py index b4d5cdba..26c50ff0 100644 --- a/src/primaite/simulator/network/hardware/nodes/network/firewall.py +++ b/src/primaite/simulator/network/hardware/nodes/network/firewall.py @@ -12,6 +12,8 @@ from primaite.simulator.network.hardware.nodes.network.router import ( RouterInterface, ) from primaite.simulator.network.transmission.data_link_layer import Frame +from primaite.simulator.network.transmission.network_layer import IPProtocol +from primaite.simulator.network.transmission.transport_layer import Port from primaite.simulator.system.core.sys_log import SysLog from primaite.utils.validators import IPV4Address @@ -479,7 +481,12 @@ class Firewall(Router): @classmethod def from_config(cls, cfg: dict) -> "Firewall": """Create a firewall based on a config dict.""" - firewall = Firewall(hostname=cfg["hostname"], operating_state=NodeOperatingState.ON) + firewall = Firewall( + hostname=cfg["hostname"], + operating_state=NodeOperatingState.ON + if not (p := cfg.get("operating_state")) + else NodeOperatingState[p.upper()], + ) if "ports" in cfg: internal_port = cfg["ports"]["internal_port"] external_port = cfg["ports"]["external_port"] @@ -505,34 +512,82 @@ class Firewall(Router): if "acl" in cfg: # acl rules for internal_inbound_acl if cfg["acl"]["internal_inbound_acl"]: - firewall.internal_inbound_acl.max_acl_rules - firewall.internal_inbound_acl._default_config = cfg["acl"]["internal_inbound_acl"] - firewall.internal_inbound_acl._reset_rules_to_default() + for r_num, r_cfg in cfg["acl"]["internal_inbound_acl"].items(): + firewall.internal_inbound_acl.add_rule( + action=ACLAction[r_cfg["action"]], + src_port=None if not (p := r_cfg.get("src_port")) else Port[p], + dst_port=None if not (p := r_cfg.get("dst_port")) else Port[p], + protocol=None if not (p := r_cfg.get("protocol")) else IPProtocol[p], + src_ip_address=r_cfg.get("src_ip"), + dst_ip_address=r_cfg.get("dst_ip"), + position=r_num, + ) # acl rules for internal_outbound_acl if cfg["acl"]["internal_outbound_acl"]: - firewall.internal_outbound_acl._default_config = cfg["acl"]["internal_outbound_acl"] - firewall.internal_outbound_acl._reset_rules_to_default() + for r_num, r_cfg in cfg["acl"]["internal_outbound_acl"].items(): + firewall.internal_outbound_acl.add_rule( + action=ACLAction[r_cfg["action"]], + src_port=None if not (p := r_cfg.get("src_port")) else Port[p], + dst_port=None if not (p := r_cfg.get("dst_port")) else Port[p], + protocol=None if not (p := r_cfg.get("protocol")) else IPProtocol[p], + src_ip_address=r_cfg.get("src_ip"), + dst_ip_address=r_cfg.get("dst_ip"), + position=r_num, + ) # acl rules for dmz_inbound_acl if cfg["acl"]["dmz_inbound_acl"]: - firewall.dmz_inbound_acl._default_config = cfg["acl"]["dmz_inbound_acl"] - firewall.dmz_inbound_acl._reset_rules_to_default() + for r_num, r_cfg in cfg["acl"]["dmz_inbound_acl"].items(): + firewall.dmz_inbound_acl.add_rule( + action=ACLAction[r_cfg["action"]], + src_port=None if not (p := r_cfg.get("src_port")) else Port[p], + dst_port=None if not (p := r_cfg.get("dst_port")) else Port[p], + protocol=None if not (p := r_cfg.get("protocol")) else IPProtocol[p], + src_ip_address=r_cfg.get("src_ip"), + dst_ip_address=r_cfg.get("dst_ip"), + position=r_num, + ) # acl rules for dmz_outbound_acl if cfg["acl"]["dmz_outbound_acl"]: - firewall.dmz_outbound_acl._default_config = cfg["acl"]["dmz_outbound_acl"] - firewall.dmz_outbound_acl._reset_rules_to_default() + for r_num, r_cfg in cfg["acl"]["dmz_outbound_acl"].items(): + firewall.dmz_outbound_acl.add_rule( + action=ACLAction[r_cfg["action"]], + src_port=None if not (p := r_cfg.get("src_port")) else Port[p], + dst_port=None if not (p := r_cfg.get("dst_port")) else Port[p], + protocol=None if not (p := r_cfg.get("protocol")) else IPProtocol[p], + src_ip_address=r_cfg.get("src_ip"), + dst_ip_address=r_cfg.get("dst_ip"), + position=r_num, + ) # acl rules for external_inbound_acl if cfg["acl"]["external_inbound_acl"]: - firewall.external_inbound_acl._default_config = cfg["acl"]["external_inbound_acl"] - firewall.external_inbound_acl._reset_rules_to_default() + for r_num, r_cfg in cfg["acl"]["external_inbound_acl"].items(): + firewall.external_inbound_acl.add_rule( + action=ACLAction[r_cfg["action"]], + src_port=None if not (p := r_cfg.get("src_port")) else Port[p], + dst_port=None if not (p := r_cfg.get("dst_port")) else Port[p], + protocol=None if not (p := r_cfg.get("protocol")) else IPProtocol[p], + src_ip_address=r_cfg.get("src_ip"), + dst_ip_address=r_cfg.get("dst_ip"), + position=r_num, + ) # acl rules for external_outbound_acl if cfg["acl"]["external_outbound_acl"]: - firewall.external_outbound_acl._default_config = cfg["acl"]["external_outbound_acl"] - firewall.external_outbound_acl._reset_rules_to_default() + for r_num, r_cfg in cfg["acl"]["external_outbound_acl"].items(): + firewall.external_outbound_acl.add_rule( + action=ACLAction[r_cfg["action"]], + src_port=None if not (p := r_cfg.get("src_port")) else Port[p], + dst_port=None if not (p := r_cfg.get("dst_port")) else Port[p], + protocol=None if not (p := r_cfg.get("protocol")) else IPProtocol[p], + src_ip_address=r_cfg.get("src_ip"), + dst_ip_address=r_cfg.get("dst_ip"), + position=r_num, + ) + if "routes" in cfg: for route in cfg.get("routes"): firewall.route_table.add_route( diff --git a/src/primaite/simulator/network/hardware/nodes/network/router.py b/src/primaite/simulator/network/hardware/nodes/network/router.py index 5b45f59c..d5302345 100644 --- a/src/primaite/simulator/network/hardware/nodes/network/router.py +++ b/src/primaite/simulator/network/hardware/nodes/network/router.py @@ -1401,7 +1401,9 @@ class Router(NetworkNode): router = Router( hostname=cfg["hostname"], num_ports=int(cfg.get("num_ports", "5")), - operating_state=NodeOperatingState.ON, + operating_state=NodeOperatingState.ON + if not (p := cfg.get("operating_state")) + else NodeOperatingState[p.upper()], ) if "ports" in cfg: for port_num, port_cfg in cfg["ports"].items(): diff --git a/tests/assets/configs/basic_switched_network.yaml b/tests/assets/configs/basic_switched_network.yaml index a248065c..daa40aa7 100644 --- a/tests/assets/configs/basic_switched_network.yaml +++ b/tests/assets/configs/basic_switched_network.yaml @@ -141,6 +141,17 @@ simulation: default_gateway: 192.168.10.1 dns_server: 192.168.1.10 # pre installed services and applications + - ref: client_3 + type: computer + hostname: client_3 + ip_address: 192.168.10.23 + subnet_mask: 255.255.255.0 + default_gateway: 192.168.10.1 + dns_server: 192.168.1.10 + start_up_duration: 0 + shut_down_duration: 0 + operating_state: "OFF" + # pre installed services and applications links: - ref: switch_1___client_1 diff --git a/tests/integration_tests/configuration_file_parsing/nodes/test_node_config.py b/tests/integration_tests/configuration_file_parsing/nodes/test_node_config.py index e222bfaf..f23e7612 100644 --- a/tests/integration_tests/configuration_file_parsing/nodes/test_node_config.py +++ b/tests/integration_tests/configuration_file_parsing/nodes/test_node_config.py @@ -1,6 +1,8 @@ from primaite.config.load import example_config_path from primaite.simulator.network.container import Network -from tests.integration_tests.configuration_file_parsing import DMZ_NETWORK, load_config +from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState +from primaite.simulator.network.hardware.nodes.host.computer import Computer +from tests.integration_tests.configuration_file_parsing import BASIC_CONFIG, DMZ_NETWORK, load_config def test_example_config(): @@ -24,3 +26,19 @@ def test_dmz_config(): assert len(network.routers) == 2 # 2 routers in network assert len(network.switches) == 3 # 3 switches in network assert len(network.servers) == 2 # 2 servers in network + + +def test_basic_config(): + """Test that the basic_switched_network config can be parsed properly.""" + game = load_config(BASIC_CONFIG) + network: Network = game.simulation.network + assert len(network.nodes) == 4 # 4 nodes in network + + client_1: Computer = network.get_node_by_hostname("client_1") + assert client_1.operating_state == NodeOperatingState.ON + client_2: Computer = network.get_node_by_hostname("client_2") + assert client_2.operating_state == NodeOperatingState.ON + + # client 3 should not be online + client_3: Computer = network.get_node_by_hostname("client_3") + assert client_3.operating_state == NodeOperatingState.OFF diff --git a/tests/integration_tests/configuration_file_parsing/software_installation_and_configuration.py b/tests/integration_tests/configuration_file_parsing/software_installation_and_configuration.py index 306f591d..f3dc51bd 100644 --- a/tests/integration_tests/configuration_file_parsing/software_installation_and_configuration.py +++ b/tests/integration_tests/configuration_file_parsing/software_installation_and_configuration.py @@ -1,6 +1,14 @@ from ipaddress import IPv4Address +from pathlib import Path +from typing import Union -from primaite.game.game import APPLICATION_TYPES_MAPPING, SERVICE_TYPES_MAPPING +import yaml + +from primaite.config.load import example_config_path +from primaite.game.agent.data_manipulation_bot import DataManipulationAgent +from primaite.game.agent.interface import ProxyAgent, RandomAgent +from primaite.game.game import APPLICATION_TYPES_MAPPING, PrimaiteGame, SERVICE_TYPES_MAPPING +from primaite.simulator.network.container import Network from primaite.simulator.network.hardware.nodes.host.computer import Computer from primaite.simulator.system.applications.database_client import DatabaseClient from primaite.simulator.system.applications.red_applications.data_manipulation_bot import DataManipulationBot