Merge remote-tracking branch 'refs/remotes/origin/release/3.2.0' into dev
# Conflicts: # src/primaite/VERSION
This commit is contained in:
@@ -17,8 +17,6 @@ PLOT_CONFIG = {
|
||||
"size": {"auto_size": False, "width": 1500, "height": 900},
|
||||
"template": "plotly_white",
|
||||
"range_slider": False,
|
||||
"av_s_per_100_steps_10_nodes_benchmark_threshold": 5,
|
||||
"benchmark_line_color": "grey",
|
||||
}
|
||||
|
||||
|
||||
@@ -229,10 +227,7 @@ def _plot_av_s_per_100_steps_10_nodes(
|
||||
"""
|
||||
Creates a bar chart visualising the performance of each version of PrimAITE.
|
||||
|
||||
Performance is based on the average training time per 100 steps on 10 nodes. The function also includes a benchmark
|
||||
line indicating the target maximum time.
|
||||
|
||||
Versions that perform under this time are marked in green, and those over are marked in red.
|
||||
Performance is based on the average training time per 100 steps on 10 nodes.
|
||||
|
||||
:param version_times_dict: A dictionary with software versions as keys and average times as values.
|
||||
:return: A Plotly figure object representing the bar chart of the performance metrics.
|
||||
@@ -256,7 +251,6 @@ def _plot_av_s_per_100_steps_10_nodes(
|
||||
versions = sorted(list(version_times_dict.keys()))
|
||||
times = [version_times_dict[version] for version in versions]
|
||||
av_s_per_100_steps_10_nodes_benchmark_threshold = PLOT_CONFIG["av_s_per_100_steps_10_nodes_benchmark_threshold"]
|
||||
benchmark_line_color = PLOT_CONFIG["benchmark_line_color"]
|
||||
|
||||
# Calculate the appropriate maximum y-axis value
|
||||
max_y_axis_value = max(max(times), av_s_per_100_steps_10_nodes_benchmark_threshold) + 1
|
||||
@@ -265,28 +259,11 @@ def _plot_av_s_per_100_steps_10_nodes(
|
||||
go.Bar(
|
||||
x=versions,
|
||||
y=times,
|
||||
marker_color=[
|
||||
"green" if time < av_s_per_100_steps_10_nodes_benchmark_threshold else "red" for time in times
|
||||
],
|
||||
text=times,
|
||||
textposition="auto",
|
||||
)
|
||||
)
|
||||
|
||||
# Add a horizontal line for the benchmark
|
||||
fig.add_shape(
|
||||
type="line",
|
||||
x0=-0.5, # start slightly before the first bar
|
||||
x1=len(versions) - 0.5, # end slightly after the last bar
|
||||
y0=av_s_per_100_steps_10_nodes_benchmark_threshold,
|
||||
y1=av_s_per_100_steps_10_nodes_benchmark_threshold,
|
||||
line=dict(
|
||||
color=benchmark_line_color,
|
||||
width=2,
|
||||
dash="dot",
|
||||
),
|
||||
)
|
||||
|
||||
fig.update_layout(
|
||||
xaxis_title="PrimAITE Version",
|
||||
yaxis_title="Avg Time per 100 Steps on 10 Nodes (seconds)",
|
||||
|
||||
Binary file not shown.
@@ -1006,4 +1006,4 @@
|
||||
"999": 112.00000000000009,
|
||||
"1000": 102.55000000000008
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1006,4 +1006,4 @@
|
||||
"999": 110.30000000000007,
|
||||
"1000": 118.05000000000011
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1006,4 +1006,4 @@
|
||||
"999": 118.44999999999996,
|
||||
"1000": 108.20000000000029
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1006,4 +1006,4 @@
|
||||
"999": 99.50000000000009,
|
||||
"1000": 98.70000000000006
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1006,4 +1006,4 @@
|
||||
"999": 118.45000000000007,
|
||||
"1000": 116.3000000000001
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 149 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
@@ -0,0 +1,38 @@
|
||||
# PrimAITE v3.2.0 Learning Benchmark
|
||||
## PrimAITE Dev Team
|
||||
### 2024-07-21
|
||||
|
||||
---
|
||||
## 1 Introduction
|
||||
PrimAITE v3.2.0 was benchmarked automatically upon release. Learning rate metrics were captured to be referenced during system-level testing and user acceptance testing (UAT).
|
||||
The benchmarking process consists of running 5 training session using the same config file. Each session trains an agent for 1000 episodes, with each episode consisting of 128 steps.
|
||||
The total reward per episode from each session is captured. This is then used to calculate an caverage total reward per episode from the 5 individual sessions for smoothing. Finally, a 25-widow rolling average of the average total reward per session is calculated for further smoothing.
|
||||
## 2 System Information
|
||||
### 2.1 Python
|
||||
**Version:** 3.10.14 (main, Apr 6 2024, 18:45:05) [GCC 9.4.0]
|
||||
### 2.2 System
|
||||
- **OS:** Linux
|
||||
- **OS Version:** #76~20.04.1-Ubuntu SMP Thu Jun 13 18:00:23 UTC 2024
|
||||
- **Machine:** x86_64
|
||||
- **Processor:** x86_64
|
||||
### 2.3 CPU
|
||||
- **Physical Cores:** 2
|
||||
- **Total Cores:** 4
|
||||
- **Max Frequency:** 0.00Mhz
|
||||
### 2.4 Memory
|
||||
- **Total:** 15.62GB
|
||||
- **Swap Total:** 0.00B
|
||||
## 3 Stats
|
||||
- **Total Sessions:** 5
|
||||
- **Total Episodes:** 5005
|
||||
- **Total Steps:** 640000
|
||||
- **Av Session Duration (s):** 1691.5034
|
||||
- **Av Step Duration (s):** 0.0529
|
||||
- **Av Duration per 100 Steps per 10 Nodes (s):** 5.2859
|
||||
## 4 Graphs
|
||||
### 4.1 v3.2.0 Learning Benchmark Plot
|
||||

|
||||
### 4.2 Learning Benchmark of Minor and Bugfix Releases for Major Version 3
|
||||

|
||||
### 4.3 Performance of Minor and Bugfix Releases for Major Version 3
|
||||

|
||||
Binary file not shown.
|
After Width: | Height: | Size: 356 KiB |
1009
benchmark/results/v3/v3.2.0/session_metadata/1.json
Normal file
1009
benchmark/results/v3/v3.2.0/session_metadata/1.json
Normal file
File diff suppressed because it is too large
Load Diff
1009
benchmark/results/v3/v3.2.0/session_metadata/2.json
Normal file
1009
benchmark/results/v3/v3.2.0/session_metadata/2.json
Normal file
File diff suppressed because it is too large
Load Diff
1009
benchmark/results/v3/v3.2.0/session_metadata/3.json
Normal file
1009
benchmark/results/v3/v3.2.0/session_metadata/3.json
Normal file
File diff suppressed because it is too large
Load Diff
1009
benchmark/results/v3/v3.2.0/session_metadata/4.json
Normal file
1009
benchmark/results/v3/v3.2.0/session_metadata/4.json
Normal file
File diff suppressed because it is too large
Load Diff
1009
benchmark/results/v3/v3.2.0/session_metadata/5.json
Normal file
1009
benchmark/results/v3/v3.2.0/session_metadata/5.json
Normal file
File diff suppressed because it is too large
Load Diff
7445
benchmark/results/v3/v3.2.0/v3.2.0_benchmark_metadata.json
Normal file
7445
benchmark/results/v3/v3.2.0/v3.2.0_benchmark_metadata.json
Normal file
File diff suppressed because it is too large
Load Diff
144
docs/index.rst
144
docs/index.rst
@@ -8,6 +8,46 @@ Welcome to PrimAITE's documentation
|
||||
What is PrimAITE?
|
||||
-----------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 8
|
||||
:caption: About PrimAITE:
|
||||
:hidden:
|
||||
|
||||
source/about
|
||||
source/dependencies
|
||||
source/glossary
|
||||
|
||||
.. toctree::
|
||||
:caption: Usage:
|
||||
:hidden:
|
||||
|
||||
source/getting_started
|
||||
source/game_layer
|
||||
source/simulation
|
||||
source/config
|
||||
source/customising_scenarios
|
||||
source/varying_config_files
|
||||
source/environment
|
||||
source/action_masking
|
||||
|
||||
.. toctree::
|
||||
:caption: Notebooks:
|
||||
:hidden:
|
||||
|
||||
source/example_notebooks
|
||||
source/notebooks/executed_notebooks
|
||||
|
||||
.. toctree::
|
||||
:caption: Developer information:
|
||||
:hidden:
|
||||
|
||||
source/developer_tools
|
||||
source/state_system
|
||||
source/request_system
|
||||
PrimAITE API <source/_autosummary/primaite>
|
||||
PrimAITE Tests <source/_autosummary/tests>
|
||||
|
||||
|
||||
Overview
|
||||
^^^^^^^^
|
||||
|
||||
@@ -36,108 +76,6 @@ PrimAITE incorporates the following features:
|
||||
- A PCAP service is seamlessly integrated within the simulation, automatically capturing and logging frames for both
|
||||
inbound and outbound traffic at the network interface level. This automatic functionality, combined with the ability
|
||||
to separate traffic directions, significantly enhances network analysis and troubleshooting capabilities;
|
||||
- Agent action logs provide a description of every action taken by each agent during the episode. This includes timestep, action, parameters, request and response, for all Blue agent activity, which is aligned with the Track 2 Common Action / Observation Space (CAOS) format. Action logs also details of all scripted / stochastic red / green agent actions;
|
||||
- Agent action logs provide a description of every action taken by each agent during the episode. This includes timestep, action, parameters, request and response, for all Blue agent activity, which is aligned with the Track 2 Common Action / Observation Space (CAOS) format. Action logs also detail all scripted / stochastic red / green agent actions;
|
||||
- Environment ground truth is provided at every timestep, providing a full description of the environment’s true state;
|
||||
- Alignment with CAOS provides the ability to transfer agents between CAOS compliant environments.
|
||||
|
||||
Architecture
|
||||
^^^^^^^^^^^^
|
||||
|
||||
PrimAITE is a Python application and will operate on multiple Operating Systems (Windows, Linux and Mac);
|
||||
a comprehensive installation and user guide is provided with each release to support its usage.
|
||||
|
||||
Configuration of PrimAITE is achieved via included YAML files which support full control over the network / system laydown being modelled, background pattern of life, adversarial (red agent) behaviour, and step and episode count.
|
||||
A Simulation Controller layer manages the overall running of the simulation, keeping track of all low-level objects.
|
||||
|
||||
It is agnostic to the number of agents, their action / observation spaces, and the RL library being used.
|
||||
|
||||
It presents a public API providing a method for describing the current state of the simulation, a method that accepts action requests and provides responses, and a method that triggers a timestep advancement.
|
||||
The Game Layer converts the simulation into a playable game for the agent(s).
|
||||
|
||||
It translates between simulation state and Gymnasium.Spaces to pass action / observation data between the agent(s) and the simulation. It is responsible for calculating rewards, managing Multi-Agent RL (MARL) action turns, and via a single agent interface can interact with Blue, Red and Green agents.
|
||||
|
||||
Agents can either generate their own scripted behaviour or accept input behaviour from an RL agent.
|
||||
|
||||
Finally, a Gymnasium / Ray RLlib Environment Layer forwards requests to the Game Layer as the agent sends them. This layer also manages most of the I/O, such as reading in the configuration files and saving agent logs.
|
||||
|
||||
.. image:: ../../_static/primAITE_architecture.png
|
||||
:width: 500
|
||||
:align: center
|
||||
|
||||
|
||||
Training & Evaluation Capability
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
PrimAITE provides a training and evaluation capability to AI agents in the context of cyber-attack, via its Gymnasium / Ray RLlib compliant interface.
|
||||
|
||||
Scenarios can be constructed to reflect network / system laydowns consisting of any configuration of nodes (e.g., PCs, servers etc.) and the networking equipment and links between them.
|
||||
|
||||
All nodes can be configured to contain applications, services, folders and files (and their status).
|
||||
|
||||
Traffic flows between services and applications as directed by an ‘execution definition,’ with the traffic flow on the network governed by the network equipment (switches, routers and firewalls) and the ACL rules and routing tables they employ.
|
||||
|
||||
Highlights of PrimAITE’s training and evaluation capability are:
|
||||
|
||||
- The scenario is not bound to a representation of any platform, system, or technology;
|
||||
- Fully configurable (network / system laydown, green pattern-of-life, red personas, reward function, ACL rules for each device, number of episodes / steps, action / observation space) and repeatable to suit the requirements of AI agents;
|
||||
- Can integrate with any Gymnasium / Ray RLlib compliant AI agent .
|
||||
|
||||
|
||||
PrimAITE provides a number of use cases (network and red/green action configurations) by default which the user is able to extend and modify as required.
|
||||
|
||||
What is PrimAITE built with
|
||||
---------------------------
|
||||
|
||||
* `Gymnasium <https://gymnasium.farama.org/>`_ is used as the basis for AI blue agent interaction with the PrimAITE environment
|
||||
* `Networkx <https://github.com/networkx/networkx>`_ is used as the underlying data structure used for the PrimAITE environment
|
||||
* `Stable Baselines 3 <https://github.com/DLR-RM/stable-baselines3>`_ is used as a default source of RL algorithms (although PrimAITE is not limited to SB3 agents)
|
||||
* `Ray RLlib <https://github.com/ray-project/ray>`_ is used as an additional source of RL algorithms
|
||||
* `Typer <https://github.com/tiangolo/typer>`_ is used for building CLIs (Command Line Interface applications)
|
||||
* `Jupyterlab <https://github.com/jupyterlab/jupyterlab>`_ is used as an extensible environment for interactive and reproducible computing, based on the Jupyter Notebook Architecture
|
||||
* `Platformdirs <https://github.com/platformdirs/platformdirs>`_ is used for finding the right location to store user data and configuration but varies per platform
|
||||
* `Plotly <https://github.com/plotly/plotly.py>`_ is used for building high level charts
|
||||
|
||||
|
||||
Getting Started with PrimAITE
|
||||
-----------------------------
|
||||
|
||||
Head over to the :ref:`getting-started` page to install and setup PrimAITE!
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 8
|
||||
:caption: About PrimAITE:
|
||||
:hidden:
|
||||
|
||||
source/about
|
||||
source/dependencies
|
||||
source/glossary
|
||||
|
||||
.. toctree::
|
||||
:caption: Usage:
|
||||
:hidden:
|
||||
|
||||
source/getting_started
|
||||
source/simulation
|
||||
source/game_layer
|
||||
source/config
|
||||
source/environment
|
||||
source/customising_scenarios
|
||||
source/varying_config_files
|
||||
source/action_masking
|
||||
|
||||
.. toctree::
|
||||
:caption: Notebooks:
|
||||
:hidden:
|
||||
|
||||
source/example_notebooks
|
||||
source/notebooks/executed_notebooks
|
||||
|
||||
.. toctree::
|
||||
:caption: Developer information:
|
||||
:hidden:
|
||||
|
||||
source/developer_tools
|
||||
source/state_system
|
||||
source/request_system
|
||||
PrimAITE API <source/_autosummary/primaite>
|
||||
PrimAITE Tests <source/_autosummary/tests>
|
||||
|
||||
@@ -7,27 +7,68 @@
|
||||
About PrimAITE
|
||||
==============
|
||||
|
||||
PrimAITE is a simulation environment for training agents to protect a computer network from cyber attacks.
|
||||
Architecture
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Features
|
||||
********
|
||||
PrimAITE is a Python application and will operate on multiple Operating Systems (Windows, Linux and Mac);
|
||||
a comprehensive installation and user guide is provided with each release to support its usage.
|
||||
|
||||
PrimAITE provides the following features:
|
||||
Configuration of PrimAITE is achieved via included YAML files which support full control over the network / system laydown being modelled, background pattern of life, adversarial (red agent) behaviour, and step and episode count.
|
||||
A Simulation Controller layer manages the overall running of the simulation, keeping track of all low-level objects.
|
||||
|
||||
* A flexible system for defining network layouts and host configurations
|
||||
* Highly configurable network hosts, including definition of software, file system, and network interfaces,
|
||||
* Realistic network traffic simulation, including address and sending packets via internet protocols like TCP, UDP, ICMP, etc.
|
||||
* Routers with traffic routing and firewall capabilities
|
||||
* Simulation of customisable deterministic agents
|
||||
* Support for multiple agents, each having their own customisable observation space, action space, and reward function definition.
|
||||
It is agnostic to the number of agents, their action / observation spaces, and the RL library being used.
|
||||
|
||||
It presents a public API providing a method for describing the current state of the simulation, a method that accepts action requests and provides responses, and a method that triggers a timestep advancement.
|
||||
The Game Layer converts the simulation into a playable game for the agent(s).
|
||||
|
||||
It translates between simulation state and Gymnasium.Spaces to pass action / observation data between the agent(s) and the simulation. It is responsible for calculating rewards, managing Multi-Agent RL (MARL) action turns, and via a single agent interface can interact with Blue, Red and Green agents.
|
||||
|
||||
Agents can either generate their own scripted behaviour or accept input behaviour from an RL agent.
|
||||
|
||||
Finally, a Gymnasium / Ray RLlib Environment Layer forwards requests to the Game Layer as the agent sends them. This layer also manages most of the I/O, such as reading in the configuration files and saving agent logs.
|
||||
|
||||
.. image:: ../../_static/primAITE_architecture.png
|
||||
:width: 500
|
||||
:align: center
|
||||
|
||||
|
||||
Structure
|
||||
*********
|
||||
Training & Evaluation Capability
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
PrimAITE consists of a simulator and a 'game' layer that allows agents to interact with the simulator. The simulator is built in a modular way where each component such as network hosts, links, networking devices, softwares, etc. are implemented as instances of a base class, meaning they all support the same interface. This allows for standardised configuration using either the Python API or YAML files.
|
||||
The game layer is built on top of the simulator and it consumes the simulation action/state interface to allow agents to interact with the simulator. The game layer is also responsible for defining the reward function and observation space for the agents.
|
||||
PrimAITE provides a training and evaluation capability to AI agents in the context of cyber-attack, via its Gymnasium / Ray RLlib compliant interface.
|
||||
|
||||
Scenarios can be constructed to reflect network / system laydowns consisting of any configuration of nodes (e.g., PCs, servers etc.) and the networking equipment and links between them.
|
||||
|
||||
All nodes can be configured to contain applications, services, folders and files (and their status).
|
||||
|
||||
Traffic flows between services and applications as directed by an ‘execution definition’, with the traffic flow on the network governed by the network equipment (switches, routers and firewalls) and the ACL rules and routing tables they employ.
|
||||
|
||||
Highlights of PrimAITE’s training and evaluation capability are:
|
||||
|
||||
- The scenario is not bound to a representation of any platform, system, or technology;
|
||||
- Fully configurable (network / system laydown, green pattern-of-life, red personas, reward function, ACL rules for each device, number of episodes / steps, action / observation space) and repeatable to suit the requirements of AI agents;
|
||||
- Can integrate with any Gymnasium / Ray RLlib compliant AI agent.
|
||||
|
||||
|
||||
PrimAITE provides a number of use cases (network and red/green action configurations) by default which the user is able to extend and modify as required.
|
||||
|
||||
What is PrimAITE built with
|
||||
---------------------------
|
||||
|
||||
* `Gymnasium <https://gymnasium.farama.org/>`_ is used as the basis for AI blue agent interaction with the PrimAITE environment
|
||||
* `Networkx <https://github.com/networkx/networkx>`_ is used as the underlying data structure used for the PrimAITE environment
|
||||
* `Stable Baselines 3 <https://github.com/DLR-RM/stable-baselines3>`_ is used as a default source of RL algorithms (although PrimAITE is not limited to SB3 agents)
|
||||
* `Ray RLlib <https://github.com/ray-project/ray>`_ is used as an additional source of RL algorithms
|
||||
* `Typer <https://github.com/tiangolo/typer>`_ is used for building CLIs (Command Line Interface applications)
|
||||
* `Jupyterlab <https://github.com/jupyterlab/jupyterlab>`_ is used as an extensible environment for interactive and reproducible computing, based on the Jupyter Notebook Architecture
|
||||
* `Platformdirs <https://github.com/platformdirs/platformdirs>`_ is used for finding the right location to store user data and configuration but varies per platform
|
||||
* `Plotly <https://github.com/plotly/plotly.py>`_ is used for building high level charts
|
||||
|
||||
|
||||
Getting Started with PrimAITE
|
||||
-----------------------------
|
||||
|
||||
Head over to the :ref:`getting-started` page to install and setup PrimAITE!
|
||||
|
||||
..
|
||||
Architecture - Nodes and Links
|
||||
|
||||
@@ -18,52 +18,101 @@ Masking Logic
|
||||
=============
|
||||
The following logic is applied:
|
||||
|
||||
* **DONOTHING** : Always possible
|
||||
* **NODE_HOST_SERVICE_SCAN** : Node is on. Service is running.
|
||||
* **NODE_HOST_SERVICE_STOP** : Node is on. Service is running.
|
||||
* **NODE_HOST_SERVICE_START** : Node is on. Service is stopped.
|
||||
* **NODE_HOST_SERVICE_PAUSE** : Node is on. Service is running.
|
||||
* **NODE_HOST_SERVICE_RESUME** : Node is on. Service is paused.
|
||||
* **NODE_HOST_SERVICE_RESTART** : Node is on. Service is running.
|
||||
* **NODE_HOST_SERVICE_DISABLE** : Node is on.
|
||||
* **NODE_HOST_SERVICE_ENABLE** : Node is on. Service is disabled.
|
||||
* **NODE_HOST_SERVICE_FIX** : Node is on. Service is running.
|
||||
* **NODE_HOST_APPLICATION_EXECUTE** : Node is on.
|
||||
* **NODE_HOST_APPLICATION_SCAN** : Node is on. Application is running.
|
||||
* **NODE_HOST_APPLICATION_CLOSE** : Node is on. Application is running.
|
||||
* **NODE_HOST_APPLICATION_FIX** : Node is on. Application is running.
|
||||
* **NODE_HOST_APPLICATION_INSTALL** : Node is on.
|
||||
* **NODE_HOST_APPLICATION_REMOVE** : Node is on.
|
||||
* **NODE_HOST_FILE_SCAN** : Node is on. File exists. File not deleted.
|
||||
* **NODE_HOST_FILE_CREATE** : Node is on.
|
||||
* **NODE_HOST_FILE_CHECKHASH** : Node is on. File exists. File not deleted.
|
||||
* **NODE_HOST_FILE_DELETE** : Node is on. File exists.
|
||||
* **NODE_HOST_FILE_REPAIR** : Node is on. File exists. File not deleted.
|
||||
* **NODE_HOST_FILE_RESTORE** : Node is on. File exists. File is deleted.
|
||||
* **NODE_HOST_FILE_CORRUPT** : Node is on. File exists. File not deleted.
|
||||
* **NODE_HOST_FILE_ACCESS** : Node is on. File exists. File not deleted.
|
||||
* **NODE_HOST_FOLDER_CREATE** : Node is on.
|
||||
* **NODE_HOST_FOLDER_SCAN** : Node is on. Folder exists. Folder not deleted.
|
||||
* **NODE_HOST_FOLDER_CHECKHASH** : Node is on. Folder exists. Folder not deleted.
|
||||
* **NODE_HOST_FOLDER_REPAIR** : Node is on. Folder exists. Folder not deleted.
|
||||
* **NODE_HOST_FOLDER_RESTORE** : Node is on. Folder exists. Folder is deleted.
|
||||
* **NODE_HOST_OS_SCAN** : Node is on.
|
||||
* **NODE_HOST_NIC_ENABLE** : NIC is disabled. Node is on.
|
||||
* **NODE_HOST_NIC_DISABLE** : NIC is enabled. Node is on.
|
||||
* **NODE_HOST_SHUTDOWN** : Node is on.
|
||||
* **NODE_HOST_STARTUP** : Node is off.
|
||||
* **NODE_HOST_RESET** : Node is on.
|
||||
* **NODE_HOST_NMAP_PING_SCAN** : Node is on.
|
||||
* **NODE_HOST_NMAP_PORT_SCAN** : Node is on.
|
||||
* **NODE_HOST_NMAP_NETWORK_SERVICE_RECON** : Node is on.
|
||||
* **NODE_ROUTER_PORT_ENABLE** : Router is on.
|
||||
* **NODE_ROUTER_PORT_DISABLE** : Router is on.
|
||||
* **NODE_ROUTER_ACL_ADDRULE** : Router is on.
|
||||
* **NODE_ROUTER_ACL_REMOVERULE** : Router is on.
|
||||
* **NODE_FIREWALL_PORT_ENABLE** : Firewall is on.
|
||||
* **NODE_FIREWALL_PORT_DISABLE** : Firewall is on.
|
||||
* **NODE_FIREWALL_ACL_ADDRULE** : Firewall is on.
|
||||
* **NODE_FIREWALL_ACL_REMOVERULE** : Firewall is on.
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| Action | Action Mask Logic |
|
||||
+==========================================+=====================================================================+
|
||||
| **DONOTHING** | Always Possible. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_SERVICE_SCAN** | Node is on. Service is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_SERVICE_STOP** | Node is on. Service is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_SERVICE_START** | Node is on. Service is stopped. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_SERVICE_PAUSE** | Node is on. Service is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_SERVICE_RESUME** | Node is on. Service is paused. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_SERVICE_RESTART** | Node is on. Service is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_SERVICE_DISABLE** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_SERVICE_ENABLE** | Node is on. Service is disabled. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_SERVICE_FIX** | Node is on. Service is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_APPLICATION_EXECUTE** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_APPLICATION_SCAN** | Node is on. Application is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_APPLICATION_CLOSE** | Node is on. Application is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_APPLICATION_FIX** | Node is on. Application is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_APPLICATION_INSTALL** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_APPLICATION_REMOVE** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FILE_SCAN** | Node is on. File exists. File not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FILE_CREATE** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FILE_CHECKHASH** | Node is on. File exists. File not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FILE_DELETE** | Node is on. File exists. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FILE_REPAIR** | Node is on. File exists. File not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FILE_RESTORE** | Node is on. File exists. File is deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FILE_CORRUPT** | Node is on. File exists. File not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FILE_ACCESS** | Node is on. File exists. File not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FOLDER_CREATE** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FOLDER_SCAN** | Node is on. Folder exists. Folder not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FOLDER_CHECKHASH** | Node is on. Folder exists. Folder not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FOLDER_REPAIR** | Node is on. Folder exists. Folder not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_FOLDER_RESTORE** | Node is on. Folder exists. Folder is deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_OS_SCAN** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_NIC_ENABLE** | NIC is disabled. Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_NIC_DISABLE** | NIC is enabled. Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_SHUTDOWN** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_STARTUP** | Node is off. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_RESET** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_NMAP_PING_SCAN** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_NMAP_PORT_SCAN** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_HOST_NMAP_NETWORK_SERVICE_RECON** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_ROUTER_PORT_ENABLE** | Router is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_ROUTER_PORT_DISABLE** | Router is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_ROUTER_ACL_ADDRULE** | Router is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_ROUTER_ACL_REMOVERULE** | Router is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FIREWALL_PORT_ENABLE** | Firewall is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FIREWALL_PORT_DISABLE** | Firewall is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FIREWALL_ACL_ADDRULE** | Firewall is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FIREWALL_ACL_REMOVERULE** | Firewall is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
|
||||
|
||||
Mechanism
|
||||
|
||||
@@ -111,7 +111,7 @@ This is an integer value specifying the allowed bandwidth across the connection.
|
||||
This section configures settings specific to the wireless network's virtual airspace.
|
||||
|
||||
``frequency_max_capacity_mbps``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This setting allows the user to override the default maximum bandwidth capacity set for each frequency. The key should
|
||||
be the AirSpaceFrequency name and the value be the desired maximum bandwidth capacity in mbps (megabits per second) for
|
||||
|
||||
@@ -49,36 +49,68 @@ dev-mode configuration
|
||||
|
||||
The following configures some specific items that the dev-mode overrides, if enabled.
|
||||
|
||||
`--sys-log-level` or `-level`
|
||||
----------------------------
|
||||
`--sys-log-level` or `-slevel`
|
||||
-----------------------------
|
||||
|
||||
The level of system logs can be overridden by dev-mode.
|
||||
|
||||
By default, this is set to DEBUG
|
||||
|
||||
The available options are [DEBUG|INFO|WARNING|ERROR|CRITICAL]
|
||||
The available options for both system and agent logs are:
|
||||
|
||||
.. code-block::
|
||||
|
||||
primaite dev-mode config -level INFO
|
||||
|
||||
or
|
||||
+-------------------+
|
||||
| Log Level |
|
||||
+===================+
|
||||
| DEBUG |
|
||||
+-------------------+
|
||||
| INFO |
|
||||
+-------------------+
|
||||
| WARNING |
|
||||
+-------------------+
|
||||
| ERROR |
|
||||
+-------------------+
|
||||
| CRITICAL |
|
||||
+-------------------+
|
||||
|
||||
.. code-block::
|
||||
|
||||
primaite dev-mode config --sys-log-level INFO
|
||||
|
||||
or
|
||||
|
||||
.. code-block::
|
||||
|
||||
primaite dev-mode config -slevel INFO
|
||||
|
||||
|
||||
`--agent-log-level` or `-alevel`
|
||||
--------------------------------
|
||||
|
||||
The level of agent logs can be overridden by dev-mode.
|
||||
|
||||
By default, this is set to DEBUG.
|
||||
|
||||
.. code-block::
|
||||
|
||||
primaite dev-mode config --agent-log-level INFO
|
||||
|
||||
or
|
||||
|
||||
.. code-block::
|
||||
|
||||
primaite dev-mode config -alevel INFO
|
||||
|
||||
`--output-sys-logs` or `-sys`
|
||||
-----------------------------
|
||||
|
||||
The outputting of system logs can be overridden by dev-mode.
|
||||
The output of system logs can be overridden by dev-mode.
|
||||
|
||||
By default, this is set to False
|
||||
|
||||
Enabling system logs
|
||||
""""""""""""""""""""
|
||||
|
||||
To enable outputting of system logs
|
||||
To enable output of system logs
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -93,7 +125,7 @@ or
|
||||
Disabling system logs
|
||||
"""""""""""""""""""""
|
||||
|
||||
To disable outputting of system logs
|
||||
To disable output of system logs
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -105,17 +137,47 @@ or
|
||||
|
||||
primaite dev-mode config -nsys
|
||||
|
||||
Enabling agent logs
|
||||
""""""""""""""""""""
|
||||
|
||||
To enable output of system logs
|
||||
|
||||
.. code-block::
|
||||
|
||||
primaite dev-mode config --output-agent-logs
|
||||
|
||||
or
|
||||
|
||||
.. code-block::
|
||||
|
||||
primaite dev-mode config -agent
|
||||
|
||||
Disabling system logs
|
||||
"""""""""""""""""""""
|
||||
|
||||
To disable output of system logs
|
||||
|
||||
.. code-block::
|
||||
|
||||
primaite dev-mode config --no-agent-logs
|
||||
|
||||
or
|
||||
|
||||
.. code-block::
|
||||
|
||||
primaite dev-mode config -nagent
|
||||
|
||||
`--output-pcap-logs` or `-pcap`
|
||||
-------------------------------
|
||||
|
||||
The outputting of packet capture logs can be overridden by dev-mode.
|
||||
The output of packet capture logs can be overridden by dev-mode.
|
||||
|
||||
By default, this is set to False
|
||||
|
||||
Enabling PCAP logs
|
||||
""""""""""""""""""
|
||||
|
||||
To enable outputting of packet capture logs
|
||||
To enable output of packet capture logs
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -130,7 +192,7 @@ or
|
||||
Disabling PCAP logs
|
||||
"""""""""""""""""""
|
||||
|
||||
To disable outputting of packet capture logs
|
||||
To disable output of packet capture logs
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -145,14 +207,14 @@ or
|
||||
`--output-to-terminal` or `-t`
|
||||
------------------------------
|
||||
|
||||
The outputting of system logs to the terminal can be overridden by dev-mode.
|
||||
The output of system logs to the terminal can be overridden by dev-mode.
|
||||
|
||||
By default, this is set to False
|
||||
|
||||
Enabling system log output to terminal
|
||||
""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
To enable outputting of system logs to terminal
|
||||
To enable output of system logs to terminal
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -167,7 +229,7 @@ or
|
||||
Disabling system log output to terminal
|
||||
"""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
To disable outputting of system logs to terminal
|
||||
To disable output of system logs to terminal
|
||||
|
||||
.. code-block::
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _example jupyter notebooks:
|
||||
|
||||
Example Jupyter Notebooks
|
||||
=========================
|
||||
|
||||
@@ -18,6 +20,7 @@ Running Jupyter Notebooks
|
||||
-------------------------
|
||||
|
||||
1. Navigate to the PrimAITE directory
|
||||
"""""""""""""""""""""""""""""""""""""
|
||||
|
||||
.. code-block:: bash
|
||||
:caption: Unix
|
||||
@@ -29,7 +32,10 @@ Running Jupyter Notebooks
|
||||
|
||||
cd ~\primaite\{VERSION}
|
||||
|
||||
2. Run jupyter notebook (the python environment to which you installed PrimAITE must be active)
|
||||
2. Run jupyter notebook
|
||||
"""""""""""""""""""""""
|
||||
|
||||
**Please note that the python environment to which you installed PrimAITE must be active.**
|
||||
|
||||
.. code-block:: bash
|
||||
:caption: Unix
|
||||
@@ -42,11 +48,13 @@ Running Jupyter Notebooks
|
||||
jupyter notebook
|
||||
|
||||
3. Opening the jupyter webpage (optional)
|
||||
"""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
The default web browser may automatically open the webpage. However, if that is not the case, click the link shown in your command prompt output. It should look like this: ``http://localhost:8888/?token=0123456798abc0123456789abc``
|
||||
|
||||
|
||||
4. Navigate to the list of notebooks
|
||||
"""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
The example notebooks are located in ``notebooks/example_notebooks/``. The file system shown in the jupyter webpage is relative to the location in which the ``jupyter notebook`` command was used.
|
||||
|
||||
@@ -77,6 +85,6 @@ The following extensions should now be installed
|
||||
:width: 300
|
||||
:align: center
|
||||
|
||||
VSCode will then ask for a Python environment version to use. PrimAITE is compatible with Python versions 3.9 - 3.11
|
||||
VSCode will then ask for a Python environment version to use. PrimAITE is compatible with Python versions 3.8 - 3.11
|
||||
|
||||
You should now be able to interact with the notebook.
|
||||
|
||||
@@ -42,49 +42,50 @@ An agent's reward function is managed by the ``RewardManager``. It calculates re
|
||||
Reward Components
|
||||
-----------------
|
||||
|
||||
Currently implemented are reward components tailored to the data manipulation scenario. View the full API and description of how they work here: :py:module:`primaite.game.agent.reward`.
|
||||
Currently implemented are reward components tailored to the data manipulation scenario. View the full API and description of how they work here: :py:modules:`primaite.game.agent.rewards`.
|
||||
|
||||
Reward Sharing
|
||||
--------------
|
||||
|
||||
An agent's reward can be based on rewards of other agents. This is particularly useful for modelling a situation where the blue agent's job is to protect the ability of green agents to perform their pattern-of-life. This can be configured in the YAML file this way:
|
||||
|
||||
```yaml
|
||||
green_agent_1: # this agent sometimes tries to access the webpage, and sometimes the database
|
||||
# actions, observations, and agent settings go here
|
||||
reward_function:
|
||||
reward_components:
|
||||
.. code-block:: yaml
|
||||
|
||||
# When the webpage loads, the reward goes up by 0.25 when it fails to load, it goes down to -0.25
|
||||
- type: WEBPAGE_UNAVAILABLE_PENALTY
|
||||
weight: 0.25
|
||||
options:
|
||||
node_hostname: client_2
|
||||
green_agent_1: # this agent sometimes tries to access the webpage, and sometimes the database
|
||||
# actions, observations, and agent settings go here
|
||||
reward_function:
|
||||
reward_components:
|
||||
|
||||
# When the database is reachable, the reward goes up by 0.05, when it is unreachable it goes down to -0.05
|
||||
- type: GREEN_ADMIN_DATABASE_UNREACHABLE_PENALTY
|
||||
weight: 0.05
|
||||
options:
|
||||
node_hostname: client_2
|
||||
# When the webpage loads, the reward goes up by 0.25 when it fails to load, it goes down to -0.25
|
||||
- type: WEBPAGE_UNAVAILABLE_PENALTY
|
||||
weight: 0.25
|
||||
options:
|
||||
node_hostname: client_2
|
||||
|
||||
blue_agent:
|
||||
# actions, observations, and agent settings go here
|
||||
reward_function:
|
||||
reward_components:
|
||||
# When the database is reachable, the reward goes up by 0.05, when it is unreachable it goes down to -0.05
|
||||
- type: GREEN_ADMIN_DATABASE_UNREACHABLE_PENALTY
|
||||
weight: 0.05
|
||||
options:
|
||||
node_hostname: client_2
|
||||
|
||||
# When the database file is in a good state, blue's reward is 0.4, when it's in a corrupted state the reward is -0.4
|
||||
- type: DATABASE_FILE_INTEGRITY
|
||||
weight: 0.40
|
||||
options:
|
||||
node_hostname: database_server
|
||||
folder_name: database
|
||||
file_name: database.db
|
||||
blue_agent:
|
||||
# actions, observations, and agent settings go here
|
||||
reward_function:
|
||||
reward_components:
|
||||
|
||||
# When the database file is in a good state, blue's reward is 0.4, when it's in a corrupted state the reward is -0.4
|
||||
- type: DATABASE_FILE_INTEGRITY
|
||||
weight: 0.40
|
||||
options:
|
||||
node_hostname: database_server
|
||||
folder_name: database
|
||||
file_name: database.db
|
||||
|
||||
# The green's reward is added onto the blue's reward.
|
||||
- type: SHARED_REWARD
|
||||
weight: 1.0
|
||||
options:
|
||||
agent_name: client_2_green_user
|
||||
|
||||
# The green's reward is added onto the blue's reward.
|
||||
- type: SHARED_REWARD
|
||||
weight: 1.0
|
||||
options:
|
||||
agent_name: client_2_green_user
|
||||
```
|
||||
|
||||
When defining agent reward sharing, users must be careful to avoid circular references, as that would lead to an infinite calculation loop. PrimAITE will prevent circular dependencies and provide a helpful error message if they are detected in the yaml.
|
||||
|
||||
@@ -2,40 +2,44 @@
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| Name | Version | License | Description | URL |
|
||||
+===================+=========+====================================+=======================================================================================================+==============================================+
|
||||
| gymnasium | 0.28.1 | MIT License | A standard API for reinforcement learning and a diverse set of reference environments (formerly Gym). | https://farama.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| ipywidgets | 8.1.3 | BSD License | Jupyter interactive widgets | http://jupyter.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| jupyterlab | 3.6.1 | BSD License | JupyterLab computational environment | https://jupyter.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| kaleido | 0.2.1 | MIT | Static image export for web-based visualization libraries with zero dependencies | https://github.com/plotly/Kaleido |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| matplotlib | 3.7.1 | Python Software Foundation License | Python plotting package | https://matplotlib.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| networkx | 3.1 | BSD License | Python package for creating and manipulating graphs and networks | https://networkx.org/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| numpy | 1.23.5 | BSD License | NumPy is the fundamental package for array computing with Python. | https://www.numpy.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| platformdirs | 3.5.1 | MIT License | A small Python package for determining appropriate platform-specific dirs, e.g. a "user data dir". | https://github.com/platformdirs/platformdirs |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| plotly | 5.15.0 | MIT License | An open-source, interactive data visualization library for Python | https://plotly.com/python/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| polars | 0.18.4 | MIT License | Blazingly fast DataFrame library | https://www.pola.rs/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| prettytable | 3.8.0 | BSD License (BSD (3 clause)) | A simple Python library for easily displaying tabular data in a visually appealing ASCII table format | https://github.com/jazzband/prettytable |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| pydantic | 2.7.0 | MIT License | Data validation using Python type hints | https://github.com/pydantic/pydantic |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| PyYAML | 6.0 | MIT License | YAML parser and emitter for Python | https://pyyaml.org/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| ray | 2.23.0 | Apache 2.0 | Ray provides a simple, universal API for building distributed applications. | https://github.com/ray-project/ray |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| stable-baselines3 | 2.1.0 | MIT | Pytorch version of Stable Baselines, implementations of reinforcement learning algorithms. | https://github.com/DLR-RM/stable-baselines3 |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| tensorflow | 2.12.0 | Apache Software License | TensorFlow is an open source machine learning framework for everyone. | https://www.tensorflow.org/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
| typer | 0.9.0 | MIT License | Typer, build great CLIs. Easy to code. Based on Python type hints. | https://github.com/tiangolo/typer |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+----------------------------------------------+
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| Name | Version | License | Description | URL |
|
||||
+===================+=========+====================================+=======================================================================================================+====================================================================+
|
||||
| gymnasium | 0.28.1 | MIT License | A standard API for reinforcement learning and a diverse set of reference environments (formerly Gym). | https://farama.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| ipywidgets | 8.1.3 | BSD License | Jupyter interactive widgets | http://jupyter.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| jupyterlab | 3.6.1 | BSD License | JupyterLab computational environment | https://jupyter.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| kaleido | 0.2.1 | MIT | Static image export for web-based visualization libraries with zero dependencies | https://github.com/plotly/Kaleido |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| matplotlib | 3.7.1 | Python Software Foundation License | Python plotting package | https://matplotlib.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| networkx | 3.1 | BSD License | Python package for creating and manipulating graphs and networks | https://networkx.org/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| numpy | 1.23.5 | BSD License | NumPy is the fundamental package for array computing with Python. | https://www.numpy.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| platformdirs | 3.5.1 | MIT License | A small Python package for determining appropriate platform-specific dirs, e.g. a "user data dir". | https://github.com/platformdirs/platformdirs |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| plotly | 5.15.0 | MIT License | An open-source, interactive data visualization library for Python | https://plotly.com/python/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| polars | 0.18.4 | MIT License | Blazingly fast DataFrame library | https://www.pola.rs/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| prettytable | 3.8.0 | BSD License (BSD (3 clause)) | A simple Python library for easily displaying tabular data in a visually appealing ASCII table format | https://github.com/jazzband/prettytable |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| pydantic | 2.7.0 | MIT License | Data validation using Python type hints | https://github.com/pydantic/pydantic |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| PyYAML | 6.0 | MIT License | YAML parser and emitter for Python | https://pyyaml.org/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| ray | 2.23.0 | Apache 2.0 | Ray provides a simple, universal API for building distributed applications. | https://github.com/ray-project/ray |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| stable-baselines3 | 2.1.0 | MIT | Pytorch version of Stable Baselines, implementations of reinforcement learning algorithms. | https://github.com/DLR-RM/stable-baselines3 |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| tensorflow | 2.12.0 | Apache Software License | TensorFlow is an open source machine learning framework for everyone. | https://www.tensorflow.org/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| typer | 0.9.0 | MIT License | Typer, build great CLIs. Easy to code. Based on Python type hints. | https://github.com/tiangolo/typer |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| Deepdiff | 7.0.1 | MIT License | Deep difference of dictionaries, iterables, strings, and any other object objects. | https://github.com/seperman/deepdiff |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| sb3_contrib | 2.3.0 | MIT License | Contrib package for Stable-Baselines3 - Experimental reinforcement learning (RL) code (Action Masking)| https://github.com/Stable-Baselines-Team/stable-baselines3-contrib |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
|
||||
@@ -9,49 +9,55 @@ Request System
|
||||
|
||||
Just like other aspects of SimComponent, the request types 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 in the simulation. This is achieved in the following way:
|
||||
|
||||
- API
|
||||
When requesting an action within the simulation, these two arguments must be provided:
|
||||
When requesting an action within the simulation, these two arguments must be provided:
|
||||
|
||||
1. ``request`` - selects which action you want to take on this ``SimComponent``. This is formatted as a list of strings such as ``['network', 'node', '<node-name>', 'service', '<service-name>', 'restart']``.
|
||||
2. ``context`` - optional extra information that can be used to decide how to process the request. This is formatted as a dictionary. For example, if the request 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', '<node-name>', 'service', '<service-name>', 'restart']``.
|
||||
2. ``context`` - optional extra information that can be used to decide how to process the request. This is formatted as a dictionary. For example, if the request requires authentication, the context can include information about the user that initiated the request to decide if their permissions are sufficient.
|
||||
|
||||
When a request is resolved, it returns a success status, and optional additional data about the request.
|
||||
When a request is resolved, it returns a success status, and optional additional data about the request.
|
||||
|
||||
``status`` can be one of:
|
||||
``status`` can be one of:
|
||||
|
||||
* ``success``: the request was executed
|
||||
* ``failure``: the request could not be executed
|
||||
* ``unreachable``: the target for the request was not found
|
||||
* ``pending``: the request was initiated, but has not finished during this step
|
||||
* ``success``: the request was executed
|
||||
* ``failure``: the request could not be executed
|
||||
* ``unreachable``: the target for the request was not found
|
||||
* ``pending``: the request was initiated, but has not finished during this step
|
||||
|
||||
``data`` can be a dictionary with any arbitrary JSON-like data to describe the outcome of the request.
|
||||
``data`` can be a dictionary with any arbitrary JSON-like data to describe the outcome of the request.
|
||||
|
||||
- ``request`` detail
|
||||
The request is a list of strings which help specify who should handle the request. The strings in the request list help RequestManagers traverse the 'ownership tree' of SimComponent. The example given above would be handled in the following way:
|
||||
Requests:
|
||||
"""""""""
|
||||
|
||||
1. ``Simulation`` receives ``['network', 'node', 'computer_1', 'service', 'DNSService', 'restart']``.
|
||||
The first element of the request is ``network``, therefore it passes the request down to its network.
|
||||
2. ``Network`` receives ``['node', 'computer_1', 'service', 'DNSService', 'restart']``.
|
||||
The first element of the request is ``node``, therefore the network looks at the node name and passes the request down to the node with that name.
|
||||
3. ``computer_1`` receives ``['service', 'DNSService', 'restart']``.
|
||||
The first element of the request is ``service``, therefore the node looks at the service name and passes the rest of the request to the service with that name.
|
||||
4. ``DNSService`` receives ``['restart']``.
|
||||
Since ``restart`` is a defined request type in the service's own RequestManager, the service performs a restart.
|
||||
Request Syntax
|
||||
---------------
|
||||
|
||||
- ``context`` detail
|
||||
The request is a list of strings which help specify who should handle the request. The strings in the request list help RequestManagers traverse the 'ownership tree' of SimComponent. The example given above would be handled in the following way:
|
||||
|
||||
1. ``Simulation`` receives ``['network', 'node', 'computer_1', 'service', 'DNSService', 'restart']``.
|
||||
The first element of the request is ``network``, therefore it passes the request down to its network.
|
||||
2. ``Network`` receives ``['node', 'computer_1', 'service', 'DNSService', 'restart']``.
|
||||
The first element of the request is ``node``, therefore the network looks at the node name and passes the request down to the node with that name.
|
||||
3. ``computer_1`` receives ``['service', 'DNSService', 'restart']``.
|
||||
The first element of the request is ``service``, therefore the node looks at the service name and passes the rest of the request to the service with that name.
|
||||
4. ``DNSService`` receives ``['restart']``.
|
||||
Since ``restart`` is a defined request type in the service's own RequestManager, the service performs a restart.
|
||||
|
||||
- ``context``
|
||||
The context is not used by any of the currently implemented components or requests.
|
||||
|
||||
- Request response
|
||||
When the simulator receives a request, it returns a response with a success status. The possible statuses are:
|
||||
Request responses
|
||||
-----------------
|
||||
|
||||
* **success**: The request was received and successfully executed.
|
||||
* For example, the agent tries to add an ACL rule and specifies correct parameters, and the ACL rule is added successfully.
|
||||
When the simulator receives a request, it returns a response with a success status. The possible statuses are:
|
||||
|
||||
* **failure**: The request was received, but it could not be executed, or it failed while executing.
|
||||
* For example, the agent tries to execute the ``WebBrowser`` application, but the webpage wasn't retrieved because the DNS server is not setup on the node.
|
||||
* **success**: The request was received and successfully executed.
|
||||
* For example, the agent tries to add an ACL rule and specifies correct parameters, and the ACL rule is added successfully.
|
||||
|
||||
* **unreachable**: The request was sent to a simulation component that does not exist.
|
||||
* For example, the agent tries to scan a file that has not been created yet.
|
||||
* **failure**: The request was received, but it could not be executed, or it failed while executing.
|
||||
* For example, the agent tries to execute the ``WebBrowser`` application, but the webpage wasn't retrieved because the DNS server is not setup on the node.
|
||||
|
||||
* **unreachable**: The request was sent to a simulation component that does not exist.
|
||||
* For example, the agent tries to scan a file that has not been created yet.
|
||||
|
||||
For more information, please refer to the ``Requests-and-Responses.ipynb`` jupyter notebook
|
||||
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
DoSBot
|
||||
######
|
||||
|
||||
The ``DoSBot`` is an implementation of a Denial of Service attack within the PrimAITE simulation. This specifically simulates a `Slow Loris attack <https://en.wikipedia.org/wiki/Slowloris_(computer_security)>`.
|
||||
The ``DoSBot`` is an implementation of a Denial of Service attack within the PrimAITE simulation.
|
||||
This specifically simulates a `Slow Loris attack`_.
|
||||
|
||||
.. _Slow Loris Attack: https://en.wikipedia.org/wiki/Slowloris_(computer_security)
|
||||
|
||||
Key features
|
||||
============
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
.. _NMAP:
|
||||
|
||||
NMAP
|
||||
====
|
||||
####
|
||||
|
||||
Overview
|
||||
--------
|
||||
========
|
||||
|
||||
The NMAP application is used to simulate network scanning activities. NMAP is a powerful tool that helps in discovering
|
||||
hosts and services on a network. It provides functionalities such as ping scans to discover active hosts and port scans
|
||||
@@ -19,8 +19,8 @@ structure, identify active devices, and find potential vulnerabilities by discov
|
||||
However, it is also a tool frequently used by attackers during the reconnaissance stage of a cyber attack to gather
|
||||
information about the target network.
|
||||
|
||||
Scan Types
|
||||
----------
|
||||
Scan Type
|
||||
=========
|
||||
|
||||
Ping Scan
|
||||
^^^^^^^^^
|
||||
@@ -46,7 +46,7 @@ identifying potential entry points for attacks. There are three types of port sc
|
||||
It gives a comprehensive view of the network's service landscape.
|
||||
|
||||
Example Usage
|
||||
-------------
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
The network we use for these examples is defined below:
|
||||
|
||||
@@ -345,3 +345,11 @@ Perform a full box scan on all ports, over both TCP and UDP, on a whole subnet:
|
||||
| 192.168.1.13 | 123 | NTP | UDP |
|
||||
| 192.168.1.13 | 219 | ARP | UDP |
|
||||
+--------------+------+-----------------+----------+
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
.. include:: ../common/common_configuration.rst
|
||||
|
||||
.. |SOFTWARE_NAME| replace:: NMAP
|
||||
.. |SOFTWARE_NAME_BACKTICK| replace:: ``NMAP``
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _RansomwareScript:
|
||||
|
||||
RansomwareScript
|
||||
###################
|
||||
|
||||
The RansomwareScript class provides functionality to connect to a :ref:`DatabaseService` and set a database's database.db into a ``CORRUPTED`` state.
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The ransomware script intends to simulate a generic implementation of ransomware.
|
||||
|
||||
Currently, due to simulation restraints, the ransomware script is unable to attack a host without an active database service.
|
||||
|
||||
The ransomware script is similar to that of the data_manipulation_bot but does not have any separate stages or configurable probabilities.
|
||||
|
||||
Additionally, similar to the data_manipulation_bot, the ransomware script must be installed on a host with a pre-existing :ref:`DatabaseClient` application installed.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
- Create an instance and call ``configure`` to set:
|
||||
- Target Database IP
|
||||
- Database password (if needed)
|
||||
- Call ``Execute`` to connect and execute the ransomware script.
|
||||
|
||||
This application handles connections to the database server and the connection made to encrypt the database but it does not handle disconnections.
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
Currently, the ransomware script connects to a :ref:`DatabaseClient` and leverages its connectivity. The host running ``RansomwareScript`` must also have a :ref:`DatabaseClient` installed on it.
|
||||
|
||||
- Uses the Application base class for lifecycle management.
|
||||
- Target IP and other options set via ``configure``.
|
||||
- ``execute`` handles connecting and encrypting.
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
Python
|
||||
""""""
|
||||
.. code-block:: python
|
||||
|
||||
from primaite.simulator.network.hardware.nodes.host.computer import Computer
|
||||
from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState
|
||||
from primaite.simulator.system.applications.red_applications.RansomwareScript import RansomwareScript
|
||||
from primaite.simulator.system.applications.database_client import DatabaseClient
|
||||
|
||||
client_1 = Computer(
|
||||
hostname="client_1",
|
||||
ip_address="192.168.10.21",
|
||||
subnet_mask="255.255.255.0",
|
||||
default_gateway="192.168.10.1",
|
||||
operating_state=NodeOperatingState.ON # initialise the computer in an ON state
|
||||
)
|
||||
network.connect(endpoint_b=client_1.network_interface[1], endpoint_a=switch_2.network_interface[1])
|
||||
client_1.software_manager.install(DatabaseClient)
|
||||
client_1.software_manager.install(RansomwareScript)
|
||||
RansomwareScript: RansomwareScript = client_1.software_manager.software.get("RansomwareScript")
|
||||
RansomwareScript.configure(server_ip_address=IPv4Address("192.168.1.14"))
|
||||
RansomwareScript.execute()
|
||||
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
The RansomwareScript inherits configuration options such as ``fix_duration`` from its parent class. However, for the ``RansomwareScript`` the most relevant option is ``server_ip``.
|
||||
|
||||
.. include:: ../common/common_configuration.rst
|
||||
|
||||
.. |SOFTWARE_NAME| replace:: RansomwareScript
|
||||
.. |SOFTWARE_NAME_BACKTICK| replace:: ``RansomwareScript``
|
||||
|
||||
``server_ip``
|
||||
"""""""""""""
|
||||
|
||||
IP address of the :ref:`DatabaseService` which the ``RansomwareScript`` will encrypt.
|
||||
|
||||
This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``.
|
||||
@@ -23,7 +23,7 @@ Usage
|
||||
=====
|
||||
|
||||
- Install on a Node via the ``SoftwareManager`` to start the ``WebBrowser``.
|
||||
- Service runs on HTTP port 80 by default. (TODO: HTTPS)
|
||||
- Service runs on HTTP port 80 by default.
|
||||
- Execute sending an HTTP GET request with ``get_webpage``
|
||||
|
||||
Implementation
|
||||
|
||||
@@ -87,5 +87,3 @@ Configuration
|
||||
|
||||
.. |SOFTWARE_NAME| replace:: FTPClient
|
||||
.. |SOFTWARE_NAME_BACKTICK| replace:: ``FTPClient``
|
||||
|
||||
**FTPClient has no configuration options**
|
||||
|
||||
@@ -82,5 +82,3 @@ Configuration
|
||||
|
||||
.. |SOFTWARE_NAME| replace:: NTPServer
|
||||
.. |SOFTWARE_NAME_BACKTICK| replace:: ``NTPServer``
|
||||
|
||||
**NTPServer has no configuration options**
|
||||
|
||||
@@ -82,5 +82,3 @@ Configuration
|
||||
|
||||
.. |SOFTWARE_NAME| replace:: WebServer
|
||||
.. |SOFTWARE_NAME_BACKTICK| replace:: ``WebServer``
|
||||
|
||||
**WebServer has no configuration options**
|
||||
|
||||
@@ -15,7 +15,7 @@ when a component's ``describe_state()`` method is called, it will include the st
|
||||
``apply_request()`` method can be used to act on a component or one of its descendants. The diagram below shows the
|
||||
relationship between components.
|
||||
|
||||
.. image:: ../../_static/component_relationship.png
|
||||
.. image:: ../_static/component_relationship.png
|
||||
:width: 500
|
||||
:align: center
|
||||
:alt: :: The top level simulation object owns a NetworkContainer and a DomainController. The DomainController has a
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
|
||||
Defining variations in the config files
|
||||
================
|
||||
=======================================
|
||||
|
||||
PrimAITE supports the ability to use different variations on a scenario at different episodes. This can be used to increase domain randomisation to prevent overfitting, or to set up curriculum learning to train agents to perform more complicated tasks.
|
||||
|
||||
@@ -15,7 +15,7 @@ Base scenario
|
||||
|
||||
The base scenario is essentially the same as a fixed YAML configuration, but it can contain placeholders that are populated with episode-specific data at runtime. The base scenario contains any network, agent, or settings that remain fixed for the entire training/evaluation session.
|
||||
|
||||
The placeholders are defined as YAML Aliases and they are denoted by an asterisk (*placeholder).
|
||||
The placeholders are defined as YAML Aliases and they are denoted by an asterisk (* *placeholder*)
|
||||
|
||||
Variations
|
||||
**********
|
||||
@@ -46,4 +46,4 @@ It takes the following format:
|
||||
|
||||
For more information please refer to the ``Using Episode Schedules`` notebook in either :ref:`Executed Notebooks` or run the notebook interactively in ``notebooks/example_notebooks/``.
|
||||
|
||||
For further information around notebooks in general refer to the :ref:`Example Jupyter Notebooks`.
|
||||
For further information around notebooks in general refer to the :ref:`example_notebooks` page.
|
||||
|
||||
@@ -1 +1 @@
|
||||
3.3.0-dev0
|
||||
3.2.0
|
||||
|
||||
@@ -8,6 +8,7 @@ weighed sum of the components.
|
||||
|
||||
The reward function is typically specified using a config yaml file or a config dictionary. The following example shows
|
||||
the structure:
|
||||
|
||||
```yaml
|
||||
reward_function:
|
||||
reward_components:
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
"source": [
|
||||
"# Action Masking\n",
|
||||
"\n",
|
||||
"© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK\n",
|
||||
"\n",
|
||||
"PrimAITE environments support action masking. The action mask shows which of the agent's actions are applicable with the current environment state. For example, a node can only be turned on if it is currently turned off."
|
||||
]
|
||||
},
|
||||
@@ -210,7 +212,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.12"
|
||||
"version": "3.10.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -76,7 +76,7 @@ def config_callback(
|
||||
LogLevel,
|
||||
typer.Option(
|
||||
"--sys-log-level",
|
||||
"-level",
|
||||
"-slevel",
|
||||
click_type=click.Choice(LogLevel._member_names_, case_sensitive=False),
|
||||
help="The level of system logs to output.",
|
||||
show_default=False,
|
||||
@@ -86,7 +86,7 @@ def config_callback(
|
||||
LogLevel,
|
||||
typer.Option(
|
||||
"--agent-log-level",
|
||||
"-level",
|
||||
"-alevel",
|
||||
click_type=click.Choice(LogLevel._member_names_, case_sensitive=False),
|
||||
help="The level of agent behaviour logs to output.",
|
||||
show_default=False,
|
||||
|
||||
@@ -67,7 +67,7 @@ def test_dev_mode_config_sys_log_level():
|
||||
# check defaults
|
||||
assert PRIMAITE_CONFIG["developer_mode"]["sys_log_level"] == "DEBUG" # DEBUG by default
|
||||
|
||||
result = cli(["dev-mode", "config", "--sys-log-level", "WARNING"])
|
||||
result = cli(["dev-mode", "config", "-slevel", "WARNING"])
|
||||
|
||||
assert "sys_log_level=WARNING" in result.output # should print correct value
|
||||
|
||||
@@ -87,7 +87,7 @@ def test_dev_mode_config_agent_log_level():
|
||||
# check defaults
|
||||
assert PRIMAITE_CONFIG["developer_mode"]["agent_log_level"] == "DEBUG" # DEBUG by default
|
||||
|
||||
result = cli(["dev-mode", "config", "-level", "WARNING"])
|
||||
result = cli(["dev-mode", "config", "-alevel", "WARNING"])
|
||||
|
||||
assert "agent_log_level=WARNING" in result.output # should print correct value
|
||||
|
||||
|
||||
Reference in New Issue
Block a user