From 2722abe428a42be5d2258e8f4ae06e848c2f424e Mon Sep 17 00:00:00 2001 From: Marek Wolan Date: Mon, 9 Oct 2023 11:49:38 +0100 Subject: [PATCH] Fix typos and formattig (based on PR Review) --- docs/source/action_system.rst | 28 +++++++++---------- .../simulator/file_system/file_system.py | 2 +- src/primaite/simulator/network/container.py | 5 +--- .../test_action_integration.py | 2 +- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/docs/source/action_system.rst b/docs/source/action_system.rst index b527bff9..ef0fbd40 100644 --- a/docs/source/action_system.rst +++ b/docs/source/action_system.rst @@ -5,27 +5,27 @@ Actions System ============== -`SimComponent`s in the simulation are decoupled from the agent training logic. However, they still need a managed means of accepting requests to perform actions. For this, they use `ActionManager` and `Action`. +``SimComponent``s in the simulation are decoupled from the agent training logic. However, they still need a managed means of accepting requests to perform actions. For this, they use ``ActionManager`` and ``Action``. Just like other aspects of SimComponent, the actions are not managed centrally for the whole simulation, but instead they are dynamically created and updated based on the nodes, links, and other components that currently exist. This was achieved with the following design decisions: - API An 'action' contains two elements: - 1. `request` - selects which action you want to take on this `SimComponent`. This is formatted as a list of strings such as `['network', 'node', '', 'service', '', 'restart']`. - 2. `context` - optional extra information that can be used to decide how to process the action. This is formatted as a dictionary. For example, if the action requires authentication, the context can include information about the user that initiated the request to decide if their permissions are sufficient. + 1. ``request`` - selects which action you want to take on this ``SimComponent``. This is formatted as a list of strings such as `['network', 'node', '', 'service', '', 'restart']`. + 2. ``context`` - optional extra information that can be used to decide how to process the action. This is formatted as a dictionary. For example, if the action requires authentication, the context can include information about the user that initiated the request to decide if their permissions are sufficient. - request The request is a list of strings which help specify who should handle the request. The strings in the request list help ActionManagers traverse the 'ownership tree' of SimComponent. The example given above would be handled in the following way: - 1. `Simulation` receives `['network', 'node', '', 'service', '', 'restart']`. - The first element of the action is `network`, therefore it passes the action down to its network. - 2. `Network` receives `['node', '', 'service', '', 'restart']`. - The first element of the action is `node`, therefore the network looks at the node uuid and passes the action down to the node with that uuid. - 3. `Node` receives `['service', '', 'restart']`. - The first element of the action is `service`, therefore the node looks at the service uuid and passes the rest of the action to the service with that uuid. - 4. `Service` receives `['restart']`. - Since `restart` is a defined action in the service's own ActionManager, the service performs a restart. + 1. ``Simulation`` receives `['network', 'node', '', 'service', '', 'restart']`. + The first element of the action is ``network``, therefore it passes the action down to its network. + 2. ``Network`` receives `['node', '', 'service', '', 'restart']`. + The first element of the action is ``node``, therefore the network looks at the node uuid and passes the action down to the node with that uuid. + 3. ``Node`` receives `['service', '', 'restart']`. + The first element of the action is ``service``, therefore the node looks at the service uuid and passes the rest of the action to the service with that uuid. + 4. ``Service`` receives ``['restart']``. + Since ``restart`` is a defined action in the service's own ActionManager, the service performs a restart. Techincal Detail ================ @@ -35,12 +35,12 @@ This system was achieved by implementing two classes, :py:class:`primaite.simula Action ------ -The `Action` object stores a reference to a method that performs the action, for example a node could have an action that stores a reference to `self.turn_on()`. Techincally, this can be any callable that accepts `request, context` as it's parameters. In practice, this is often defined using `lambda` functions within a component's `self._init_action_manager()` method. Optionally, the `Action` object can also hold a validator that will permit/deny the action depending on context. +The ``Action`` object stores a reference to a method that performs the action, for example a node could have an action that stores a reference to ``self.turn_on()``. Techincally, this can be any callable that accepts `request, context` as it's parameters. In practice, this is often defined using ``lambda`` functions within a component's ``self._init_action_manager()`` method. Optionally, the ``Action`` object can also hold a validator that will permit/deny the action depending on context. ActionManager ------------- -The `ActionManager` object stores a mapping between strings and actions. It is responsible for processing the `request` and passing it down the ownership tree. Techincally, the `ActionManager` is itself a callable that accepts `request, context` tuple, and so it can be chained with other action managers. +The ``ActionManager`` object stores a mapping between strings and actions. It is responsible for processing the ``request`` and passing it down the ownership tree. Techincally, the ``ActionManager`` is itself a callable that accepts `request, context` tuple, and so it can be chained with other action managers. A simple example without chaining can be seen in the :py:class:`primaite.simulator.file_system.file_system.File` class. @@ -54,7 +54,7 @@ A simple example without chaining can be seen in the :py:class:`primaite.simulat action_manager.add_action("repair", Action(func=lambda request, context: self.repair())) action_manager.add_action("restore", Action(func=lambda request, context: self.restore())) -*ellipses (`...`) used to omit code impertinent to this explanation* +*ellipses (``...``) used to omit code impertinent to this explanation* Chaining ActionManagers ----------------------- diff --git a/src/primaite/simulator/file_system/file_system.py b/src/primaite/simulator/file_system/file_system.py index 2c110624..8d981100 100644 --- a/src/primaite/simulator/file_system/file_system.py +++ b/src/primaite/simulator/file_system/file_system.py @@ -332,7 +332,7 @@ class Folder(FileSystemItemABC): is_quarantined: bool = False "Flag that marks the folder as quarantined if true." - def _init_action_manager(sekf) -> ActionManager: + def _init_action_manager(self) -> ActionManager: am = super()._init_action_manager() am.add_action("scan", Action(func=lambda request, context: ...)) # TODO implement action diff --git a/src/primaite/simulator/network/container.py b/src/primaite/simulator/network/container.py index f3afad12..e0384b5e 100644 --- a/src/primaite/simulator/network/container.py +++ b/src/primaite/simulator/network/container.py @@ -48,10 +48,7 @@ class Network(SimComponent): self._node_action_manager = ActionManager() am.add_action( "node", - Action( - func=self._node_action_manager - # func=lambda request, context: self.nodes[request.pop(0)].apply_action(request, context), - ), + Action(func=self._node_action_manager), ) return am diff --git a/tests/integration_tests/component_creation/test_action_integration.py b/tests/integration_tests/component_creation/test_action_integration.py index eb18110d..ef04ec41 100644 --- a/tests/integration_tests/component_creation/test_action_integration.py +++ b/tests/integration_tests/component_creation/test_action_integration.py @@ -5,7 +5,7 @@ from primaite.simulator.network.hardware.nodes.computer import Computer from primaite.simulator.network.hardware.nodes.server import Server from primaite.simulator.network.hardware.nodes.switch import Switch from primaite.simulator.sim_container import Simulation -from primaite.simulator.system.services.database_service import DatabaseService +from primaite.simulator.system.services.database.database_service import DatabaseService def test_passing_actions_down(monkeypatch) -> None: