#2682 Backport changes to core PrimAITE
This commit is contained in:
4
.github/workflows/build-sphinx.yml
vendored
4
.github/workflows/build-sphinx.yml
vendored
@@ -1,8 +1,8 @@
|
||||
name: build-sphinx-to-github-pages
|
||||
|
||||
env:
|
||||
GITHUB_ACTOR: Autonomous-Resilient-Cyber-Defence
|
||||
GITHUB_REPOSITORY: Autonomous-Resilient-Cyber-Defence/PrimAITE
|
||||
GITHUB_ACTOR: {todo:fill in URL}
|
||||
GITHUB_REPOSITORY: {todo:fill in URL}/PrimAITE
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN}}
|
||||
|
||||
on:
|
||||
|
||||
11
.github/workflows/python-package.yml
vendored
11
.github/workflows/python-package.yml
vendored
@@ -5,13 +5,11 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- dev
|
||||
- dev-gui
|
||||
- 'release/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- dev
|
||||
- dev-gui
|
||||
- 'release/**'
|
||||
jobs:
|
||||
build:
|
||||
@@ -19,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.8", "3.9", "3.10"]
|
||||
python-version: ["3.9", "3.10", "3.11"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -54,13 +52,6 @@ jobs:
|
||||
run: |
|
||||
primaite setup
|
||||
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
# exit-zero treats all errors as warnings.
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=120 --statistics
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
pytest tests/
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -148,7 +148,7 @@ cython_debug/
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
docs/source/primaite-dependencies.rst
|
||||
|
||||
.vscode/
|
||||
|
||||
# outputs
|
||||
|
||||
@@ -10,10 +10,8 @@ repos:
|
||||
hooks:
|
||||
- id: check-yaml
|
||||
exclude: |
|
||||
(?x)^(
|
||||
.*/scenario_with_placeholders/.*|
|
||||
.*/mini_scenario_with_simulation_variation/.*
|
||||
)$
|
||||
| scenario_with_placeholders/
|
||||
| mini_scenario_with_simulation_variation/
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- id: check-added-large-files
|
||||
|
||||
@@ -4,20 +4,20 @@
|
||||
### **Did you find a bug?**
|
||||
|
||||
|
||||
* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE/issues).
|
||||
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE/issues/new?assignees=&labels=bug&projects=&template=bug_report.md&title=%5BBUG%5D+-+%3Cbug+title+goes+here%3E). Be sure to follow our bug report template with the headers **Describe the bug**, **To Reproduce**, **Expected behaviour**, **Screenshots/Outputs**, **Environment**, and **Additional context**
|
||||
* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/{todo:fill in URL}/PrimAITE/issues).
|
||||
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/{todo:fill in URL}/PrimAITE/issues/new?assignees=&labels=bug&projects=&template=bug_report.md&title=%5BBUG%5D+-+%3Cbug+title+goes+here%3E). Be sure to follow our bug report template with the headers **Describe the bug**, **To Reproduce**, **Expected behaviour**, **Screenshots/Outputs**, **Environment**, and **Additional context**
|
||||
|
||||
|
||||
### **Do you have a solution to fix the bug?**
|
||||
|
||||
* [Fork the repository](https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE/fork).
|
||||
* [Fork the repository](https://github.com/{todo:fill in URL}/PrimAITE/fork).
|
||||
* Install the pre-commit hook with `pre-commit install`.
|
||||
* Implement the bug fix.
|
||||
* Update documentation where applicable.
|
||||
* Update the **UNRELEASED** section of the [CHANGELOG.md](CHANGELOG.md) file
|
||||
* Write a suitable test/tests.
|
||||
* Commit the bug fix to the dev branch on your fork. If the bug has an open issue under [Issues](https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE/issues), reference the issue in the commit message (e.g. #1 references issue 1).
|
||||
* Submit a pull request from your dev branch to the Autonomous-Resilient-Cyber-Defence/PrimAITE dev branch. Again, if the bug has an open issue under [Issues](https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE/issues), reference the issue in the pull request description.
|
||||
* Commit the bug fix to the dev branch on your fork. If the bug has an open issue under [Issues](https://github.com/{todo:fill in URL}/PrimAITE/issues), reference the issue in the commit message (e.g. #1 references issue 1).
|
||||
* Submit a pull request from your dev branch to the {todo:fill in URL}/PrimAITE dev branch. Again, if the bug has an open issue under [Issues](https://github.com/{todo:fill in URL}/PrimAITE/issues), reference the issue in the pull request description.
|
||||
|
||||
### **Did you fix whitespace, format code, or make a purely cosmetic patch?**
|
||||
|
||||
@@ -25,7 +25,7 @@ Changes that are cosmetic in nature and do not add anything substantial to the s
|
||||
|
||||
### **Do you intend to add a new feature or change an existing one?**
|
||||
|
||||
* Submit a [feature request issue](https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE/issues/new?assignees=&labels=feature_request&projects=&template=feature_request.md&title=%5BREQUEST%5D+-+%3Crequest+title+goes+here%3E).
|
||||
* Submit a [feature request issue](https://github.com/{todo:fill in URL}/PrimAITE/issues/new?assignees=&labels=feature_request&projects=&template=feature_request.md&title=%5BREQUEST%5D+-+%3Crequest+title+goes+here%3E).
|
||||
* Know how to implement the new feature or change? Follow the same steps in the bug fix section above to fork, build, document, test, commit, and submit a pull request.
|
||||
|
||||
### **Do you have questions about the source code?**
|
||||
|
||||
22
LICENSE
22
LICENSE
@@ -1,21 +1,27 @@
|
||||
MIT License
|
||||
MIT License License
|
||||
|
||||
Copyright (c) 2023 - 2025 Defence Science and Technology Laboratory UK (https://dstl.gov.uk)
|
||||
MIT License Conditions
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
These MIT License conditions confirm the provision of the following artefacts as MIT License by Defence Science and Technology
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
request to the QQ or FNC mailbox):
|
||||
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
- Use Case Release Packs
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
Suppliers are required to read and confirm acceptance of the {todo:fill in URL} Foundry SyOPs (https://github.com/{todo:fill in URL}/foundry-syops) before being admitted access to material hosted on the {todo:fill in URL} Foundry GitHub site.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
|
||||
The material is supplied in confidence to QQ / FNC and their subcontractors under SERAPIS, and is issued to inform only those
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
of DSTL. The material must be stored and protected appropriately. All material must be destroyed at the end of the task.
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ Currently, the PrimAITE wheel can only be installed from GitHub. This may change
|
||||
#### Windows (PowerShell)
|
||||
|
||||
**Prerequisites:**
|
||||
* Manual install of Python >= 3.8 < 3.12
|
||||
* Manual install of Python >= 3.9 < 3.12
|
||||
|
||||
**Install:**
|
||||
|
||||
@@ -43,7 +43,7 @@ cd ~\primaite
|
||||
python3 -m venv .venv
|
||||
attrib +h .venv /s /d # Hides the .venv directory
|
||||
.\.venv\Scripts\activate
|
||||
pip install primaite-3.0.0-py3-none-any.whl[rl]
|
||||
pip install primaite-{VERSION}-py3-none-any.whl[rl]
|
||||
primaite setup
|
||||
```
|
||||
|
||||
@@ -66,7 +66,7 @@ mkdir ~/primaite
|
||||
cd ~/primaite
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install primaite-3.0.0-py3-none-any.whl[rl]
|
||||
pip install primaite-{VERSION}-py3-none-any.whl[rl]
|
||||
primaite setup
|
||||
```
|
||||
|
||||
@@ -77,7 +77,7 @@ To make your own changes to PrimAITE, perform the install from source (developer
|
||||
|
||||
#### 1. Clone the PrimAITE repository
|
||||
``` unix
|
||||
git clone git@github.com:Autonomous-Resilient-Cyber-Defence/PrimAITE.git
|
||||
git clone git@github.com:{todo:fill in URL}/PrimAITE.git
|
||||
```
|
||||
|
||||
#### 2. CD into the repo directory
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
# Minimal makefile for Sphinx documentation
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
#!/bin/bash
|
||||
set -x
|
||||
|
||||
@@ -42,7 +43,7 @@ touch .nojekyll
|
||||
# Add README
|
||||
cat > README.md <<EOF
|
||||
# README for the Sphinx Docs GitHub Pages Branch
|
||||
This branch is simply a cache for the website served from https://Autonomous-Resilient-Cyber-Defence.github.io/PrimAITE/,
|
||||
This branch is simply a cache for the website served from https://{todo:fill in URL}.github.io/PrimAITE/,
|
||||
and is not intended to be viewed on github.com.
|
||||
For more information on how this site is built using Sphinx, Read the Docs, GitHub Actions/Pages, and demo
|
||||
implementation from https://github.com/annegentle, see:
|
||||
|
||||
@@ -147,7 +147,7 @@ def copy_notebooks_to_docs() -> Any:
|
||||
This allows developers to create new notebooks without having to worry about updating documentation when
|
||||
a new notebook is included within PrimAITE.
|
||||
"""
|
||||
notebook_asset_types = [".ipynb", ".png"]
|
||||
notebook_asset_types = [".ipynb", ".png", ".svg"]
|
||||
notebook_directories = []
|
||||
|
||||
# find paths where notebooks are contained
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@ECHO OFF
|
||||
REM © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
|
||||
@@ -77,6 +77,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.8 - 3.11
|
||||
VSCode will then ask for a Python environment version to use. PrimAITE is compatible with Python versions 3.9 - 3.11
|
||||
|
||||
You should now be able to interact with the notebook.
|
||||
|
||||
@@ -85,7 +85,6 @@ blue_agent:
|
||||
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.
|
||||
|
||||
@@ -113,7 +113,7 @@ For example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git clone https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE
|
||||
git clone https://github.com/{todo:fill in URL}/PrimAITE
|
||||
cd primaite
|
||||
|
||||
2. Create and activate your Python virtual environment (venv)
|
||||
|
||||
@@ -7,17 +7,15 @@ name = "primaite"
|
||||
description = "PrimAITE (Primary-level AI Training Environment) is a simulation environment for training AI under the ARCD programme."
|
||||
authors = [{name="Defence Science and Technology Laboratory UK", email="oss@dstl.gov.uk"}]
|
||||
license = {file = "LICENSE"}
|
||||
requires-python = ">=3.8, <3.12"
|
||||
requires-python = ">=3.9, <3.12"
|
||||
dynamic = ["version", "readme"]
|
||||
classifiers = [
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Operating System :: Microsoft :: Windows",
|
||||
"Operating System :: MacOS",
|
||||
"Operating System :: POSIX :: Linux",
|
||||
"Operating System :: Unix",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
@@ -91,7 +89,7 @@ order_by_type = "False"
|
||||
line-length = 120
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE"
|
||||
Documentation = "https://Autonomous-Resilient-Cyber-Defence.github.io/PrimAITE/"
|
||||
Repository = "https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE"
|
||||
Changelog = "https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE/blob/dev/CHANGELOG.md"
|
||||
Homepage = "https://github.com/{todo:fill in URL}/PrimAITE"
|
||||
Documentation = "https://{todo:fill in URL}.github.io/PrimAITE"
|
||||
Repository = "https://github.com/{todo:fill in URL}/PrimAITE"
|
||||
Changelog = "https://github.com/{todo:fill in URL}/PrimAITE/blob/main/CHANGELOG.md"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[metadata]
|
||||
url = https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE
|
||||
url = https://github.com/{todo:fill in URL}/PrimAITE
|
||||
author = Defence Science and Technology Laboratory UK
|
||||
author_email = oss@dstl.gov.uk
|
||||
|
||||
@@ -203,3 +203,6 @@ def getLogger(name: str) -> Logger: # noqa
|
||||
logger.setLevel(PRIMAITE_CONFIG["logging"]["log_level"])
|
||||
|
||||
return logger
|
||||
|
||||
|
||||
DEFAULT_BANDWIDTH: Final[int] = 100
|
||||
|
||||
@@ -476,7 +476,7 @@ agents:
|
||||
46: # old action num: 22 # "ACL: ADDRULE - Block outgoing traffic from client 1"
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -489,7 +489,7 @@ agents:
|
||||
47: # old action num: 23 # "ACL: ADDRULE - Block outgoing traffic from client 2"
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -502,7 +502,7 @@ agents:
|
||||
48: # old action num: 24 # block tcp traffic from client 1 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -515,7 +515,7 @@ agents:
|
||||
49: # old action num: 25 # block tcp traffic from client 2 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -528,7 +528,7 @@ agents:
|
||||
50: # old action num: 26
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -541,7 +541,7 @@ agents:
|
||||
51: # old action num: 27
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -554,52 +554,52 @@ agents:
|
||||
52: # old action num: 28
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 0
|
||||
53: # old action num: 29
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
54: # old action num: 30
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
55: # old action num: 31
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
56: # old action num: 32
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
57: # old action num: 33
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
58: # old action num: 34
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
59: # old action num: 35
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 7
|
||||
60: # old action num: 36
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 8
|
||||
61: # old action num: 37
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 9
|
||||
62: # old action num: 38
|
||||
action: "HOST_NIC_DISABLE"
|
||||
|
||||
@@ -470,7 +470,7 @@ agents:
|
||||
46: # old action num: 22 # "ACL: ADDRULE - Block outgoing traffic from client 1"
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -483,7 +483,7 @@ agents:
|
||||
47: # old action num: 23 # "ACL: ADDRULE - Block outgoing traffic from client 2"
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -496,7 +496,7 @@ agents:
|
||||
48: # old action num: 24 # block tcp traffic from client 1 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -509,7 +509,7 @@ agents:
|
||||
49: # old action num: 25 # block tcp traffic from client 2 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -522,7 +522,7 @@ agents:
|
||||
50: # old action num: 26
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -535,7 +535,7 @@ agents:
|
||||
51: # old action num: 27
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -548,52 +548,52 @@ agents:
|
||||
52: # old action num: 28
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 0
|
||||
53: # old action num: 29
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
54: # old action num: 30
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
55: # old action num: 31
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
56: # old action num: 32
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
57: # old action num: 33
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
58: # old action num: 34
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
59: # old action num: 35
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 7
|
||||
60: # old action num: 36
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 8
|
||||
61: # old action num: 37
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 9
|
||||
62: # old action num: 38
|
||||
action: "HOST_NIC_DISABLE"
|
||||
@@ -834,10 +834,10 @@ agents:
|
||||
- type: NODE_RESET
|
||||
- type: ROUTER_ACL_ADDRULE
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
- type: ROUTER_ACL_REMOVERULE
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
- type: HOST_NIC_ENABLE
|
||||
- type: HOST_NIC_DISABLE
|
||||
|
||||
@@ -1053,7 +1053,7 @@ agents:
|
||||
46: # old action num: 22 # "ACL: ADDRULE - Block outgoing traffic from client 1"
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -1066,7 +1066,7 @@ agents:
|
||||
47: # old action num: 23 # "ACL: ADDRULE - Block outgoing traffic from client 2"
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -1079,7 +1079,7 @@ agents:
|
||||
48: # old action num: 24 # block tcp traffic from client 1 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -1092,7 +1092,7 @@ agents:
|
||||
49: # old action num: 25 # block tcp traffic from client 2 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -1105,7 +1105,7 @@ agents:
|
||||
50: # old action num: 26
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -1118,7 +1118,7 @@ agents:
|
||||
51: # old action num: 27
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -1131,52 +1131,52 @@ agents:
|
||||
52: # old action num: 28
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 0
|
||||
53: # old action num: 29
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
54: # old action num: 30
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
55: # old action num: 31
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
56: # old action num: 32
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
57: # old action num: 33
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
58: # old action num: 34
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
59: # old action num: 35
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 7
|
||||
60: # old action num: 36
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 8
|
||||
61: # old action num: 37
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 9
|
||||
62: # old action num: 38
|
||||
action: "HOST_NIC_DISABLE"
|
||||
|
||||
@@ -11,9 +11,10 @@ AbstractAction. The ActionManager is responsible for:
|
||||
"""
|
||||
import itertools
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Dict, List, Optional, Tuple, TYPE_CHECKING, Union
|
||||
from typing import Dict, List, Literal, Optional, Tuple, TYPE_CHECKING, Union
|
||||
|
||||
from gymnasium import spaces
|
||||
from pydantic import BaseModel, Field, field_validator, ValidationInfo
|
||||
|
||||
from primaite import getLogger
|
||||
|
||||
@@ -321,12 +322,12 @@ class NodeFileCreateAction(AbstractAction):
|
||||
super().__init__(manager, num_nodes=num_nodes, num_folders=num_folders, **kwargs)
|
||||
self.verb: str = "create"
|
||||
|
||||
def form_request(self, node_id: int, folder_name: str, file_name: str) -> List[str]:
|
||||
def form_request(self, node_id: int, folder_name: str, file_name: str, force: Optional[bool] = False) -> List[str]:
|
||||
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
|
||||
node_name = self.manager.get_node_name_by_idx(node_id)
|
||||
if node_name is None or folder_name is None or file_name is None:
|
||||
return ["do_nothing"]
|
||||
return ["network", "node", node_name, "file_system", "create", "file", folder_name, file_name]
|
||||
return ["network", "node", node_name, "file_system", "create", "file", folder_name, file_name, force]
|
||||
|
||||
|
||||
class NodeFolderCreateAction(AbstractAction):
|
||||
@@ -493,6 +494,47 @@ class NodeResetAction(NodeAbstractAction):
|
||||
class RouterACLAddRuleAction(AbstractAction):
|
||||
"""Action which adds a rule to a router's ACL."""
|
||||
|
||||
class ACLRuleOptions(BaseModel):
|
||||
"""Validator for ACL_ADD_RULE options."""
|
||||
|
||||
target_router: str
|
||||
"""On which router to add the rule, must be specified."""
|
||||
position: int
|
||||
"""At what position to add the rule, must be specified."""
|
||||
permission: Literal[1, 2]
|
||||
"""Whether to allow or deny traffic, must be specified. 1 = PERMIT, 2 = DENY."""
|
||||
source_ip_id: int = Field(default=1, ge=1)
|
||||
"""Rule source IP address. By default, all ip addresses."""
|
||||
source_wildcard_id: int = Field(default=0, ge=0)
|
||||
"""Rule source IP wildcard. By default, use the wildcard at index 0 from action manager."""
|
||||
source_port_id: int = Field(default=1, ge=1)
|
||||
"""Rule source port. By default, all source ports."""
|
||||
dest_ip_id: int = Field(default=1, ge=1)
|
||||
"""Rule destination IP address. By default, all ip addresses."""
|
||||
dest_wildcard_id: int = Field(default=0, ge=0)
|
||||
"""Rule destination IP wildcard. By default, use the wildcard at index 0 from action manager."""
|
||||
dest_port_id: int = Field(default=1, ge=1)
|
||||
"""Rule destination port. By default, all destination ports."""
|
||||
protocol_id: int = Field(default=1, ge=1)
|
||||
"""Rule protocol. By default, all protocols."""
|
||||
|
||||
@field_validator(
|
||||
"source_ip_id",
|
||||
"source_port_id",
|
||||
"source_wildcard_id",
|
||||
"dest_ip_id",
|
||||
"dest_port_id",
|
||||
"dest_wildcard_id",
|
||||
"protocol_id",
|
||||
mode="before",
|
||||
)
|
||||
@classmethod
|
||||
def not_none(cls, v: str, info: ValidationInfo) -> int:
|
||||
"""If None is passed, use the default value instead."""
|
||||
if v is None:
|
||||
return cls.model_fields[info.field_name].default
|
||||
return v
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
manager: "ActionManager",
|
||||
@@ -529,7 +571,7 @@ class RouterACLAddRuleAction(AbstractAction):
|
||||
|
||||
def form_request(
|
||||
self,
|
||||
target_router_nodename: str,
|
||||
target_router: str,
|
||||
position: int,
|
||||
permission: int,
|
||||
source_ip_id: int,
|
||||
@@ -541,62 +583,63 @@ class RouterACLAddRuleAction(AbstractAction):
|
||||
protocol_id: int,
|
||||
) -> List[str]:
|
||||
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
|
||||
if permission == 0:
|
||||
permission_str = "UNUSED"
|
||||
return ["do_nothing"] # NOT SUPPORTED, JUST DO NOTHING IF WE COME ACROSS THIS
|
||||
elif permission == 1:
|
||||
# Validate incoming data.
|
||||
parsed_options = RouterACLAddRuleAction.ACLRuleOptions(
|
||||
target_router=target_router,
|
||||
position=position,
|
||||
permission=permission,
|
||||
source_ip_id=source_ip_id,
|
||||
source_wildcard_id=source_wildcard_id,
|
||||
dest_ip_id=dest_ip_id,
|
||||
dest_wildcard_id=dest_wildcard_id,
|
||||
source_port_id=source_port_id,
|
||||
dest_port_id=dest_port_id,
|
||||
protocol_id=protocol_id,
|
||||
)
|
||||
if parsed_options.permission == 1:
|
||||
permission_str = "PERMIT"
|
||||
elif permission == 2:
|
||||
elif parsed_options.permission == 2:
|
||||
permission_str = "DENY"
|
||||
else:
|
||||
_LOGGER.warning(f"{self.__class__} received permission {permission}, expected 0 or 1.")
|
||||
|
||||
if protocol_id == 0:
|
||||
return ["do_nothing"] # NOT SUPPORTED, JUST DO NOTHING IF WE COME ACROSS THIS
|
||||
|
||||
if protocol_id == 1:
|
||||
if parsed_options.protocol_id == 1:
|
||||
protocol = "ALL"
|
||||
else:
|
||||
protocol = self.manager.get_internet_protocol_by_idx(protocol_id - 2)
|
||||
protocol = self.manager.get_internet_protocol_by_idx(parsed_options.protocol_id - 2)
|
||||
# subtract 2 to account for UNUSED=0 and ALL=1.
|
||||
|
||||
if source_ip_id == 0:
|
||||
return ["do_nothing"] # invalid formulation
|
||||
elif source_ip_id == 1:
|
||||
if parsed_options.source_ip_id == 1:
|
||||
src_ip = "ALL"
|
||||
else:
|
||||
src_ip = self.manager.get_ip_address_by_idx(source_ip_id - 2)
|
||||
src_ip = self.manager.get_ip_address_by_idx(parsed_options.source_ip_id - 2)
|
||||
# subtract 2 to account for UNUSED=0, and ALL=1
|
||||
src_wildcard = self.manager.get_wildcard_by_idx(source_wildcard_id)
|
||||
if source_port_id == 0:
|
||||
return ["do_nothing"] # invalid formulation
|
||||
elif source_port_id == 1:
|
||||
|
||||
src_wildcard = self.manager.get_wildcard_by_idx(parsed_options.source_wildcard_id)
|
||||
|
||||
if parsed_options.source_port_id == 1:
|
||||
src_port = "ALL"
|
||||
else:
|
||||
src_port = self.manager.get_port_by_idx(source_port_id - 2)
|
||||
src_port = self.manager.get_port_by_idx(parsed_options.source_port_id - 2)
|
||||
# subtract 2 to account for UNUSED=0, and ALL=1
|
||||
|
||||
if dest_ip_id == 0:
|
||||
return ["do_nothing"] # invalid formulation
|
||||
elif dest_ip_id == 1:
|
||||
if parsed_options.dest_ip_id == 1:
|
||||
dst_ip = "ALL"
|
||||
else:
|
||||
dst_ip = self.manager.get_ip_address_by_idx(dest_ip_id - 2)
|
||||
dst_ip = self.manager.get_ip_address_by_idx(parsed_options.dest_ip_id - 2)
|
||||
# subtract 2 to account for UNUSED=0, and ALL=1
|
||||
dst_wildcard = self.manager.get_wildcard_by_idx(dest_wildcard_id)
|
||||
dst_wildcard = self.manager.get_wildcard_by_idx(parsed_options.dest_wildcard_id)
|
||||
|
||||
if dest_port_id == 0:
|
||||
return ["do_nothing"] # invalid formulation
|
||||
elif dest_port_id == 1:
|
||||
if parsed_options.dest_port_id == 1:
|
||||
dst_port = "ALL"
|
||||
else:
|
||||
dst_port = self.manager.get_port_by_idx(dest_port_id - 2)
|
||||
dst_port = self.manager.get_port_by_idx(parsed_options.dest_port_id - 2)
|
||||
# subtract 2 to account for UNUSED=0, and ALL=1
|
||||
|
||||
return [
|
||||
"network",
|
||||
"node",
|
||||
target_router_nodename,
|
||||
target_router,
|
||||
"acl",
|
||||
"add_rule",
|
||||
permission_str,
|
||||
@@ -625,9 +668,9 @@ class RouterACLRemoveRuleAction(AbstractAction):
|
||||
super().__init__(manager=manager)
|
||||
self.shape: Dict[str, int] = {"position": max_acl_rules}
|
||||
|
||||
def form_request(self, target_router_nodename: str, position: int) -> List[str]:
|
||||
def form_request(self, target_router: str, position: int) -> List[str]:
|
||||
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
|
||||
return ["network", "node", target_router_nodename, "acl", "remove_rule", position]
|
||||
return ["network", "node", target_router, "acl", "remove_rule", position]
|
||||
|
||||
|
||||
class FirewallACLAddRuleAction(AbstractAction):
|
||||
@@ -877,7 +920,10 @@ class NodeNMAPPingScanAction(AbstractAction):
|
||||
def __init__(self, manager: "ActionManager", **kwargs) -> None:
|
||||
super().__init__(manager=manager)
|
||||
|
||||
def form_request(self, source_node: str, target_ip_address: Union[str, List[str]]) -> List[str]: # noqa
|
||||
def form_request(
|
||||
self, source_node: str, target_ip_address: Union[str, List[str]], show: Optional[bool] = False
|
||||
) -> List[str]: # noqa
|
||||
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
|
||||
return [
|
||||
"network",
|
||||
"node",
|
||||
@@ -885,7 +931,7 @@ class NodeNMAPPingScanAction(AbstractAction):
|
||||
"application",
|
||||
"NMAP",
|
||||
"ping_scan",
|
||||
{"target_ip_address": target_ip_address},
|
||||
{"target_ip_address": target_ip_address, "show": show},
|
||||
]
|
||||
|
||||
|
||||
@@ -901,6 +947,7 @@ class NodeNMAPPortScanAction(AbstractAction):
|
||||
target_ip_address: Union[str, List[str]],
|
||||
target_protocol: Optional[Union[str, List[str]]] = None,
|
||||
target_port: Optional[Union[str, List[str]]] = None,
|
||||
show: Optional[bool] = False,
|
||||
) -> List[str]: # noqa
|
||||
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
|
||||
return [
|
||||
@@ -910,7 +957,12 @@ class NodeNMAPPortScanAction(AbstractAction):
|
||||
"application",
|
||||
"NMAP",
|
||||
"port_scan",
|
||||
{"target_ip_address": target_ip_address, "target_port": target_port, "target_protocol": target_protocol},
|
||||
{
|
||||
"target_ip_address": target_ip_address,
|
||||
"target_port": target_port,
|
||||
"target_protocol": target_protocol,
|
||||
"show": show,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -926,6 +978,7 @@ class NodeNetworkServiceReconAction(AbstractAction):
|
||||
target_ip_address: Union[str, List[str]],
|
||||
target_protocol: Optional[Union[str, List[str]]] = None,
|
||||
target_port: Optional[Union[str, List[str]]] = None,
|
||||
show: Optional[bool] = False,
|
||||
) -> List[str]: # noqa
|
||||
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
|
||||
return [
|
||||
@@ -935,7 +988,12 @@ class NodeNetworkServiceReconAction(AbstractAction):
|
||||
"application",
|
||||
"NMAP",
|
||||
"network_service_recon",
|
||||
{"target_ip_address": target_ip_address, "target_port": target_port, "target_protocol": target_protocol},
|
||||
{
|
||||
"target_ip_address": target_ip_address,
|
||||
"target_port": target_port,
|
||||
"target_protocol": target_protocol,
|
||||
"show": show,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -107,6 +107,8 @@ class AbstractAgent(ABC):
|
||||
:type observation_space: Optional[ObservationSpace]
|
||||
:param reward_function: Reward function for the agent.
|
||||
:type reward_function: Optional[RewardFunction]
|
||||
:param agent_settings: Configurable Options for Abstracted Agents
|
||||
:type agent_settings: Optional[AgentSettings]
|
||||
"""
|
||||
self.agent_name: str = agent_name or "unnamed_agent"
|
||||
self.action_manager: Optional[ActionManager] = action_space
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Dict, List, Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
from primaite import getLogger
|
||||
from primaite import DEFAULT_BANDWIDTH, getLogger
|
||||
from primaite.game.agent.actions import ActionManager
|
||||
from primaite.game.agent.interface import AbstractAgent, AgentSettings, ProxyAgent
|
||||
from primaite.game.agent.observations.observation_manager import ObservationManager
|
||||
@@ -406,7 +406,7 @@ class PrimaiteGame:
|
||||
for link_cfg in links_cfg:
|
||||
node_a = net.get_node_by_hostname(link_cfg["endpoint_a_hostname"])
|
||||
node_b = net.get_node_by_hostname(link_cfg["endpoint_b_hostname"])
|
||||
bandwidth = link_cfg.get("bandwidth", 100) # default value if not configured
|
||||
bandwidth = link_cfg.get("bandwidth", DEFAULT_BANDWIDTH) # default value if not configured
|
||||
|
||||
if isinstance(node_a, Switch):
|
||||
endpoint_a = node_a.network_interface[link_cfg["endpoint_a_port"]]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
from typing import Dict, ForwardRef, List, Literal, Union
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, StrictBool, validate_call
|
||||
from pydantic import BaseModel, ConfigDict, StrictBool # , validate_call
|
||||
|
||||
RequestFormat = List[Union[str, int, float, Dict]]
|
||||
|
||||
@@ -31,7 +31,7 @@ class RequestResponse(BaseModel):
|
||||
# much. However, in the future we might consider making them mandatory.
|
||||
|
||||
@classmethod
|
||||
@validate_call
|
||||
# @validate_call # this slows down execution quite a bit.
|
||||
def from_bool(cls, status_bool: StrictBool) -> RequestResponse:
|
||||
"""
|
||||
Construct a basic request response from a boolean.
|
||||
|
||||
@@ -458,7 +458,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.12"
|
||||
"version": "3.10.11"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
"source": [
|
||||
"# Requests and Responses\n",
|
||||
"\n",
|
||||
"Agents interact with the PrimAITE simulation via the Request system.\n",
|
||||
"© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK\n",
|
||||
"\n",
|
||||
"© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK\n"
|
||||
"Agents interact with the PrimAITE simulation via the Request system.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -423,7 +423,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.12"
|
||||
"version": "3.10.11"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -60,7 +60,7 @@ class PrimaiteGymEnv(gymnasium.Env):
|
||||
|
||||
next_obs = self._get_obs() # this doesn't update observation, just gets the current observation
|
||||
reward = self.agent.reward_function.current_reward
|
||||
_LOGGER.info(f"step: {self.game.step_counter}, Blue reward: {reward}")
|
||||
_LOGGER.debug(f"step: {self.game.step_counter}, Blue reward: {reward}")
|
||||
terminated = False
|
||||
truncated = self.game.calculate_truncated()
|
||||
info = {
|
||||
|
||||
@@ -45,11 +45,7 @@ def run(overwrite_existing: bool = True) -> None:
|
||||
shutil.copy2(src_fp, dst_fp)
|
||||
_LOGGER.info(f"Reset example notebook: {dst_fp}")
|
||||
|
||||
for src_fp in primaite_root.glob("notebooks/_package_data/*"):
|
||||
dst_fp = example_notebooks_user_dir / "_package_data" / src_fp.name
|
||||
if should_copy_file(src_fp, dst_fp, overwrite_existing):
|
||||
if not Path.exists(example_notebooks_user_dir / "_package_data/"):
|
||||
Path.mkdir(example_notebooks_user_dir / "_package_data/")
|
||||
print(dst_fp)
|
||||
shutil.copy2(src_fp, dst_fp)
|
||||
_LOGGER.info(f"Copied notebook resource to: {dst_fp}")
|
||||
src = primaite_root / "notebooks/_package_data/"
|
||||
dst = example_notebooks_user_dir / "_package_data/"
|
||||
|
||||
shutil.copytree(src, dst, dirs_exist_ok=True)
|
||||
|
||||
@@ -221,7 +221,7 @@ class SimComponent(BaseModel):
|
||||
}
|
||||
return state
|
||||
|
||||
@validate_call
|
||||
# @validate_call # this slows down execution quite a bit.
|
||||
def apply_request(self, request: RequestFormat, context: Optional[Dict] = None) -> RequestResponse:
|
||||
"""
|
||||
Apply a request to a simulation component. Request data is passed in as a 'namespaced' list of strings.
|
||||
|
||||
@@ -6,6 +6,8 @@ import json
|
||||
import warnings
|
||||
from typing import Dict, Optional
|
||||
|
||||
from prettytable import MARKDOWN, PrettyTable
|
||||
|
||||
from primaite import getLogger
|
||||
from primaite.simulator.file_system.file_system_item_abc import FileSystemItemABC, FileSystemItemHealthStatus
|
||||
from primaite.simulator.file_system.file_type import FileType, get_file_type_from_extension
|
||||
@@ -203,3 +205,18 @@ class File(FileSystemItemABC):
|
||||
self.deleted = True
|
||||
self.sys_log.info(f"File deleted {self.folder_name}/{self.name}")
|
||||
return True
|
||||
|
||||
def show(self, markdown: bool = False):
|
||||
"""
|
||||
Prints a table of the file, displaying the file type, name and the file's access count.
|
||||
|
||||
:param markdown: Flag indicating if output should be in markdown format.
|
||||
"""
|
||||
headers = ["File Name", "File Type", "Number of Accesses"]
|
||||
table = PrettyTable(headers)
|
||||
if markdown:
|
||||
table.set_style(MARKDOWN)
|
||||
table.align = "l"
|
||||
table.title = f"{self.name}"
|
||||
table.add_row([self.name, self.file_type.name, self.num_access])
|
||||
print(table)
|
||||
|
||||
@@ -67,7 +67,7 @@ class FileSystem(SimComponent):
|
||||
self._create_manager = RequestManager()
|
||||
|
||||
def _create_file_action(request: List[Any], context: Any) -> RequestResponse:
|
||||
file = self.create_file(folder_name=request[0], file_name=request[1])
|
||||
file = self.create_file(folder_name=request[0], file_name=request[1], force=request[2])
|
||||
if not file:
|
||||
return RequestResponse.from_bool(False)
|
||||
return RequestResponse(
|
||||
@@ -75,7 +75,7 @@ class FileSystem(SimComponent):
|
||||
data={
|
||||
"file_name": file.name,
|
||||
"folder_name": file.folder_name,
|
||||
"file_type": file.file_type,
|
||||
"file_type": file.file_type.name,
|
||||
"file_size": file.size,
|
||||
},
|
||||
)
|
||||
@@ -111,9 +111,9 @@ class FileSystem(SimComponent):
|
||||
data={
|
||||
"file_name": file.name,
|
||||
"folder_name": file.folder_name,
|
||||
"file_type": file.file_type,
|
||||
"file_type": file.file_type.name,
|
||||
"file_size": file.size,
|
||||
"file_status": file.health_status,
|
||||
"file_status": file.health_status.name,
|
||||
},
|
||||
)
|
||||
return RequestResponse.from_bool(False)
|
||||
@@ -160,6 +160,21 @@ class FileSystem(SimComponent):
|
||||
"""
|
||||
return sum(folder.size for folder in self.folders.values())
|
||||
|
||||
def show_num_files(self, markdown: bool = False):
|
||||
"""
|
||||
Prints a table showing a host's number of file creations & deletions.
|
||||
|
||||
:param markdown: Flag indicating if output should be in markdown format.
|
||||
"""
|
||||
headers = ["File creations", "File deletions"]
|
||||
table = PrettyTable(headers)
|
||||
if markdown:
|
||||
table.set_style(MARKDOWN)
|
||||
table.align = "l"
|
||||
table.title = f"{self.sys_log.hostname} Number of Creations & Deletions"
|
||||
table.add_row([self.num_file_creations, self.num_file_deletions])
|
||||
print(table)
|
||||
|
||||
def show(self, markdown: bool = False, full: bool = False):
|
||||
"""
|
||||
Prints a table of the FileSystem, displaying either just folders or full files.
|
||||
@@ -167,7 +182,7 @@ class FileSystem(SimComponent):
|
||||
:param markdown: Flag indicating if output should be in markdown format.
|
||||
:param full: Flag indicating if to show full files.
|
||||
"""
|
||||
headers = ["Folder", "Size", "Deleted"]
|
||||
headers = ["Folder", "Size", "Health status", "Visible health status", "Deleted"]
|
||||
if full:
|
||||
headers[0] = "File Path"
|
||||
table = PrettyTable(headers)
|
||||
@@ -178,14 +193,38 @@ class FileSystem(SimComponent):
|
||||
folders = {**self.folders, **self.deleted_folders}
|
||||
for folder in folders.values():
|
||||
if not full:
|
||||
table.add_row([folder.name, folder.size_str, folder.deleted])
|
||||
table.add_row(
|
||||
[
|
||||
folder.name,
|
||||
folder.size_str,
|
||||
folder.health_status.name,
|
||||
folder.visible_health_status.name,
|
||||
folder.deleted,
|
||||
]
|
||||
)
|
||||
else:
|
||||
files = {**folder.files, **folder.deleted_files}
|
||||
if not files:
|
||||
table.add_row([folder.name, folder.size_str, folder.deleted])
|
||||
table.add_row(
|
||||
[
|
||||
folder.name,
|
||||
folder.size_str,
|
||||
folder.health_status.name,
|
||||
folder.visible_health_status.name,
|
||||
folder.deleted,
|
||||
]
|
||||
)
|
||||
else:
|
||||
for file in files.values():
|
||||
table.add_row([file.path, file.size_str, file.deleted])
|
||||
table.add_row(
|
||||
[
|
||||
file.path,
|
||||
file.size_str,
|
||||
file.health_status.name,
|
||||
file.visible_health_status.name,
|
||||
file.deleted,
|
||||
]
|
||||
)
|
||||
if full:
|
||||
print(table.get_string(sortby="File Path"))
|
||||
else:
|
||||
@@ -201,15 +240,15 @@ class FileSystem(SimComponent):
|
||||
:param folder_name: The name of the folder.
|
||||
"""
|
||||
# check if folder with name already exists
|
||||
if self.get_folder(folder_name):
|
||||
raise Exception(f"Cannot create folder as it already exists: {folder_name}")
|
||||
|
||||
folder = Folder(name=folder_name, sys_log=self.sys_log)
|
||||
|
||||
folder = self.get_folder(folder_name)
|
||||
if folder:
|
||||
self.sys_log.info(f"Cannot create folder as it already exists: {folder_name}")
|
||||
else:
|
||||
folder = Folder(name=folder_name, sys_log=self.sys_log)
|
||||
self._folder_request_manager.add_request(
|
||||
name=folder.name, request_type=RequestType(func=folder._request_manager)
|
||||
)
|
||||
self.folders[folder.uuid] = folder
|
||||
self._folder_request_manager.add_request(
|
||||
name=folder.name, request_type=RequestType(func=folder._request_manager)
|
||||
)
|
||||
return folder
|
||||
|
||||
def delete_folder(self, folder_name: str) -> bool:
|
||||
@@ -289,6 +328,7 @@ class FileSystem(SimComponent):
|
||||
size: Optional[int] = None,
|
||||
file_type: Optional[FileType] = None,
|
||||
folder_name: Optional[str] = None,
|
||||
force: Optional[bool] = False,
|
||||
) -> File:
|
||||
"""
|
||||
Creates a File and adds it to the list of files.
|
||||
@@ -297,6 +337,7 @@ class FileSystem(SimComponent):
|
||||
:param size: The size the file takes on disk in bytes.
|
||||
:param file_type: The type of the file.
|
||||
:param folder_name: The folder to add the file to.
|
||||
:param force: Replaces the file if it already exists.
|
||||
"""
|
||||
if folder_name:
|
||||
# check if file with name already exists
|
||||
@@ -308,17 +349,23 @@ class FileSystem(SimComponent):
|
||||
# Use root folder if folder_name not supplied
|
||||
folder = self.get_folder("root")
|
||||
|
||||
# Create the file and add it to the folder
|
||||
file = File(
|
||||
name=file_name,
|
||||
sim_size=size,
|
||||
file_type=file_type,
|
||||
folder_id=folder.uuid,
|
||||
folder_name=folder.name,
|
||||
sim_root=self.sim_root,
|
||||
sys_log=self.sys_log,
|
||||
)
|
||||
folder.add_file(file)
|
||||
file = self.get_file(folder, file_name)
|
||||
if file:
|
||||
self.sys_log.info(f"Cannot create file {file_name} as it already exists.")
|
||||
if force:
|
||||
self.sys_log.info(f"Replacing {file_name}")
|
||||
else:
|
||||
# Create the file and add it to the folder
|
||||
file = File(
|
||||
name=file_name,
|
||||
sim_size=size,
|
||||
file_type=file_type,
|
||||
folder_id=folder.uuid,
|
||||
folder_name=folder.name,
|
||||
sim_root=self.sim_root,
|
||||
sys_log=self.sys_log,
|
||||
)
|
||||
folder.add_file(file, force=force)
|
||||
self._file_request_manager.add_request(name=file.name, request_type=RequestType(func=file._request_manager))
|
||||
# increment file creation
|
||||
self.num_file_creations += 1
|
||||
|
||||
@@ -96,6 +96,20 @@ class FileType(Enum):
|
||||
DB = 32
|
||||
"Generic DB file. Used by sqlite3."
|
||||
|
||||
# Script file types
|
||||
PS1 = 33
|
||||
"A Powershell script. Used in Windows operating systems."
|
||||
BAT = 34
|
||||
"Windows batch file. Used in Windows operating systems."
|
||||
SH = 35
|
||||
"Linux shell script. Used in Unix based operating systems."
|
||||
|
||||
# Executable file types
|
||||
PE = 36
|
||||
"Portable Executable. Used in Windows operating systems."
|
||||
ELF = 37
|
||||
"Executable and Linkable Format. Used in Unix based operating systems."
|
||||
|
||||
@classmethod
|
||||
def _missing_(cls, value: Any) -> FileType:
|
||||
return cls.UNKNOWN
|
||||
@@ -116,8 +130,11 @@ class FileType(Enum):
|
||||
|
||||
Returns 0 if a default size does not exist.
|
||||
"""
|
||||
size = file_type_sizes_bytes[self]
|
||||
return size if size else 0
|
||||
try:
|
||||
size = file_type_sizes_bytes[self]
|
||||
return size
|
||||
except KeyError:
|
||||
return 0
|
||||
|
||||
|
||||
def get_file_type_from_extension(file_type_extension: str) -> FileType:
|
||||
|
||||
@@ -11,6 +11,7 @@ from typing import Any, Dict, Optional, Type, TypeVar, Union
|
||||
from prettytable import MARKDOWN, PrettyTable
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
import primaite.simulator.network.nmne
|
||||
from primaite import getLogger
|
||||
from primaite.exceptions import NetworkError
|
||||
from primaite.interface.request import RequestResponse
|
||||
@@ -1049,7 +1050,7 @@ class Node(SimComponent):
|
||||
|
||||
def show_nic(self, markdown: bool = False):
|
||||
"""Prints a table of the NICs on the Node."""
|
||||
table = PrettyTable(["Port", "Type", "MAC Address", "Address", "Speed", "Status"])
|
||||
table = PrettyTable(["Port", "Type", "MAC Address", "Address", "Speed", "Status", "NMNE"])
|
||||
if markdown:
|
||||
table.set_style(MARKDOWN)
|
||||
table.align = "l"
|
||||
@@ -1066,6 +1067,7 @@ class Node(SimComponent):
|
||||
ip_address,
|
||||
network_interface.speed,
|
||||
"Enabled" if network_interface.enabled else "Disabled",
|
||||
network_interface.nmne if primaite.simulator.network.nmne.CAPTURE_NMNE else "Disabled",
|
||||
]
|
||||
)
|
||||
print(table)
|
||||
|
||||
@@ -185,7 +185,10 @@ def arcd_uc2_network() -> Network:
|
||||
db_client_2.run()
|
||||
web_browser_2 = client_2.software_manager.software.get("WebBrowser")
|
||||
web_browser_2.target_url = "http://arcd.com/users/"
|
||||
network.connect(endpoint_b=client_2.network_interface[1], endpoint_a=switch_2.network_interface[2])
|
||||
network.connect(
|
||||
endpoint_b=client_2.network_interface[1],
|
||||
endpoint_a=switch_2.network_interface[2],
|
||||
)
|
||||
|
||||
# Domain Controller
|
||||
domain_controller = Server(
|
||||
|
||||
@@ -25,6 +25,10 @@ class IPProtocol(Enum):
|
||||
ICMP = "icmp"
|
||||
"""Internet Control Message Protocol."""
|
||||
|
||||
def model_dump(self) -> str:
|
||||
"""Return as JSON-serialisable string."""
|
||||
return self.name
|
||||
|
||||
|
||||
class Precedence(Enum):
|
||||
"""
|
||||
|
||||
@@ -72,6 +72,10 @@ class Port(Enum):
|
||||
POSTGRES_SERVER = 5432
|
||||
"Postgres SQL Server."
|
||||
|
||||
def model_dump(self) -> str:
|
||||
"""Return a json-serialisable string."""
|
||||
return self.name
|
||||
|
||||
|
||||
class UDPHeader(BaseModel):
|
||||
"""
|
||||
|
||||
@@ -87,7 +87,9 @@ class NMAP(Application):
|
||||
|
||||
def _init_request_manager(self) -> RequestManager:
|
||||
def _ping_scan_action(request: List[Any], context: Any) -> RequestResponse:
|
||||
results = self.ping_scan(target_ip_address=request[0]["target_ip_address"], json_serializable=True)
|
||||
results = self.ping_scan(
|
||||
target_ip_address=request[0]["target_ip_address"], show=request[0]["show"], json_serializable=True
|
||||
)
|
||||
if not self._can_perform_network_action():
|
||||
return RequestResponse.from_bool(False)
|
||||
return RequestResponse(
|
||||
@@ -311,7 +313,6 @@ class NMAP(Application):
|
||||
self.sys_log.info(
|
||||
f"{self.name}: Responding to port scan request for port {payload.port.value} "
|
||||
f"({payload.port.name}) over {payload.protocol.name}",
|
||||
True,
|
||||
)
|
||||
self.software_manager.send_payload_to_session_manager(payload=payload, session_id=session_id)
|
||||
|
||||
@@ -370,7 +371,8 @@ class NMAP(Application):
|
||||
port_open = self._check_port_open_on_ip_address(ip_address=ip_address, port=port, protocol=protocol)
|
||||
|
||||
if port_open:
|
||||
table.add_row([ip_address, port.value, port.name, protocol.name])
|
||||
if show:
|
||||
table.add_row([ip_address, port.value, port.name, protocol.name])
|
||||
_ip_address = ip_address if not json_serializable else str(ip_address)
|
||||
_protocol = protocol if not json_serializable else protocol.value
|
||||
_port = port if not json_serializable else port.value
|
||||
|
||||
@@ -143,7 +143,7 @@ class ARP(Service):
|
||||
self.sys_log.info(f"Cannot send ARP request to a network address {str(target_ip_address)}")
|
||||
return
|
||||
if target_ip_address == outbound_network_interface.ip_network.broadcast_address:
|
||||
self.sys_log.info(f"Cannot send ARP request to a broadcast address {str(target_ip_address)}")
|
||||
self.sys_log.info(f"Cannot send ARP request to a broadcast addresss {str(target_ip_address)}")
|
||||
return
|
||||
|
||||
self.sys_log.info(f"Sending ARP request from NIC {outbound_network_interface} for ip {target_ip_address}")
|
||||
|
||||
@@ -61,7 +61,7 @@ class ICMP(Service):
|
||||
if target_ip_address.is_loopback:
|
||||
self.sys_log.info("Pinging loopback address")
|
||||
return any(network_interface.enabled for network_interface in self.network_interfaces.values())
|
||||
self.sys_log.info(f"Pinging {target_ip_address}:", to_terminal=True)
|
||||
self.sys_log.info(f"Pinging {target_ip_address}:", to_terminal=False)
|
||||
sequence, identifier = 0, None
|
||||
while sequence < pings:
|
||||
sequence, identifier = self._send_icmp_echo_request(target_ip_address, sequence, identifier, pings)
|
||||
@@ -77,7 +77,7 @@ class ICMP(Service):
|
||||
f"Received = {request_replies}, "
|
||||
f"Lost = {pings - request_replies} ({(pings - request_replies) / pings * 100}% loss)"
|
||||
)
|
||||
self.sys_log.info(output, to_terminal=True)
|
||||
self.sys_log.info(output, to_terminal=False)
|
||||
|
||||
return passed
|
||||
|
||||
@@ -167,7 +167,7 @@ class ICMP(Service):
|
||||
f"bytes={len(frame.payload)}, "
|
||||
f"time={time_str}, "
|
||||
f"TTL={frame.ip.ttl}",
|
||||
to_terminal=True,
|
||||
to_terminal=False,
|
||||
)
|
||||
if not self.request_replies.get(frame.icmp.identifier):
|
||||
self.request_replies[frame.icmp.identifier] = 0
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
raise DeprecationWarning(
|
||||
"Benchmarking depends on deprecated functionality and it has not been updated to primaite v3 yet."
|
||||
)
|
||||
# © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Union
|
||||
|
||||
@@ -286,7 +286,7 @@ agents:
|
||||
22: # "ACL: ADDRULE - Block outgoing traffic from client 1" (not supported in Primaite)
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -299,7 +299,7 @@ agents:
|
||||
23: # "ACL: ADDRULE - Block outgoing traffic from client 2" (not supported in Primaite)
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -312,7 +312,7 @@ agents:
|
||||
24: # block tcp traffic from client 1 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -325,7 +325,7 @@ agents:
|
||||
25: # block tcp traffic from client 2 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -338,7 +338,7 @@ agents:
|
||||
26:
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -351,7 +351,7 @@ agents:
|
||||
27:
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -364,52 +364,52 @@ agents:
|
||||
28:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 0
|
||||
29:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
30:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
31:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
32:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
33:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
34:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
35:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 7
|
||||
36:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 8
|
||||
37:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 9
|
||||
38:
|
||||
action: "HOST_NIC_DISABLE"
|
||||
|
||||
@@ -298,7 +298,7 @@ agents:
|
||||
22: # "ACL: ADDRULE - Block outgoing traffic from client 1" (not supported in Primaite)
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -311,7 +311,7 @@ agents:
|
||||
23: # "ACL: ADDRULE - Block outgoing traffic from client 2" (not supported in Primaite)
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -324,7 +324,7 @@ agents:
|
||||
24: # block tcp traffic from client 1 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -337,7 +337,7 @@ agents:
|
||||
25: # block tcp traffic from client 2 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -350,7 +350,7 @@ agents:
|
||||
26:
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -363,7 +363,7 @@ agents:
|
||||
27:
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -376,52 +376,52 @@ agents:
|
||||
28:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 0
|
||||
29:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
30:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
31:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
32:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
33:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
34:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
35:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 7
|
||||
36:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 8
|
||||
37:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 9
|
||||
38:
|
||||
action: "HOST_NIC_DISABLE"
|
||||
|
||||
@@ -289,7 +289,7 @@ agents:
|
||||
22: # "ACL: ADDRULE - Block outgoing traffic from client 1" (not supported in Primaite)
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -302,7 +302,7 @@ agents:
|
||||
23: # "ACL: ADDRULE - Block outgoing traffic from client 2" (not supported in Primaite)
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -315,7 +315,7 @@ agents:
|
||||
24: # block tcp traffic from client 1 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -328,7 +328,7 @@ agents:
|
||||
25: # block tcp traffic from client 2 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -341,7 +341,7 @@ agents:
|
||||
26:
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -354,7 +354,7 @@ agents:
|
||||
27:
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -367,52 +367,52 @@ agents:
|
||||
28:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 0
|
||||
29:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
30:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
31:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
32:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
33:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
34:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
35:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 7
|
||||
36:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 8
|
||||
37:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 9
|
||||
38:
|
||||
action: "HOST_NIC_DISABLE"
|
||||
@@ -759,7 +759,7 @@ agents:
|
||||
22: # "ACL: ADDRULE - Block outgoing traffic from client 1" (not supported in Primaite)
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -772,7 +772,7 @@ agents:
|
||||
23: # "ACL: ADDRULE - Block outgoing traffic from client 2" (not supported in Primaite)
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -785,7 +785,7 @@ agents:
|
||||
24: # block tcp traffic from client 1 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -798,7 +798,7 @@ agents:
|
||||
25: # block tcp traffic from client 2 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -811,7 +811,7 @@ agents:
|
||||
26:
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -824,7 +824,7 @@ agents:
|
||||
27:
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -837,52 +837,52 @@ agents:
|
||||
28:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 0
|
||||
29:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
30:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
31:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
32:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
33:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
34:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
35:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 7
|
||||
36:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 8
|
||||
37:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 9
|
||||
|
||||
|
||||
|
||||
@@ -466,7 +466,7 @@ agents:
|
||||
46: # old action num: 22 # "ACL: ADDRULE - Block outgoing traffic from client 1"
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -479,7 +479,7 @@ agents:
|
||||
47: # old action num: 23 # "ACL: ADDRULE - Block outgoing traffic from client 2"
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -492,7 +492,7 @@ agents:
|
||||
48: # old action num: 24 # block tcp traffic from client 1 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -505,7 +505,7 @@ agents:
|
||||
49: # old action num: 25 # block tcp traffic from client 2 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -518,7 +518,7 @@ agents:
|
||||
50: # old action num: 26
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -531,7 +531,7 @@ agents:
|
||||
51: # old action num: 27
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -544,52 +544,52 @@ agents:
|
||||
52: # old action num: 28
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 0
|
||||
53: # old action num: 29
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
54: # old action num: 30
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
55: # old action num: 31
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
56: # old action num: 32
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
57: # old action num: 33
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
58: # old action num: 34
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
59: # old action num: 35
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 7
|
||||
60: # old action num: 36
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 8
|
||||
61: # old action num: 37
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 9
|
||||
62: # old action num: 38
|
||||
action: "HOST_NIC_DISABLE"
|
||||
|
||||
@@ -307,7 +307,7 @@ agents:
|
||||
22: # "ACL: ADDRULE - Block outgoing traffic from client 1" (not supported in Primaite)
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -320,7 +320,7 @@ agents:
|
||||
23: # "ACL: ADDRULE - Block outgoing traffic from client 2" (not supported in Primaite)
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -333,7 +333,7 @@ agents:
|
||||
24: # block tcp traffic from client 1 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -346,7 +346,7 @@ agents:
|
||||
25: # block tcp traffic from client 2 to web app
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -359,7 +359,7 @@ agents:
|
||||
26:
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
permission: 2
|
||||
source_ip_id: 7 # client 1
|
||||
@@ -372,7 +372,7 @@ agents:
|
||||
27:
|
||||
action: "ROUTER_ACL_ADDRULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
permission: 2
|
||||
source_ip_id: 8 # client 2
|
||||
@@ -385,52 +385,52 @@ agents:
|
||||
28:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 0
|
||||
29:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 1
|
||||
30:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 2
|
||||
31:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 3
|
||||
32:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 4
|
||||
33:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 5
|
||||
34:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 6
|
||||
35:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 7
|
||||
36:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 8
|
||||
37:
|
||||
action: "ROUTER_ACL_REMOVERULE"
|
||||
options:
|
||||
target_router_nodename: router_1
|
||||
target_router: router_1
|
||||
position: 9
|
||||
38:
|
||||
action: "HOST_NIC_DISABLE"
|
||||
|
||||
@@ -39,3 +39,4 @@ def test_rllib_multi_agent_compatibility():
|
||||
),
|
||||
param_space=config,
|
||||
).fit()
|
||||
ray.shutdown()
|
||||
|
||||
@@ -41,3 +41,4 @@ def test_rllib_single_agent_compatibility():
|
||||
assert save_file.exists()
|
||||
|
||||
save_file.unlink() # clean up
|
||||
ray.shutdown()
|
||||
|
||||
@@ -45,5 +45,7 @@ def test_basic_config():
|
||||
client_3: Computer = network.get_node_by_hostname("client_3")
|
||||
assert client_3.operating_state == NodeOperatingState.OFF
|
||||
|
||||
# Bandwidth should have non-default values
|
||||
|
||||
for link in network.links:
|
||||
assert network.links[link].bandwidth == 200
|
||||
|
||||
@@ -123,7 +123,7 @@ def test_router_acl_addrule_integration(game_and_agent: Tuple[PrimaiteGame, Prox
|
||||
action = (
|
||||
"ROUTER_ACL_ADDRULE",
|
||||
{
|
||||
"target_router_nodename": "router",
|
||||
"target_router": "router",
|
||||
"position": 4, # 4th rule
|
||||
"permission": 2, # DENY
|
||||
"source_ip_id": 3, # 10.0.1.2 (client_1)
|
||||
@@ -150,7 +150,7 @@ def test_router_acl_addrule_integration(game_and_agent: Tuple[PrimaiteGame, Prox
|
||||
action = (
|
||||
"ROUTER_ACL_ADDRULE",
|
||||
{
|
||||
"target_router_nodename": "router",
|
||||
"target_router": "router",
|
||||
"position": 5, # 5th rule
|
||||
"permission": 2, # DENY
|
||||
"source_ip_id": 5, # 10.0.2.2 (server_1)
|
||||
@@ -188,7 +188,7 @@ def test_router_acl_removerule_integration(game_and_agent: Tuple[PrimaiteGame, P
|
||||
action = (
|
||||
"ROUTER_ACL_REMOVERULE",
|
||||
{
|
||||
"target_router_nodename": "router",
|
||||
"target_router": "router",
|
||||
"position": 3, # 4th rule
|
||||
},
|
||||
)
|
||||
|
||||
@@ -21,7 +21,9 @@ def test_successful_node_file_system_creation_request(example_network):
|
||||
client_1 = example_network.get_node_by_hostname("client_1")
|
||||
assert client_1.file_system.get_file(folder_name="root", file_name="test.txt") is None
|
||||
|
||||
response = example_network.apply_request(["node", "client_1", "file_system", "create", "file", "", "test.txt"])
|
||||
response = example_network.apply_request(
|
||||
["node", "client_1", "file_system", "create", "file", "", "test.txt", "false"]
|
||||
)
|
||||
|
||||
assert response
|
||||
assert client_1.file_system.get_file(folder_name="root", file_name="test.txt")
|
||||
|
||||
@@ -25,6 +25,10 @@ def test_creating_response_from_boolean():
|
||||
r2 = RequestResponse.from_bool(False)
|
||||
assert r2.status == "failure"
|
||||
|
||||
|
||||
@pytest.mark.skip("Disable validation due to performance hit.")
|
||||
def test_response_from_invalid_options():
|
||||
"""Test that we get a validation error if a non-boolean is passed."""
|
||||
with pytest.raises(ValidationError):
|
||||
r3 = RequestResponse.from_bool(1)
|
||||
with pytest.raises(ValidationError):
|
||||
|
||||
@@ -108,8 +108,9 @@ def test_create_duplicate_folder(file_system):
|
||||
file_system.create_folder(folder_name="test_folder")
|
||||
|
||||
assert len(file_system.folders) is 2
|
||||
with pytest.raises(Exception):
|
||||
file_system.create_folder(folder_name="test_folder")
|
||||
# We no longer through exceptions on making duplicate folders.
|
||||
# with pytest.raises(Exception):
|
||||
# file_system.create_folder(folder_name="test_folder")
|
||||
|
||||
assert len(file_system.folders) is 2
|
||||
|
||||
|
||||
Reference in New Issue
Block a user