diff --git a/MANIFEST.in b/MANIFEST.in index 04a90e0e..51ae4ddf 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,2 @@ +include src/primaite/setup/_package_data/primaite_config.yaml include src/primaite/config/_package_data/*.yaml diff --git a/src/primaite/__init__.py b/src/primaite/__init__.py index 039e66c4..c000e422 100644 --- a/src/primaite/__init__.py +++ b/src/primaite/__init__.py @@ -7,11 +7,33 @@ from logging.handlers import RotatingFileHandler from pathlib import Path from typing import Final +import pkg_resources +import yaml from platformdirs import PlatformDirs _PLATFORM_DIRS: Final[PlatformDirs] = PlatformDirs(appname="primaite") """An instance of `PlatformDirs` set with appname='primaite'.""" +def _get_primaite_config(): + config_path = _PLATFORM_DIRS.user_config_path / "primaite_config.yaml" + if not config_path.exists(): + config_path = Path( + pkg_resources.resource_filename( + "primaite", "setup/_package_data/primaite_config.yaml" + ) + ) + with open(config_path, "r") as file: + primaite_config = yaml.safe_load(file) + return primaite_config + + +_PRIMAITE_CONFIG = _get_primaite_config() + +# PrimAITE config items +_LOG_LEVEL: int = _PRIMAITE_CONFIG["log_level"] +_LOGGER_FORMAT: str = _PRIMAITE_CONFIG["logger_format"] + + _USER_DIRS: Final[Path] = Path.home() / "primaite" """The users home space for PrimAITE which is located at: ~/primaite.""" @@ -64,12 +86,10 @@ _FILE_HANDLER: Final[RotatingFileHandler] = RotatingFileHandler( backupCount=9, # Max 100MB of logs encoding="utf8", ) -_STREAM_HANDLER.setLevel(logging.DEBUG) -_FILE_HANDLER.setLevel(logging.DEBUG) +_STREAM_HANDLER.setLevel(_LOG_LEVEL) +_FILE_HANDLER.setLevel(_LOG_LEVEL) -_LOG_FORMAT_STR: Final[ - str -] = "%(asctime)s::%(levelname)s::%(name)s::%(lineno)s::%(message)s" +_LOG_FORMAT_STR: Final[str] = _LOGGER_FORMAT _STREAM_HANDLER.setFormatter(logging.Formatter(_LOG_FORMAT_STR)) _FILE_HANDLER.setFormatter(logging.Formatter(_LOG_FORMAT_STR)) @@ -88,7 +108,7 @@ def getLogger(name: str) -> Logger: logging config. """ logger = logging.getLogger(name) - logger.setLevel(logging.DEBUG) + logger.setLevel(_LOG_LEVEL) return logger diff --git a/src/primaite/cli.py b/src/primaite/cli.py index ebc126e0..1640f54f 100644 --- a/src/primaite/cli.py +++ b/src/primaite/cli.py @@ -1,9 +1,13 @@ # Crown Copyright (C) Dstl 2022. DEFCON 703. Shared in confidence. """Provides a CLI using Typer as an entry point.""" import os +import shutil import sys +from pathlib import Path +import pkg_resources import typer +from platformdirs import PlatformDirs app = typer.Typer() @@ -79,12 +83,24 @@ def clean_up(): @app.command() -def setup(): +def setup(overwrite_existing: bool = True): """ Perform the PrimAITE first-time setup. WARNING: All user-data will be lost. """ + app_dirs = PlatformDirs(appname="primaite") + user_config_path = app_dirs.user_config_path / "primaite_config.yaml" + build_config = overwrite_existing or (not user_config_path.exists()) + if build_config: + pkg_config_path = Path( + pkg_resources.resource_filename( + "primaite", "setup/_package_data/primaite_config.yaml" + ) + ) + + shutil.copy2(pkg_config_path, user_config_path) + from primaite import getLogger from primaite.setup import ( old_installation_clean_up, @@ -97,6 +113,9 @@ def setup(): _LOGGER.info("Performing the PrimAITE first-time setup...") + if build_config: + _LOGGER.info("Building primaite_config.yaml...") + _LOGGER.info("Building the PrimAITE app directories...") setup_app_dirs.run() diff --git a/src/primaite/config/training_config.py b/src/primaite/config/training_config.py index 15bfb156..6a026cf1 100644 --- a/src/primaite/config/training_config.py +++ b/src/primaite/config/training_config.py @@ -1,7 +1,7 @@ # Crown Copyright (C) Dstl 2022. DEFCON 703. Shared in confidence. -from dataclasses import dataclass +from dataclasses import dataclass, field from pathlib import Path -from typing import Any, Dict, Final, Union +from typing import Any, Dict, Final, Union, Optional import yaml @@ -18,85 +18,118 @@ class TrainingConfig: """The Training Config class.""" # Generic - agent_identifier: str # The Red Agent algo/class to be used - action_type: ActionType # type of action to use (NODE/ACL/ANY) - num_episodes: int # number of episodes to train over - num_steps: int # number of steps in an episode - time_delay: int # delay between steps (ms) - applies to generic agents only + agent_identifier: str = "STABLE_BASELINES3_A2C" + "The Red Agent algo/class to be used." + + action_type: ActionType = ActionType.ANY + "The ActionType to use." + + num_episodes: int = 10 + "The number of episodes to train over." + + num_steps: int = 256 + "The number of steps in an episode." + observation_space: dict = field( + default_factory=lambda: {"components": [{"name": "NODE_LINK_TABLE"}]} + ) + "The observation space config dict." + + time_delay: int = 10 + "The delay between steps (ms). Applies to generic agents only." + # file - session_type: str # the session type to run (TRAINING or EVALUATION) - load_agent: str # Determine whether to load an agent from file - agent_load_file: str # File path and file name of agent if you're loading one in + session_type: str = "TRAINING" + "the session type to run (TRAINING or EVALUATION)" + + load_agent: str = False + "Determine whether to load an agent from file." + + agent_load_file: Optional[str] = None + "File path and file name of agent if you're loading one in." # Environment - observation_space_high_value: int # The high value for the observation space + observation_space_high_value: int = 1000000000 + "The high value for the observation space." # Reward values # Generic - all_ok: int + all_ok: int = 0 + # Node Hardware State - off_should_be_on: int - off_should_be_resetting: int - on_should_be_off: int - on_should_be_resetting: int - resetting_should_be_on: int - resetting_should_be_off: int - resetting: int + off_should_be_on: int = -10 + off_should_be_resetting: int = -5 + on_should_be_off: int = -2 + on_should_be_resetting: int = -5 + resetting_should_be_on: int = -5 + resetting_should_be_off: int = -2 + resetting: int = -3 + # Node Software or Service State - good_should_be_patching: int - good_should_be_compromised: int - good_should_be_overwhelmed: int - patching_should_be_good: int - patching_should_be_compromised: int - patching_should_be_overwhelmed: int - patching: int - compromised_should_be_good: int - compromised_should_be_patching: int - compromised_should_be_overwhelmed: int - compromised: int - overwhelmed_should_be_good: int - overwhelmed_should_be_patching: int - overwhelmed_should_be_compromised: int - overwhelmed: int + good_should_be_patching: int = 2 + good_should_be_compromised: int = 5 + good_should_be_overwhelmed: int = 5 + patching_should_be_good: int = -5 + patching_should_be_compromised: int = 2 + patching_should_be_overwhelmed: int = 2 + patching: int = -3 + compromised_should_be_good: int = -20 + compromised_should_be_patching: int = -20 + compromised_should_be_overwhelmed: int = -20 + compromised: int = -20 + overwhelmed_should_be_good: int = -20 + overwhelmed_should_be_patching: int = -20 + overwhelmed_should_be_compromised: int = -20 + overwhelmed: int = -20 + # Node File System State - good_should_be_repairing: int - good_should_be_restoring: int - good_should_be_corrupt: int - good_should_be_destroyed: int - repairing_should_be_good: int - repairing_should_be_restoring: int - repairing_should_be_corrupt: int - repairing_should_be_destroyed: int # Repairing does not fix destroyed state - you need to restore + good_should_be_repairing: int = 2 + good_should_be_restoring: int = 2 + good_should_be_corrupt: int = 5 + good_should_be_destroyed: int = 10 + repairing_should_be_good: int = -5 + repairing_should_be_restoring: int = 2 + repairing_should_be_corrupt: int = 2 + repairing_should_be_destroyed: int = 0 + repairing: int = -3 + restoring_should_be_good: int = -10 + restoring_should_be_repairing: int = -2 + restoring_should_be_corrupt: int = 1 + restoring_should_be_destroyed: int = 2 + restoring: int = -6 + corrupt_should_be_good: int = -10 + corrupt_should_be_repairing: int = -10 + corrupt_should_be_restoring: int = -10 + corrupt_should_be_destroyed: int = 2 + corrupt: int = -10 + destroyed_should_be_good: int = -20 + destroyed_should_be_repairing: int = -20 + destroyed_should_be_restoring: int = -20 + destroyed_should_be_corrupt: int = -20 + destroyed: int = -20 + scanning: int = -2 - repairing: int - restoring_should_be_good: int - restoring_should_be_repairing: int - restoring_should_be_corrupt: int # Not the optimal method (as repair will fix corruption) - - restoring_should_be_destroyed: int - restoring: int - corrupt_should_be_good: int - corrupt_should_be_repairing: int - corrupt_should_be_restoring: int - corrupt_should_be_destroyed: int - corrupt: int - destroyed_should_be_good: int - destroyed_should_be_repairing: int - destroyed_should_be_restoring: int - destroyed_should_be_corrupt: int - destroyed: int - scanning: int # IER status - red_ier_running: int - green_ier_blocked: int + red_ier_running: int = -5 + green_ier_blocked: int = -10 - # Patching / Reset - os_patching_duration: int # The time taken to patch the OS - node_reset_duration: int # The time taken to reset a node (hardware) - service_patching_duration: int # The time taken to patch a service - file_system_repairing_limit: int # The time take to repair a file - file_system_restoring_limit: int # The time take to restore a file - file_system_scanning_limit: int # The time taken to scan the file system + # Patching / Reset durations + os_patching_duration: int = 5 + "The time taken to patch the OS." + + node_reset_duration: int = 5 + "The time taken to reset a node (hardware)." + + service_patching_duration: int = 5 + "The time taken to patch a service." + + file_system_repairing_limit: int = 5 + "The time take to repair the file system." + + file_system_restoring_limit: int = 5 + "The time take to restore the file system." + + file_system_scanning_limit: int = 5 + "The time taken to scan the file system." def to_dict(self, json_serializable: bool = True): """ @@ -128,7 +161,8 @@ def main_training_config_path() -> Path: return path -def load(file_path: Union[str, Path], legacy_file: bool = False) -> TrainingConfig: +def load(file_path: Union[str, Path], + legacy_file: bool = False) -> TrainingConfig: """ Read in a training config yaml file. @@ -173,7 +207,8 @@ def load(file_path: Union[str, Path], legacy_file: bool = False) -> TrainingConf def convert_legacy_training_config_dict( - legacy_config_dict: Dict[str, Any], num_steps: int = 256, action_type: str = "ANY" + legacy_config_dict: Dict[str, Any], num_steps: int = 256, + action_type: str = "ANY" ) -> Dict[str, Any]: """ Convert a legacy training config dict to the new format. diff --git a/src/primaite/environment/primaite_env.py b/src/primaite/environment/primaite_env.py index 35901198..71537817 100644 --- a/src/primaite/environment/primaite_env.py +++ b/src/primaite/environment/primaite_env.py @@ -168,8 +168,8 @@ class Primaite(Env): # TODO fix up with TrainingConfig # stores the observation config from the yaml, default is NODE_LINK_TABLE self.obs_config: dict = {"components": [{"name": "NODE_LINK_TABLE"}]} - if self.config_values.observation_config is not None: - self.obs_config = self.config_values.observation_config + if self.training_config.observation_space is not None: + self.obs_config = self.training_config.observation_space # Observation Handler manages the user-configurable observation space. # It will be initialised later. diff --git a/src/primaite/setup/_package_data/primaite_config.yaml b/src/primaite/setup/_package_data/primaite_config.yaml new file mode 100644 index 00000000..e5c9667e --- /dev/null +++ b/src/primaite/setup/_package_data/primaite_config.yaml @@ -0,0 +1,5 @@ +# The main PrimAITE application config file + +# Logging +log_level: 'INFO' +logger_format: '%(asctime)s::%(levelname)s::%(name)s::%(lineno)s::%(message)s' diff --git a/tests/config/__init__.py b/tests/config/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/config/legacy/__init__.py b/tests/config/legacy/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/config/obs_tests/laydown.yaml b/tests/config/obs_tests/laydown.yaml index b110befc..ef77ce83 100644 --- a/tests/config/obs_tests/laydown.yaml +++ b/tests/config/obs_tests/laydown.yaml @@ -1,7 +1,3 @@ -- item_type: ACTIONS - type: NODE -- item_type: STEPS - steps: 5 - item_type: PORTS ports_list: - port: '80' @@ -88,14 +84,14 @@ ######################################### # ACL Rules -- itemType: ACL_RULE +- item_type: ACL_RULE id: '6' permission: ALLOW source: 192.168.1.1 destination: 192.168.1.2 protocol: TCP port: 80 -- itemType: ACL_RULE +- item_type: ACL_RULE id: '7' permission: ALLOW source: 192.168.1.2 diff --git a/tests/config/obs_tests/main_config_LINK_TRAFFIC_LEVELS.yaml b/tests/config/obs_tests/main_config_LINK_TRAFFIC_LEVELS.yaml index cdb741f3..67aaa9de 100644 --- a/tests/config/obs_tests/main_config_LINK_TRAFFIC_LEVELS.yaml +++ b/tests/config/obs_tests/main_config_LINK_TRAFFIC_LEVELS.yaml @@ -5,92 +5,100 @@ # "STABLE_BASELINES3_PPO" # "STABLE_BASELINES3_A2C" # "GENERIC" -agentIdentifier: NONE +agent_identifier: STABLE_BASELINES3_A2C +# Sets How the Action Space is defined: +# "NODE" +# "ACL" +# "ANY" node and acl actions +action_type: ANY # Number of episodes to run per session -observationSpace: +num_episodes: 1 +# Number of time_steps per episode +num_steps: 5 + + +observation_space: components: - name: LINK_TRAFFIC_LEVELS options: combine_service_traffic: false quantisation_levels: 8 -numEpisodes: 1 # Time delay between steps (for generic agents) -timeDelay: 1 -# Filename of the scenario / laydown -configFilename: one_node_states_on_off_lay_down_config.yaml +time_delay: 1 + # Type of session to be run (TRAINING or EVALUATION) -sessionType: TRAINING +session_type: TRAINING # Determine whether to load an agent from file -loadAgent: False +load_agent: False # File path and file name of agent if you're loading one in -agentLoadFile: C:\[Path]\[agent_saved_filename.zip] +agent_load_file: C:\[Path]\[agent_saved_filename.zip] # Environment config values # The high value for the observation space -observationSpaceHighValue: 1_000_000_000 +observation_space_high_value: 1_000_000_000 # Reward values # Generic -allOk: 0 +all_ok: 0 # Node Hardware State -offShouldBeOn: -10 -offShouldBeResetting: -5 -onShouldBeOff: -2 -onShouldBeResetting: -5 -resettingShouldBeOn: -5 -resettingShouldBeOff: -2 +off_should_be_on: -10 +off_should_be_resetting: -5 +on_should_be_off: -2 +on_should_be_resetting: -5 +resetting_should_be_on: -5 +resetting_should_be_off: -2 resetting: -3 # Node Software or Service State -goodShouldBePatching: 2 -goodShouldBeCompromised: 5 -goodShouldBeOverwhelmed: 5 -patchingShouldBeGood: -5 -patchingShouldBeCompromised: 2 -patchingShouldBeOverwhelmed: 2 +good_should_be_patching: 2 +good_should_be_compromised: 5 +good_should_be_overwhelmed: 5 +patching_should_be_good: -5 +patching_should_be_compromised: 2 +patching_should_be_overwhelmed: 2 patching: -3 -compromisedShouldBeGood: -20 -compromisedShouldBePatching: -20 -compromisedShouldBeOverwhelmed: -20 +compromised_should_be_good: -20 +compromised_should_be_patching: -20 +compromised_should_be_overwhelmed: -20 compromised: -20 -overwhelmedShouldBeGood: -20 -overwhelmedShouldBePatching: -20 -overwhelmedShouldBeCompromised: -20 +overwhelmed_should_be_good: -20 +overwhelmed_should_be_patching: -20 +overwhelmed_should_be_compromised: -20 overwhelmed: -20 # Node File System State -goodShouldBeRepairing: 2 -goodShouldBeRestoring: 2 -goodShouldBeCorrupt: 5 -goodShouldBeDestroyed: 10 -repairingShouldBeGood: -5 -repairingShouldBeRestoring: 2 -repairingShouldBeCorrupt: 2 -repairingShouldBeDestroyed: 0 +good_should_be_repairing: 2 +good_should_be_restoring: 2 +good_should_be_corrupt: 5 +good_should_be_destroyed: 10 +repairing_should_be_good: -5 +repairing_should_be_restoring: 2 +repairing_should_be_corrupt: 2 +repairing_should_be_destroyed: 0 repairing: -3 -restoringShouldBeGood: -10 -restoringShouldBeRepairing: -2 -restoringShouldBeCorrupt: 1 -restoringShouldBeDestroyed: 2 +restoring_should_be_good: -10 +restoring_should_be_repairing: -2 +restoring_should_be_corrupt: 1 +restoring_should_be_destroyed: 2 restoring: -6 -corruptShouldBeGood: -10 -corruptShouldBeRepairing: -10 -corruptShouldBeRestoring: -10 -corruptShouldBeDestroyed: 2 +corrupt_should_be_good: -10 +corrupt_should_be_repairing: -10 +corrupt_should_be_restoring: -10 +corrupt_should_be_destroyed: 2 corrupt: -10 -destroyedShouldBeGood: -20 -destroyedShouldBeRepairing: -20 -destroyedShouldBeRestoring: -20 -destroyedShouldBeCorrupt: -20 +destroyed_should_be_good: -20 +destroyed_should_be_repairing: -20 +destroyed_should_be_restoring: -20 +destroyed_should_be_corrupt: -20 destroyed: -20 scanning: -2 # IER status -redIerRunning: -5 -greenIerBlocked: -10 +red_ier_running: -5 +green_ier_blocked: -10 # Patching / Reset durations -osPatchingDuration: 5 # The time taken to patch the OS -nodeResetDuration: 5 # The time taken to reset a node (hardware) -servicePatchingDuration: 5 # The time taken to patch a service -fileSystemRepairingLimit: 5 # The time take to repair the file system -fileSystemRestoringLimit: 5 # The time take to restore the file system -fileSystemScanningLimit: 5 # The time taken to scan the file system +os_patching_duration: 5 # The time taken to patch the OS +node_reset_duration: 5 # The time taken to reset a node (hardware) +service_patching_duration: 5 # The time taken to patch a service +file_system_repairing_limit: 5 # The time take to repair the file system +file_system_restoring_limit: 5 # The time take to restore the file system +file_system_scanning_limit: 5 # The time taken to scan the file system diff --git a/tests/config/obs_tests/main_config_NODE_LINK_TABLE.yaml b/tests/config/obs_tests/main_config_NODE_LINK_TABLE.yaml index 19d220c8..29a89b8d 100644 --- a/tests/config/obs_tests/main_config_NODE_LINK_TABLE.yaml +++ b/tests/config/obs_tests/main_config_NODE_LINK_TABLE.yaml @@ -5,89 +5,96 @@ # "STABLE_BASELINES3_PPO" # "STABLE_BASELINES3_A2C" # "GENERIC" -agentIdentifier: NONE +agent_identifier: NONE +# Sets How the Action Space is defined: +# "NODE" +# "ACL" +# "ANY" node and acl actions +action_type: ANY # Number of episodes to run per session -observationSpace: +num_episodes: 1 +# Number of time_steps per episode +num_steps: 5 + +observation_space: components: - name: NODE_LINK_TABLE -numEpisodes: 1 # Time delay between steps (for generic agents) -timeDelay: 1 +time_delay: 1 # Filename of the scenario / laydown -configFilename: one_node_states_on_off_lay_down_config.yaml -# Type of session to be run (TRAINING or EVALUATION) -sessionType: TRAINING + +session_type: TRAINING # Determine whether to load an agent from file -loadAgent: False +load_agent: False # File path and file name of agent if you're loading one in -agentLoadFile: C:\[Path]\[agent_saved_filename.zip] +agent_load_file: C:\[Path]\[agent_saved_filename.zip] # Environment config values # The high value for the observation space -observationSpaceHighValue: 1_000_000_000 +observation_space_high_value: 1_000_000_000 # Reward values # Generic -allOk: 0 +all_ok: 0 # Node Hardware State -offShouldBeOn: -10 -offShouldBeResetting: -5 -onShouldBeOff: -2 -onShouldBeResetting: -5 -resettingShouldBeOn: -5 -resettingShouldBeOff: -2 +off_should_be_on: -10 +off_should_be_resetting: -5 +on_should_be_off: -2 +on_should_be_resetting: -5 +resetting_should_be_on: -5 +resetting_should_be_off: -2 resetting: -3 # Node Software or Service State -goodShouldBePatching: 2 -goodShouldBeCompromised: 5 -goodShouldBeOverwhelmed: 5 -patchingShouldBeGood: -5 -patchingShouldBeCompromised: 2 -patchingShouldBeOverwhelmed: 2 +good_should_be_patching: 2 +good_should_be_compromised: 5 +good_should_be_overwhelmed: 5 +patching_should_be_good: -5 +patching_should_be_compromised: 2 +patching_should_be_overwhelmed: 2 patching: -3 -compromisedShouldBeGood: -20 -compromisedShouldBePatching: -20 -compromisedShouldBeOverwhelmed: -20 +compromised_should_be_good: -20 +compromised_should_be_patching: -20 +compromised_should_be_overwhelmed: -20 compromised: -20 -overwhelmedShouldBeGood: -20 -overwhelmedShouldBePatching: -20 -overwhelmedShouldBeCompromised: -20 +overwhelmed_should_be_good: -20 +overwhelmed_should_be_patching: -20 +overwhelmed_should_be_compromised: -20 overwhelmed: -20 # Node File System State -goodShouldBeRepairing: 2 -goodShouldBeRestoring: 2 -goodShouldBeCorrupt: 5 -goodShouldBeDestroyed: 10 -repairingShouldBeGood: -5 -repairingShouldBeRestoring: 2 -repairingShouldBeCorrupt: 2 -repairingShouldBeDestroyed: 0 +good_should_be_repairing: 2 +good_should_be_restoring: 2 +good_should_be_corrupt: 5 +good_should_be_destroyed: 10 +repairing_should_be_good: -5 +repairing_should_be_restoring: 2 +repairing_should_be_corrupt: 2 +repairing_should_be_destroyed: 0 repairing: -3 -restoringShouldBeGood: -10 -restoringShouldBeRepairing: -2 -restoringShouldBeCorrupt: 1 -restoringShouldBeDestroyed: 2 +restoring_should_be_good: -10 +restoring_should_be_repairing: -2 +restoring_should_be_corrupt: 1 +restoring_should_be_destroyed: 2 restoring: -6 -corruptShouldBeGood: -10 -corruptShouldBeRepairing: -10 -corruptShouldBeRestoring: -10 -corruptShouldBeDestroyed: 2 +corrupt_should_be_good: -10 +corrupt_should_be_repairing: -10 +corrupt_should_be_restoring: -10 +corrupt_should_be_destroyed: 2 corrupt: -10 -destroyedShouldBeGood: -20 -destroyedShouldBeRepairing: -20 -destroyedShouldBeRestoring: -20 -destroyedShouldBeCorrupt: -20 +destroyed_should_be_good: -20 +destroyed_should_be_repairing: -20 +destroyed_should_be_restoring: -20 +destroyed_should_be_corrupt: -20 destroyed: -20 scanning: -2 # IER status -redIerRunning: -5 -greenIerBlocked: -10 +red_ier_running: -5 +green_ier_blocked: -10 # Patching / Reset durations -osPatchingDuration: 5 # The time taken to patch the OS -nodeResetDuration: 5 # The time taken to reset a node (hardware) -servicePatchingDuration: 5 # The time taken to patch a service -fileSystemRepairingLimit: 5 # The time take to repair the file system -fileSystemRestoringLimit: 5 # The time take to restore the file system -fileSystemScanningLimit: 5 # The time taken to scan the file system +os_patching_duration: 5 # The time taken to patch the OS +node_reset_duration: 5 # The time taken to reset a node (hardware) +service_patching_duration: 5 # The time taken to patch a service +file_system_repairing_limit: 5 # The time take to repair the file system +file_system_restoring_limit: 5 # The time take to restore the file system +file_system_scanning_limit: 5 # The time taken to scan the file system diff --git a/tests/config/obs_tests/main_config_NODE_STATUSES.yaml b/tests/config/obs_tests/main_config_NODE_STATUSES.yaml index 25520ccc..8f2d9a38 100644 --- a/tests/config/obs_tests/main_config_NODE_STATUSES.yaml +++ b/tests/config/obs_tests/main_config_NODE_STATUSES.yaml @@ -5,89 +5,97 @@ # "STABLE_BASELINES3_PPO" # "STABLE_BASELINES3_A2C" # "GENERIC" -agentIdentifier: NONE +agent_identifier: NONE +# Sets How the Action Space is defined: +# "NODE" +# "ACL" +# "ANY" node and acl actions +action_type: ANY # Number of episodes to run per session -observationSpace: +num_episodes: 1 +# Number of time_steps per episode +num_steps: 5 + +observation_space: components: - name: NODE_STATUSES -numEpisodes: 1 + # Time delay between steps (for generic agents) -timeDelay: 1 -# Filename of the scenario / laydown -configFilename: one_node_states_on_off_lay_down_config.yaml +time_delay: 1 + # Type of session to be run (TRAINING or EVALUATION) -sessionType: TRAINING +session_type: TRAINING # Determine whether to load an agent from file -loadAgent: False +load_agent: False # File path and file name of agent if you're loading one in -agentLoadFile: C:\[Path]\[agent_saved_filename.zip] +agent_load_file: C:\[Path]\[agent_saved_filename.zip] # Environment config values # The high value for the observation space -observationSpaceHighValue: 1_000_000_000 +observation_space_high_value: 1_000_000_000 # Reward values # Generic -allOk: 0 +all_ok: 0 # Node Hardware State -offShouldBeOn: -10 -offShouldBeResetting: -5 -onShouldBeOff: -2 -onShouldBeResetting: -5 -resettingShouldBeOn: -5 -resettingShouldBeOff: -2 +off_should_be_on: -10 +off_should_be_resetting: -5 +on_should_be_off: -2 +on_should_be_resetting: -5 +resetting_should_be_on: -5 +resetting_should_be_off: -2 resetting: -3 # Node Software or Service State -goodShouldBePatching: 2 -goodShouldBeCompromised: 5 -goodShouldBeOverwhelmed: 5 -patchingShouldBeGood: -5 -patchingShouldBeCompromised: 2 -patchingShouldBeOverwhelmed: 2 +good_should_be_patching: 2 +good_should_be_compromised: 5 +good_should_be_overwhelmed: 5 +patching_should_be_good: -5 +patching_should_be_compromised: 2 +patching_should_be_overwhelmed: 2 patching: -3 -compromisedShouldBeGood: -20 -compromisedShouldBePatching: -20 -compromisedShouldBeOverwhelmed: -20 +compromised_should_be_good: -20 +compromised_should_be_patching: -20 +compromised_should_be_overwhelmed: -20 compromised: -20 -overwhelmedShouldBeGood: -20 -overwhelmedShouldBePatching: -20 -overwhelmedShouldBeCompromised: -20 +overwhelmed_should_be_good: -20 +overwhelmed_should_be_patching: -20 +overwhelmed_should_be_compromised: -20 overwhelmed: -20 # Node File System State -goodShouldBeRepairing: 2 -goodShouldBeRestoring: 2 -goodShouldBeCorrupt: 5 -goodShouldBeDestroyed: 10 -repairingShouldBeGood: -5 -repairingShouldBeRestoring: 2 -repairingShouldBeCorrupt: 2 -repairingShouldBeDestroyed: 0 +good_should_be_repairing: 2 +good_should_be_restoring: 2 +good_should_be_corrupt: 5 +good_should_be_destroyed: 10 +repairing_should_be_good: -5 +repairing_should_be_restoring: 2 +repairing_should_be_corrupt: 2 +repairing_should_be_destroyed: 0 repairing: -3 -restoringShouldBeGood: -10 -restoringShouldBeRepairing: -2 -restoringShouldBeCorrupt: 1 -restoringShouldBeDestroyed: 2 +restoring_should_be_good: -10 +restoring_should_be_repairing: -2 +restoring_should_be_corrupt: 1 +restoring_should_be_destroyed: 2 restoring: -6 -corruptShouldBeGood: -10 -corruptShouldBeRepairing: -10 -corruptShouldBeRestoring: -10 -corruptShouldBeDestroyed: 2 +corrupt_should_be_good: -10 +corrupt_should_be_repairing: -10 +corrupt_should_be_restoring: -10 +corrupt_should_be_destroyed: 2 corrupt: -10 -destroyedShouldBeGood: -20 -destroyedShouldBeRepairing: -20 -destroyedShouldBeRestoring: -20 -destroyedShouldBeCorrupt: -20 +destroyed_should_be_good: -20 +destroyed_should_be_repairing: -20 +destroyed_should_be_restoring: -20 +destroyed_should_be_corrupt: -20 destroyed: -20 scanning: -2 # IER status -redIerRunning: -5 -greenIerBlocked: -10 +red_ier_running: -5 +green_ier_blocked: -10 # Patching / Reset durations -osPatchingDuration: 5 # The time taken to patch the OS -nodeResetDuration: 5 # The time taken to reset a node (hardware) -servicePatchingDuration: 5 # The time taken to patch a service -fileSystemRepairingLimit: 5 # The time take to repair the file system -fileSystemRestoringLimit: 5 # The time take to restore the file system -fileSystemScanningLimit: 5 # The time taken to scan the file system +os_patching_duration: 5 # The time taken to patch the OS +node_reset_duration: 5 # The time taken to reset a node (hardware) +service_patching_duration: 5 # The time taken to patch a service +file_system_repairing_limit: 5 # The time take to repair the file system +file_system_restoring_limit: 5 # The time take to restore the file system +file_system_scanning_limit: 5 # The time taken to scan the file system diff --git a/tests/config/obs_tests/main_config_without_obs.yaml b/tests/config/obs_tests/main_config_without_obs.yaml index 43ee251f..e8bb49ea 100644 --- a/tests/config/obs_tests/main_config_without_obs.yaml +++ b/tests/config/obs_tests/main_config_without_obs.yaml @@ -5,85 +5,90 @@ # "STABLE_BASELINES3_PPO" # "STABLE_BASELINES3_A2C" # "GENERIC" -agentIdentifier: NONE +agent_identifier: NONE +# Sets How the Action Space is defined: +# "NODE" +# "ACL" +# "ANY" node and acl actions +action_type: ANY # Number of episodes to run per session -numEpisodes: 1 +num_episodes: 1 +# Number of time_steps per episode +num_steps: 5 # Time delay between steps (for generic agents) -timeDelay: 1 -# Filename of the scenario / laydown -configFilename: one_node_states_on_off_lay_down_config.yaml +time_delay: 1 # Type of session to be run (TRAINING or EVALUATION) -sessionType: TRAINING +session_type: TRAINING # Determine whether to load an agent from file -loadAgent: False +load_agent: False # File path and file name of agent if you're loading one in -agentLoadFile: C:\[Path]\[agent_saved_filename.zip] +agent_load_file: C:\[Path]\[agent_saved_filename.zip] # Environment config values # The high value for the observation space -observationSpaceHighValue: 1_000_000_000 +observation_space_high_value: 1_000_000_000 # Reward values # Generic -allOk: 0 +all_ok: 0 # Node Hardware State -offShouldBeOn: -10 -offShouldBeResetting: -5 -onShouldBeOff: -2 -onShouldBeResetting: -5 -resettingShouldBeOn: -5 -resettingShouldBeOff: -2 +off_should_be_on: -10 +off_should_be_resetting: -5 +on_should_be_off: -2 +on_should_be_resetting: -5 +resetting_should_be_on: -5 +resetting_should_be_off: -2 resetting: -3 # Node Software or Service State -goodShouldBePatching: 2 -goodShouldBeCompromised: 5 -goodShouldBeOverwhelmed: 5 -patchingShouldBeGood: -5 -patchingShouldBeCompromised: 2 -patchingShouldBeOverwhelmed: 2 +good_should_be_patching: 2 +good_should_be_compromised: 5 +good_should_be_overwhelmed: 5 +patching_should_be_good: -5 +patching_should_be_compromised: 2 +patching_should_be_overwhelmed: 2 patching: -3 -compromisedShouldBeGood: -20 -compromisedShouldBePatching: -20 -compromisedShouldBeOverwhelmed: -20 +compromised_should_be_good: -20 +compromised_should_be_patching: -20 +compromised_should_be_overwhelmed: -20 compromised: -20 -overwhelmedShouldBeGood: -20 -overwhelmedShouldBePatching: -20 -overwhelmedShouldBeCompromised: -20 +overwhelmed_should_be_good: -20 +overwhelmed_should_be_patching: -20 +overwhelmed_should_be_compromised: -20 overwhelmed: -20 # Node File System State -goodShouldBeRepairing: 2 -goodShouldBeRestoring: 2 -goodShouldBeCorrupt: 5 -goodShouldBeDestroyed: 10 -repairingShouldBeGood: -5 -repairingShouldBeRestoring: 2 -repairingShouldBeCorrupt: 2 -repairingShouldBeDestroyed: 0 +good_should_be_repairing: 2 +good_should_be_restoring: 2 +good_should_be_corrupt: 5 +good_should_be_destroyed: 10 +repairing_should_be_good: -5 +repairing_should_be_restoring: 2 +repairing_should_be_corrupt: 2 +repairing_should_be_destroyed: 0 repairing: -3 -restoringShouldBeGood: -10 -restoringShouldBeRepairing: -2 -restoringShouldBeCorrupt: 1 -restoringShouldBeDestroyed: 2 +restoring_should_be_good: -10 +restoring_should_be_repairing: -2 +restoring_should_be_corrupt: 1 +restoring_should_be_destroyed: 2 restoring: -6 -corruptShouldBeGood: -10 -corruptShouldBeRepairing: -10 -corruptShouldBeRestoring: -10 -corruptShouldBeDestroyed: 2 +corrupt_should_be_good: -10 +corrupt_should_be_repairing: -10 +corrupt_should_be_restoring: -10 +corrupt_should_be_destroyed: 2 corrupt: -10 -destroyedShouldBeGood: -20 -destroyedShouldBeRepairing: -20 -destroyedShouldBeRestoring: -20 -destroyedShouldBeCorrupt: -20 +destroyed_should_be_good: -20 +destroyed_should_be_repairing: -20 +destroyed_should_be_restoring: -20 +destroyed_should_be_corrupt: -20 destroyed: -20 scanning: -2 # IER status -redIerRunning: -5 -greenIerBlocked: -10 +red_ier_running: -5 +green_ier_blocked: -10 # Patching / Reset durations -osPatchingDuration: 5 # The time taken to patch the OS -nodeResetDuration: 5 # The time taken to reset a node (hardware) -servicePatchingDuration: 5 # The time taken to patch a service -fileSystemRepairingLimit: 5 # The time take to repair the file system -fileSystemRestoringLimit: 5 # The time take to restore the file system -fileSystemScanningLimit: 5 # The time taken to scan the file system +os_patching_duration: 5 # The time taken to patch the OS +node_reset_duration: 5 # The time taken to reset a node (hardware) +service_patching_duration: 5 # The time taken to patch a service +file_system_repairing_limit: 5 # The time take to repair the file system +file_system_restoring_limit: 5 # The time take to restore the file system +file_system_scanning_limit: 5 # The time taken to scan the file system diff --git a/tests/config/single_action_space_main_config.yaml b/tests/config/single_action_space_main_config.yaml index 42916390..967fdcce 100644 --- a/tests/config/single_action_space_main_config.yaml +++ b/tests/config/single_action_space_main_config.yaml @@ -14,7 +14,7 @@ action_type: ANY # Number of episodes to run per session num_episodes: 1 # Number of time_steps per episode -num_steps: 15 +num_steps: 5 # Time delay between steps (for generic agents) time_delay: 1 # Type of session to be run (TRAINING or EVALUATION) diff --git a/tests/test_observation_space.py b/tests/test_observation_space.py index 0df59b72..dbcdf2d6 100644 --- a/tests/test_observation_space.py +++ b/tests/test_observation_space.py @@ -16,10 +16,10 @@ from tests.conftest import _get_primaite_env_from_config def env(request): """Build Primaite environment for integration tests of observation space.""" marker = request.node.get_closest_marker("env_config_paths") - main_config_path = marker.args[0]["main_config_path"] + training_config_path = marker.args[0]["training_config_path"] lay_down_config_path = marker.args[0]["lay_down_config_path"] - env, _ = _get_primaite_env_from_config( - main_config_path=main_config_path, + env = _get_primaite_env_from_config( + training_config_path=training_config_path, lay_down_config_path=lay_down_config_path, ) yield env @@ -27,7 +27,7 @@ def env(request): @pytest.mark.env_config_paths( dict( - main_config_path=TEST_CONFIG_ROOT / "obs_tests/main_config_without_obs.yaml", + training_config_path=TEST_CONFIG_ROOT / "obs_tests/main_config_without_obs.yaml", lay_down_config_path=TEST_CONFIG_ROOT / "obs_tests/laydown.yaml", ) ) @@ -43,7 +43,7 @@ def test_default_obs_space(env: Primaite): @pytest.mark.env_config_paths( dict( - main_config_path=TEST_CONFIG_ROOT / "obs_tests/main_config_without_obs.yaml", + training_config_path=TEST_CONFIG_ROOT / "obs_tests/main_config_without_obs.yaml", lay_down_config_path=TEST_CONFIG_ROOT / "obs_tests/laydown.yaml", ) ) @@ -59,7 +59,7 @@ def test_registering_components(env: Primaite): @pytest.mark.env_config_paths( dict( - main_config_path=TEST_CONFIG_ROOT + training_config_path=TEST_CONFIG_ROOT / "obs_tests/main_config_NODE_LINK_TABLE.yaml", lay_down_config_path=TEST_CONFIG_ROOT / "obs_tests/laydown.yaml", ) @@ -140,7 +140,7 @@ class TestNodeLinkTable: @pytest.mark.env_config_paths( dict( - main_config_path=TEST_CONFIG_ROOT / "obs_tests/main_config_NODE_STATUSES.yaml", + training_config_path=TEST_CONFIG_ROOT / "obs_tests/main_config_NODE_STATUSES.yaml", lay_down_config_path=TEST_CONFIG_ROOT / "obs_tests/laydown.yaml", ) ) @@ -184,7 +184,7 @@ class TestNodeStatuses: @pytest.mark.env_config_paths( dict( - main_config_path=TEST_CONFIG_ROOT + training_config_path=TEST_CONFIG_ROOT / "obs_tests/main_config_LINK_TRAFFIC_LEVELS.yaml", lay_down_config_path=TEST_CONFIG_ROOT / "obs_tests/laydown.yaml", )