From 9a55b7b864511fbc5fe870b538864cb91b0d65e9 Mon Sep 17 00:00:00 2001 From: Chris McCarthy Date: Fri, 19 Apr 2024 15:58:50 +0100 Subject: [PATCH] #2266 - Fixed some minor bugs that prevented basic networks without a default gateway from being parsed. Completed the basic client-server P2P network documentation, file and retrieval method. --- .../simulation/nodes/network_examples.rst | 68 +++++++++++++++++++ .../client-server-p2p-network-example.yaml | 10 ++- .../game/agent/observations/observations.py | 4 +- src/primaite/game/agent/rewards.py | 4 +- src/primaite/game/game.py | 4 +- src/primaite/simulator/network/networks.py | 14 ++++ 6 files changed, 97 insertions(+), 7 deletions(-) diff --git a/docs/source/configuration/simulation/nodes/network_examples.rst b/docs/source/configuration/simulation/nodes/network_examples.rst index 572d8bb5..f5084d4c 100644 --- a/docs/source/configuration/simulation/nodes/network_examples.rst +++ b/docs/source/configuration/simulation/nodes/network_examples.rst @@ -29,7 +29,75 @@ and a Server on the same subnet with a single Link connecting the two. :width: 800 :align: center +The yaml file contains two nodes in the ``simulation.network.nodes`` array, one with the `pc_1` reference and another +with the `server_1` reference. both nodes are given a node type, `pc_1` being a `computer` and `server_1` being a +`server`. Both nodes are then given an ip address and subnet mask. +The link between the two nodes is configured in the ``simulation.network.links`` array, with the hostname and network +interface for each being configured under ``endpoint__hostname`` and ``endpoint__port`` respectively. + + + +.. code-block:: yaml + :linenos: + :emphasive-lines: + + simulation: + network: + nodes: + - hostname: pc_1 + type: computer + ip_address: 192.168.1.11 + subnet_mask: 255.255.255.0 + + - hostname: server_1 + type: server + ip_address: 192.168.1.13 + subnet_mask: 255.255.255.0 + + links: + - endpoint_a_hostname: pc_1 + endpoint_a_port: 1 + endpoint_b_hostname: server_1 + endpoint_b_port: 1 + +The following codeblock demonstrates how to access this network and all ``.show()`` to output the network details: + +.. code-block:: python + + from primaite.simulator.network.networks import client_server_p2p_network + + network = client_server_p2p_network() + + network.show() + +Which gives the output: + +.. code-block:: text + + +---------------------------------------+ + | Nodes | + +----------+----------+-----------------+ + | Node | Type | Operating State | + +----------+----------+-----------------+ + | server_1 | Server | ON | + | pc_1 | Computer | ON | + +----------+----------+-----------------+ + +------------------------------------------------------------------+ + | IP Addresses | + +----------+------+--------------+---------------+-----------------+ + | Node | Port | IP Address | Subnet Mask | Default Gateway | + +----------+------+--------------+---------------+-----------------+ + | server_1 | 1 | 192.168.1.13 | 255.255.255.0 | None | + | pc_1 | 1 | 192.168.1.11 | 255.255.255.0 | None | + +----------+------+--------------+---------------+-----------------+ + +------------------------------------------------------------------------------------------------------------------------------------------------------+ + | Links | + +------------+----------------------------------------+------------+----------------------------------------+-------+-------------------+--------------+ + | Endpoint A | A Port | Endpoint B | B Port | is Up | Bandwidth (MBits) | Current Load | + +------------+----------------------------------------+------------+----------------------------------------+-------+-------------------+--------------+ + | pc_1 | Port 1: dd:70:be:52:b1:a9/192.168.1.11 | server_1 | Port 1: 17:3a:11:af:9b:b1/192.168.1.13 | True | 100.0 | 0.00000% | + +------------+----------------------------------------+------------+----------------------------------------+-------+-------------------+--------------+ #2. Basic Switched Network -------------------------- diff --git a/src/primaite/config/_package_data/client-server-p2p-network-example.yaml b/src/primaite/config/_package_data/client-server-p2p-network-example.yaml index edaeb6f4..798dd318 100644 --- a/src/primaite/config/_package_data/client-server-p2p-network-example.yaml +++ b/src/primaite/config/_package_data/client-server-p2p-network-example.yaml @@ -1,3 +1,11 @@ +game: + ports: + - ARP + protocols: + - ICMP + - TCP + - UDP + simulation: network: nodes: @@ -8,7 +16,7 @@ simulation: - hostname: server_1 type: server - ip_address: 192.168.1.11 + ip_address: 192.168.1.13 subnet_mask: 255.255.255.0 links: diff --git a/src/primaite/game/agent/observations/observations.py b/src/primaite/game/agent/observations/observations.py index 0d6ff2a3..518fdf9f 100644 --- a/src/primaite/game/agent/observations/observations.py +++ b/src/primaite/game/agent/observations/observations.py @@ -1,6 +1,6 @@ """Manages the observation space for the agent.""" from abc import ABC, abstractmethod -from typing import Any, Dict, Iterable, Type +from typing import Any, Dict, Iterable, Type, Optional, Union from gymnasium import spaces from gymnasium.core import ObsType @@ -9,7 +9,7 @@ from pydantic import BaseModel, ConfigDict from primaite import getLogger _LOGGER = getLogger(__name__) -WhereType = Iterable[str | int] | None +WhereType = Optional[Iterable[Union[str, int]]] class AbstractObservation(ABC): diff --git a/src/primaite/game/agent/rewards.py b/src/primaite/game/agent/rewards.py index 726afaa4..0222bfcc 100644 --- a/src/primaite/game/agent/rewards.py +++ b/src/primaite/game/agent/rewards.py @@ -26,7 +26,7 @@ the structure: ``` """ from abc import abstractmethod -from typing import Callable, Dict, Iterable, List, Optional, Tuple, Type, TYPE_CHECKING +from typing import Callable, Dict, Iterable, List, Optional, Tuple, Type, TYPE_CHECKING, Union from typing_extensions import Never @@ -37,7 +37,7 @@ if TYPE_CHECKING: from primaite.game.agent.interface import AgentActionHistoryItem _LOGGER = getLogger(__name__) -WhereType = Iterable[str | int] | None +WhereType = Optional[Iterable[Union[str, int]]] class AbstractReward: diff --git a/src/primaite/game/game.py b/src/primaite/game/game.py index 908b5148..336c27df 100644 --- a/src/primaite/game/game.py +++ b/src/primaite/game/game.py @@ -244,7 +244,7 @@ class PrimaiteGame: hostname=node_cfg["hostname"], ip_address=node_cfg["ip_address"], subnet_mask=IPv4Address(node_cfg.get("subnet_mask", "255.255.255.0")), - default_gateway=node_cfg["default_gateway"], + default_gateway=node_cfg.get("default_gateway"), dns_server=node_cfg.get("dns_server", None), operating_state=NodeOperatingState.ON if not (p := node_cfg.get("operating_state")) @@ -255,7 +255,7 @@ class PrimaiteGame: hostname=node_cfg["hostname"], ip_address=node_cfg["ip_address"], subnet_mask=IPv4Address(node_cfg.get("subnet_mask", "255.255.255.0")), - default_gateway=node_cfg["default_gateway"], + default_gateway=node_cfg.get("default_gateway"), dns_server=node_cfg.get("dns_server", None), operating_state=NodeOperatingState.ON if not (p := node_cfg.get("operating_state")) diff --git a/src/primaite/simulator/network/networks.py b/src/primaite/simulator/network/networks.py index c1eef224..36d34bc3 100644 --- a/src/primaite/simulator/network/networks.py +++ b/src/primaite/simulator/network/networks.py @@ -1,5 +1,9 @@ from ipaddress import IPv4Address +import yaml + +from primaite import PRIMAITE_PATHS +from primaite.game.game import PrimaiteGame from primaite.simulator.network.container import Network from primaite.simulator.network.hardware.nodes.host.computer import Computer from primaite.simulator.network.hardware.nodes.host.host_node import NIC @@ -279,3 +283,13 @@ def arcd_uc2_network() -> Network: router_1.acl.add_rule(action=ACLAction.PERMIT, src_port=Port.HTTP, dst_port=Port.HTTP, position=3) return network + + +def client_server_p2p_network_example() -> Network: + path = PRIMAITE_PATHS.user_config_path / "example_config" / "client-server-p2p-network-example.yaml" + with open(path, "r") as file: + cfg = yaml.safe_load(file) + + game = PrimaiteGame.from_config(cfg) + + return game.simulation.network