diff --git a/.gitignore b/.gitignore index 892751d9..8be60770 100644 --- a/.gitignore +++ b/.gitignore @@ -156,3 +156,4 @@ benchmark/output # src/primaite/notebooks/scratch.ipynb src/primaite/notebooks/scratch.py sandbox.py +sandbox.ipynb diff --git a/src/primaite/config/_package_data/example_config.yaml b/src/primaite/config/_package_data/example_config.yaml index 24f9945d..db0bca74 100644 --- a/src/primaite/config/_package_data/example_config.yaml +++ b/src/primaite/config/_package_data/example_config.yaml @@ -105,25 +105,25 @@ agents: num_files_per_folder: 1 num_nics_per_node: 2 nodes: - - node_ref: domain_controller + - node_hostname: domain_controller services: - - service_ref: domain_controller_dns_server - - node_ref: web_server + - service_name: DNSServer + - node_hostname: web_server services: - - service_ref: web_server_database_client - - node_ref: database_server + - service_name: web_server_database_client + - node_hostname: database_server services: - - service_ref: database_service + - service_name: database_service folders: - folder_name: database files: - file_name: database.db - - node_ref: backup_server + - node_hostname: backup_server # services: # - service_ref: backup_service - - node_ref: security_suite - - node_ref: client_1 - - node_ref: client_2 + - node_hostname: security_suite + - node_hostname: client_1 + - node_hostname: client_2 links: - link_ref: router_1___switch_1 - link_ref: router_1___switch_2 @@ -138,7 +138,7 @@ agents: acl: options: max_acl_rules: 10 - router_node_ref: router_1 + router_hostname: router_1 ip_address_order: - node_ref: domain_controller nic_num: 1 @@ -509,7 +509,7 @@ agents: - type: DATABASE_FILE_INTEGRITY weight: 0.5 options: - node_ref: database_server + node_hostname: database_server folder_name: database file_name: database.db @@ -517,8 +517,8 @@ agents: - type: WEB_SERVER_404_PENALTY weight: 0.5 options: - node_ref: web_server - service_ref: web_server_web_service + node_hostname: web_server + service_name: web_server_web_service agent_settings: diff --git a/src/primaite/game/agent/observations.py b/src/primaite/game/agent/observations.py index 767514b4..ac091b77 100644 --- a/src/primaite/game/agent/observations.py +++ b/src/primaite/game/agent/observations.py @@ -40,8 +40,7 @@ class AbstractObservation(ABC): def from_config(cls, config: Dict, game: "PrimaiteGame"): """Create this observation space component form a serialised format. - The `game` parameter is for a the PrimaiteGame object that spawns this component. During deserialisation, - a subclass of this class may need to translate from a 'reference' to a UUID. + The `game` parameter is for a the PrimaiteGame object that spawns this component. """ pass @@ -53,12 +52,12 @@ class FileObservation(AbstractObservation): """ Initialise file observation. - :param where: Store information about where in the simulation state dictionary to find the relevatn information. + :param where: Store information about where in the simulation state dictionary to find the relevant information. Optional. If None, this corresponds that the file does not exist and the observation will be populated with zeroes. A typical location for a file looks like this: - ['network','nodes',,'file_system', 'folders',,'files',] + ['network','nodes',,'file_system', 'folders',,'files',] :type where: Optional[List[str]] """ super().__init__() @@ -120,7 +119,7 @@ class ServiceObservation(AbstractObservation): zeroes. A typical location for a service looks like this: - `['network','nodes',,'services', ]` + `['network','nodes',,'services', ]` :type where: Optional[List[str]] """ super().__init__() @@ -162,7 +161,7 @@ class ServiceObservation(AbstractObservation): :return: Constructed service observation :rtype: ServiceObservation """ - return cls(where=parent_where + ["services", game.ref_map_services[config["service_ref"]]]) + return cls(where=parent_where + ["services", config["service_name"]]) class LinkObservation(AbstractObservation): @@ -179,7 +178,7 @@ class LinkObservation(AbstractObservation): zeroes. A typical location for a service looks like this: - `['network','nodes',,'servics', ]` + `['network','nodes',,'servics', ]` :type where: Optional[List[str]] """ super().__init__() @@ -242,7 +241,7 @@ class FolderObservation(AbstractObservation): :param where: Where in the simulation state dictionary to find the relevant information for this folder. A typical location for a file looks like this: - ['network','nodes',,'file_system', 'folders',] + ['network','nodes',,'file_system', 'folders',] :type where: Optional[List[str]] :param max_files: As size of the space must remain static, define max files that can be in this folder , defaults to 5 @@ -321,7 +320,7 @@ class FolderObservation(AbstractObservation): :type game: PrimaiteGame :param parent_where: Where in the simulation state dictionary to find the information about this folder's parent node. A typical location for a node ``where`` can be: - ['network','nodes',,'file_system'] + ['network','nodes',,'file_system'] :type parent_where: Optional[List[str]] :param num_files_per_folder: How many spaces for files are in this folder observation (to preserve static observation size) , defaults to 2 @@ -347,7 +346,7 @@ class NicObservation(AbstractObservation): :param where: Where in the simulation state dictionary to find the relevant information for this NIC. A typical example may look like this: - ['network','nodes',,'NICs',] + ['network','nodes',,'NICs',] If None, this denotes that the NIC does not exist and the observation will be populated with zeroes. :type where: Optional[Tuple[str]], optional """ @@ -384,12 +383,12 @@ class NicObservation(AbstractObservation): :param game: Reference to the PrimaiteGame object that spawned this observation. :type game: PrimaiteGame :param parent_where: Where in the simulation state dictionary to find the information about this NIC's parent - node. A typical location for a node ``where`` can be: ['network','nodes',] + node. A typical location for a node ``where`` can be: ['network','nodes',] :type parent_where: Optional[List[str]] :return: Constructed NIC observation :rtype: NicObservation """ - return cls(where=parent_where + ["NICs", config["nic_uuid"]]) + return cls(where=parent_where + ["NICs", config["nic_num"]]) class NodeObservation(AbstractObservation): @@ -412,9 +411,9 @@ class NodeObservation(AbstractObservation): :param where: Where in the simulation state dictionary for find relevant information for this observation. A typical location for a node looks like this: - ['network','nodes',]. If empty list, a default null observation will be output, defaults to [] + ['network','nodes',]. If empty list, a default null observation will be output, defaults to [] :type where: List[str], optional - :param services: Mapping between position in observation space and service UUID, defaults to {} + :param services: Mapping between position in observation space and service name, defaults to {} :type services: Dict[int,str], optional :param max_services: Max number of services that can be presented in observation space for this node , defaults to 2 @@ -423,7 +422,7 @@ class NodeObservation(AbstractObservation): :type folders: Dict[int,str], optional :param max_folders: Max number of folders in this node's obs space, defaults to 2 :type max_folders: int, optional - :param nics: Mapping between position in observation space and NIC UUID, defaults to {} + :param nics: Mapping between position in observation space and NIC idx, defaults to {} :type nics: Dict[int,str], optional :param max_nics: Max number of NICS in this node's obs space, defaults to 5 :type max_nics: int, optional @@ -541,11 +540,11 @@ class NodeObservation(AbstractObservation): :return: Constructed node observation :rtype: NodeObservation """ - node_uuid = game.ref_map_nodes[config["node_ref"]] + node_hostname = config["node_hostname"] if parent_where is None: - where = ["network", "nodes", node_uuid] + where = ["network", "nodes", node_hostname] else: - where = parent_where + ["nodes", node_uuid] + where = parent_where + ["nodes", node_hostname] svc_configs = config.get("services", {}) services = [ServiceObservation.from_config(config=c, game=game, parent_where=where) for c in svc_configs] @@ -556,8 +555,8 @@ class NodeObservation(AbstractObservation): ) for c in folder_configs ] - nic_uuids = game.simulation.network.nodes[node_uuid].nics.keys() - nic_configs = [{"nic_uuid": n for n in nic_uuids}] if nic_uuids else [] + # create some configs for the NIC observation in the format {"nic_num":1}, {"nic_num":2}, {"nic_num":3}, etc. + nic_configs = [{"nic_num": i for i in range(num_nics_per_node)}] nics = [NicObservation.from_config(config=c, game=game, parent_where=where) for c in nic_configs] logon_status = config.get("logon_status", False) return cls( @@ -598,7 +597,7 @@ class AclObservation(AbstractObservation): :type protocols: list[str] :param where: Where in the simulation state dictionary to find the relevant information for this ACL. A typical example may look like this: - ['network','nodes',,'acl','acl'] + ['network','nodes',,'acl','acl'] :type where: Optional[Tuple[str]], optional :param num_rules: , defaults to 10 :type num_rules: int, optional @@ -711,12 +710,12 @@ class AclObservation(AbstractObservation): nic_obj = node_obj.ethernet_port[nic_num] node_ip_to_idx[nic_obj.ip_address] = ip_idx + 2 - router_uuid = game.ref_map_nodes[config["router_node_ref"]] + router_hostname = config["router_hostname"] return cls( node_ip_to_id=node_ip_to_idx, ports=game.options.ports, protocols=game.options.protocols, - where=["network", "nodes", router_uuid, "acl", "acl"], + where=["network", "nodes", router_hostname, "acl", "acl"], num_rules=max_acl_rules, ) @@ -846,6 +845,7 @@ class UC2BlueObservation(AbstractObservation): :rtype: UC2BlueObservation """ node_configs = config["nodes"] + num_services_per_node = config["num_services_per_node"] num_folders_per_node = config["num_folders_per_node"] num_files_per_folder = config["num_files_per_folder"] diff --git a/src/primaite/game/agent/rewards.py b/src/primaite/game/agent/rewards.py index 9b3dfb80..e2c7d6fc 100644 --- a/src/primaite/game/agent/rewards.py +++ b/src/primaite/game/agent/rewards.py @@ -82,11 +82,11 @@ class DummyReward(AbstractReward): class DatabaseFileIntegrity(AbstractReward): """Reward function component which rewards the agent for maintaining the integrity of a database file.""" - def __init__(self, node_uuid: str, folder_name: str, file_name: str) -> None: + def __init__(self, node_hostname: str, folder_name: str, file_name: str) -> None: """Initialise the reward component. - :param node_uuid: UUID of the node which contains the database file. - :type node_uuid: str + :param node_hostname: Hostname of the node which contains the database file. + :type node_hostname: str :param folder_name: folder which contains the database file. :type folder_name: str :param file_name: name of the database file. @@ -95,7 +95,7 @@ class DatabaseFileIntegrity(AbstractReward): self.location_in_state = [ "network", "nodes", - node_uuid, + node_hostname, "file_system", "folders", folder_name, @@ -129,49 +129,29 @@ class DatabaseFileIntegrity(AbstractReward): :return: The reward component. :rtype: DatabaseFileIntegrity """ - node_ref = config.get("node_ref") + node_hostname = config.get("node_hostname") folder_name = config.get("folder_name") file_name = config.get("file_name") - if not node_ref: - _LOGGER.error( - f"{cls.__name__} could not be initialised from config because node_ref parameter was not specified" - ) - return DummyReward() # TODO: better error handling - if not folder_name: - _LOGGER.error( - f"{cls.__name__} could not be initialised from config because folder_name parameter was not specified" - ) - return DummyReward() # TODO: better error handling - if not file_name: - _LOGGER.error( - f"{cls.__name__} could not be initialised from config because file_name parameter was not specified" - ) - return DummyReward() # TODO: better error handling - node_uuid = game.ref_map_nodes[node_ref] - if not node_uuid: - _LOGGER.error( - ( - f"{cls.__name__} could not be initialised from config because the referenced node could not be " - f"found in the simulation" - ) - ) - return DummyReward() # TODO: better error handling + if not node_hostname and folder_name and file_name: + msg = f"{cls.__name__} could not be initialised with parameters {config}" + _LOGGER.error(msg) + raise ValueError(msg) - return cls(node_uuid=node_uuid, folder_name=folder_name, file_name=file_name) + return cls(node_hostname=node_hostname, folder_name=folder_name, file_name=file_name) class WebServer404Penalty(AbstractReward): """Reward function component which penalises the agent when the web server returns a 404 error.""" - def __init__(self, node_uuid: str, service_uuid: str) -> None: + def __init__(self, node_hostname: str, service_name: str) -> None: """Initialise the reward component. - :param node_uuid: UUID of the node which contains the web server service. - :type node_uuid: str - :param service_uuid: UUID of the web server service. - :type service_uuid: str + :param node_hostname: Hostname of the node which contains the web server service. + :type node_hostname: str + :param service_node: Name of the web server service. + :type service_node: str """ - self.location_in_state = ["network", "nodes", node_uuid, "services", service_uuid] + self.location_in_state = ["network", "nodes", node_hostname, "services", service_name] def calculate(self, state: Dict) -> float: """Calculate the reward for the current state. @@ -203,26 +183,17 @@ class WebServer404Penalty(AbstractReward): :return: The reward component. :rtype: WebServer404Penalty """ - node_ref = config.get("node_ref") - service_ref = config.get("service_ref") - if not (node_ref and service_ref): + node_hostname = config.get("node_hostname") + service_name = config.get("service_name") + if not (node_hostname and service_name): msg = ( f"{cls.__name__} could not be initialised from config because node_ref and service_ref were not " "found in reward config." ) _LOGGER.warning(msg) - return DummyReward() # TODO: should we error out with incorrect inputs? Probably! - node_uuid = game.ref_map_nodes[node_ref] - service_uuid = game.ref_map_services[service_ref] - if not (node_uuid and service_uuid): - msg = ( - f"{cls.__name__} could not be initialised because node {node_ref} and service {service_ref} were not" - " found in the simulator." - ) - _LOGGER.warning(msg) - return DummyReward() # TODO: consider erroring here as well + raise ValueError(msg) - return cls(node_uuid=node_uuid, service_uuid=service_uuid) + return cls(node_hostname=node_hostname, service_name=service_name) class RewardFunction: diff --git a/src/primaite/simulator/domain/controller.py b/src/primaite/simulator/domain/controller.py index e9f3b26d..bc428743 100644 --- a/src/primaite/simulator/domain/controller.py +++ b/src/primaite/simulator/domain/controller.py @@ -102,7 +102,7 @@ class DomainController(SimComponent): :rtype: Dict """ state = super().describe_state() - state.update({"accounts": {uuid: acct.describe_state() for uuid, acct in self.accounts.items()}}) + state.update({"accounts": {acct.username: acct.describe_state() for acct in self.accounts.values()}}) return state def _register_account(self, account: Account) -> None: diff --git a/src/primaite/simulator/network/container.py b/src/primaite/simulator/network/container.py index e1780448..8d8709d3 100644 --- a/src/primaite/simulator/network/container.py +++ b/src/primaite/simulator/network/container.py @@ -199,10 +199,24 @@ class Network(SimComponent): state = super().describe_state() state.update( { - "nodes": {uuid: node.describe_state() for uuid, node in self.nodes.items()}, - "links": {uuid: link.describe_state() for uuid, link in self.links.items()}, + "nodes": {node.hostname: node.describe_state() for node in self.nodes.values()}, + "links": {}, } ) + # Update the links one-by-one. The key is a 4-tuple of `hostname_a, port_a, hostname_b, port_b` + for uuid, link in self.links.items(): + node_a = link.endpoint_a._connected_node + node_b = link.endpoint_b._connected_node + hostname_a = node_a.hostname if node_a else None + hostname_b = node_b.hostname if node_b else None + port_a = link.endpoint_a._port_num_on_node + port_b = link.endpoint_b._port_num_on_node + state["links"][uuid] = link.describe_state() + state["links"][uuid]["hostname_a"] = hostname_a + state["links"][uuid]["hostname_b"] = hostname_b + state["links"][uuid]["port_a"] = port_a + state["links"][uuid]["port_b"] = port_b + return state def add_node(self, node: Node) -> None: diff --git a/src/primaite/simulator/network/hardware/base.py b/src/primaite/simulator/network/hardware/base.py index a310a3f5..ad3d73aa 100644 --- a/src/primaite/simulator/network/hardware/base.py +++ b/src/primaite/simulator/network/hardware/base.py @@ -91,6 +91,8 @@ class NIC(SimComponent): "Indicates if the NIC supports Wake-on-LAN functionality." _connected_node: Optional[Node] = None "The Node to which the NIC is connected." + _port_num_on_node: Optional[int] = None + "Which port number is assigned on this NIC" _connected_link: Optional[Link] = None "The Link to which the NIC is connected." enabled: bool = False @@ -148,7 +150,7 @@ class NIC(SimComponent): state = super().describe_state() state.update( { - "ip_adress": str(self.ip_address), + "ip_address": str(self.ip_address), "subnet_mask": str(self.subnet_mask), "mac_address": self.mac_address, "speed": self.speed, @@ -311,6 +313,8 @@ class SwitchPort(SimComponent): "The Maximum Transmission Unit (MTU) of the SwitchPort in Bytes. Default is 1500 B" _connected_node: Optional[Node] = None "The Node to which the SwitchPort is connected." + _port_num_on_node: Optional[int] = None + "The port num on the connected node." _connected_link: Optional[Link] = None "The Link to which the SwitchPort is connected." enabled: bool = False @@ -497,8 +501,8 @@ class Link(SimComponent): state = super().describe_state() state.update( { - "endpoint_a": self.endpoint_a.uuid, - "endpoint_b": self.endpoint_b.uuid, + "endpoint_a": self.endpoint_a.uuid, # TODO: consider if using UUID is the best way to do this + "endpoint_b": self.endpoint_b.uuid, # TODO: consider if using UUID is the best way to do this "bandwidth": self.bandwidth, "current_load": self.current_load, } @@ -1094,12 +1098,12 @@ class Node(SimComponent): { "hostname": self.hostname, "operating_state": self.operating_state.value, - "NICs": {uuid: nic.describe_state() for uuid, nic in self.nics.items()}, + "NICs": {eth_num: nic.describe_state() for eth_num, nic in self.ethernet_port.items()}, # "switch_ports": {uuid, sp for uuid, sp in self.switch_ports.items()}, "file_system": self.file_system.describe_state(), - "applications": {uuid: app.describe_state() for uuid, app in self.applications.items()}, - "services": {uuid: svc.describe_state() for uuid, svc in self.services.items()}, - "process": {uuid: proc.describe_state() for uuid, proc in self.processes.items()}, + "applications": {app.name: app.describe_state() for app in self.applications.values()}, + "services": {svc.name: svc.describe_state() for svc in self.services.values()}, + "process": {proc.name: proc.describe_state() for proc in self.processes.values()}, "revealed_to_red": self.revealed_to_red, } ) @@ -1316,6 +1320,7 @@ class Node(SimComponent): self.nics[nic.uuid] = nic self.ethernet_port[len(self.nics)] = nic nic._connected_node = self + nic._port_num_on_node = len(self.nics) nic.parent = self self.sys_log.info(f"Connected NIC {nic}") if self.operating_state == NodeOperatingState.ON: diff --git a/src/primaite/simulator/network/hardware/nodes/switch.py b/src/primaite/simulator/network/hardware/nodes/switch.py index 92999b88..fffae6e2 100644 --- a/src/primaite/simulator/network/hardware/nodes/switch.py +++ b/src/primaite/simulator/network/hardware/nodes/switch.py @@ -30,6 +30,7 @@ class Switch(Node): self.switch_ports = {i: SwitchPort() for i in range(1, self.num_ports + 1)} for port_num, port in self.switch_ports.items(): port._connected_node = self + port._port_num_on_node = port_num port.parent = self port.port_num = port_num diff --git a/src/primaite/simulator/system/processes/process.py b/src/primaite/simulator/system/processes/process.py index ad9af335..b753e3ad 100644 --- a/src/primaite/simulator/system/processes/process.py +++ b/src/primaite/simulator/system/processes/process.py @@ -41,5 +41,5 @@ class Process(Software): :rtype: Dict """ state = super().describe_state() - state.update({"operating_state": self.operating_state.name}) + state.update({"operating_state": self.operating_state.value}) return state diff --git a/tests/assets/configs/bad_primaite_session.yaml b/tests/assets/configs/bad_primaite_session.yaml index 9070f246..478cbfae 100644 --- a/tests/assets/configs/bad_primaite_session.yaml +++ b/tests/assets/configs/bad_primaite_session.yaml @@ -93,25 +93,25 @@ agents: num_files_per_folder: 1 num_nics_per_node: 2 nodes: - - node_ref: domain_controller + - node_hostname: domain_controller services: - - service_ref: domain_controller_dns_server - - node_ref: web_server + - service_name: domain_controller_dns_server + - node_hostname: web_server services: - - service_ref: web_server_database_client - - node_ref: database_server + - service_name: web_server_database_client + - node_hostname: database_server services: - - service_ref: database_service + - service_name: database_service folders: - folder_name: database files: - file_name: database.db - - node_ref: backup_server + - node_hostname: backup_server # services: # - service_ref: backup_service - - node_ref: security_suite - - node_ref: client_1 - - node_ref: client_2 + - node_hostname: security_suite + - node_hostname: client_1 + - node_hostname: client_2 links: - link_ref: router_1___switch_1 - link_ref: router_1___switch_2 @@ -126,7 +126,7 @@ agents: acl: options: max_acl_rules: 10 - router_node_ref: router_1 + router_hostname: router_1 ip_address_order: - node_ref: domain_controller nic_num: 1 @@ -497,7 +497,7 @@ agents: - type: DATABASE_FILE_INTEGRITY weight: 0.5 options: - node_ref: database_server + node_hostname: database_server folder_name: database file_name: database.db @@ -505,8 +505,8 @@ agents: - type: WEB_SERVER_404_PENALTY weight: 0.5 options: - node_ref: web_server - service_ref: web_server_web_service + node_hostname: web_server + service_name: web_server_web_service agent_settings: diff --git a/tests/assets/configs/eval_only_primaite_session.yaml b/tests/assets/configs/eval_only_primaite_session.yaml index e67f6606..ec6bfb63 100644 --- a/tests/assets/configs/eval_only_primaite_session.yaml +++ b/tests/assets/configs/eval_only_primaite_session.yaml @@ -31,13 +31,6 @@ agents: action_space: action_list: - type: DONOTHING - # - # - type: NODE_LOGON - # - type: NODE_LOGOFF - # - type: NODE_APPLICATION_EXECUTE - # options: - # execution_definition: - # target_address: arcd.com options: nodes: @@ -104,25 +97,25 @@ agents: num_files_per_folder: 1 num_nics_per_node: 2 nodes: - - node_ref: domain_controller + - node_hostname: domain_controller services: - - service_ref: domain_controller_dns_server - - node_ref: web_server + - service_name: domain_controller_dns_server + - node_hostname: web_server services: - - service_ref: web_server_database_client - - node_ref: database_server + - service_name: web_server_database_client + - node_hostname: database_server services: - - service_ref: database_service + - service_name: database_service folders: - folder_name: database files: - file_name: database.db - - node_ref: backup_server + - node_hostname: backup_server # services: # - service_ref: backup_service - - node_ref: security_suite - - node_ref: client_1 - - node_ref: client_2 + - node_hostname: security_suite + - node_hostname: client_1 + - node_hostname: client_2 links: - link_ref: router_1___switch_1 - link_ref: router_1___switch_2 @@ -137,7 +130,7 @@ agents: acl: options: max_acl_rules: 10 - router_node_ref: router_1 + router_hostname: router_1 ip_address_order: - node_ref: domain_controller nic_num: 1 @@ -508,7 +501,7 @@ agents: - type: DATABASE_FILE_INTEGRITY weight: 0.5 options: - node_ref: database_server + node_hostname: database_server folder_name: database file_name: database.db @@ -516,8 +509,8 @@ agents: - type: WEB_SERVER_404_PENALTY weight: 0.5 options: - node_ref: web_server - service_ref: web_server_web_service + node_hostname: web_server + service_name: web_server_web_service agent_settings: diff --git a/tests/assets/configs/multi_agent_session.yaml b/tests/assets/configs/multi_agent_session.yaml index 220ca21e..3671b809 100644 --- a/tests/assets/configs/multi_agent_session.yaml +++ b/tests/assets/configs/multi_agent_session.yaml @@ -37,13 +37,6 @@ agents: action_space: action_list: - type: DONOTHING - # - # - type: NODE_LOGON - # - type: NODE_LOGOFF - # - type: NODE_APPLICATION_EXECUTE - # options: - # execution_definition: - # target_address: arcd.com options: nodes: @@ -111,25 +104,25 @@ agents: num_files_per_folder: 1 num_nics_per_node: 2 nodes: - - node_ref: domain_controller + - node_hostname: domain_controller services: - - service_ref: domain_controller_dns_server - - node_ref: web_server + - service_name: domain_controller_dns_server + - node_hostname: web_server services: - - service_ref: web_server_database_client - - node_ref: database_server + - service_name: web_server_database_client + - node_hostname: database_server services: - - service_ref: database_service + - service_name: database_service folders: - folder_name: database files: - file_name: database.db - - node_ref: backup_server + - node_hostname: backup_server # services: # - service_ref: backup_service - - node_ref: security_suite - - node_ref: client_1 - - node_ref: client_2 + - node_hostname: security_suite + - node_hostname: client_1 + - node_hostname: client_2 links: - link_ref: router_1___switch_1 - link_ref: router_1___switch_2 @@ -144,7 +137,7 @@ agents: acl: options: max_acl_rules: 10 - router_node_ref: router_1 + router_hostname: router_1 ip_address_order: - node_ref: domain_controller nic_num: 1 @@ -515,7 +508,7 @@ agents: - type: DATABASE_FILE_INTEGRITY weight: 0.5 options: - node_ref: database_server + node_hostname: database_server folder_name: database file_name: database.db @@ -523,8 +516,8 @@ agents: - type: WEB_SERVER_404_PENALTY weight: 0.5 options: - node_ref: web_server - service_ref: web_server_web_service + node_hostname: web_server + service_name: web_server_web_service agent_settings: @@ -542,25 +535,25 @@ agents: num_files_per_folder: 1 num_nics_per_node: 2 nodes: - - node_ref: domain_controller + - node_hostname: domain_controller services: - - service_ref: domain_controller_dns_server - - node_ref: web_server + - service_name: domain_controller_dns_server + - node_hostname: web_server services: - - service_ref: web_server_database_client - - node_ref: database_server + - service_name: web_server_database_client + - node_hostname: database_server services: - - service_ref: database_service + - service_name: database_service folders: - folder_name: database files: - file_name: database.db - - node_ref: backup_server + - node_hostname: backup_server # services: # - service_ref: backup_service - - node_ref: security_suite - - node_ref: client_1 - - node_ref: client_2 + - node_hostname: security_suite + - node_hostname: client_1 + - node_hostname: client_2 links: - link_ref: router_1___switch_1 - link_ref: router_1___switch_2 @@ -575,7 +568,7 @@ agents: acl: options: max_acl_rules: 10 - router_node_ref: router_1 + router_hostname: router_1 ip_address_order: - node_ref: domain_controller nic_num: 1 @@ -946,7 +939,7 @@ agents: - type: DATABASE_FILE_INTEGRITY weight: 0.5 options: - node_ref: database_server + node_hostname: database_server folder_name: database file_name: database.db @@ -954,8 +947,8 @@ agents: - type: WEB_SERVER_404_PENALTY weight: 0.5 options: - node_ref: web_server - service_ref: web_server_web_service + node_hostname: web_server + service_name: web_server_web_service agent_settings: diff --git a/tests/assets/configs/test_primaite_session.yaml b/tests/assets/configs/test_primaite_session.yaml index d7e94cb6..cc198a64 100644 --- a/tests/assets/configs/test_primaite_session.yaml +++ b/tests/assets/configs/test_primaite_session.yaml @@ -35,13 +35,6 @@ agents: action_space: action_list: - type: DONOTHING - # - # - type: NODE_LOGON - # - type: NODE_LOGOFF - # - type: NODE_APPLICATION_EXECUTE - # options: - # execution_definition: - # target_address: arcd.com options: nodes: @@ -109,25 +102,25 @@ agents: num_files_per_folder: 1 num_nics_per_node: 2 nodes: - - node_ref: domain_controller + - node_hostname: domain_controller services: - - service_ref: domain_controller_dns_server - - node_ref: web_server + - service_name: domain_controller_dns_server + - node_hostname: web_server services: - - service_ref: web_server_database_client - - node_ref: database_server + - service_name: web_server_database_client + - node_hostname: database_server services: - - service_ref: database_service + - service_name: database_service folders: - folder_name: database files: - file_name: database.db - - node_ref: backup_server + - node_hostname: backup_server # services: - # - service_ref: backup_service - - node_ref: security_suite - - node_ref: client_1 - - node_ref: client_2 + # - service_name: backup_service + - node_hostname: security_suite + - node_hostname: client_1 + - node_hostname: client_2 links: - link_ref: router_1___switch_1 - link_ref: router_1___switch_2 @@ -142,7 +135,7 @@ agents: acl: options: max_acl_rules: 10 - router_node_ref: router_1 + router_hostname: router_1 ip_address_order: - node_ref: domain_controller nic_num: 1 @@ -513,7 +506,7 @@ agents: - type: DATABASE_FILE_INTEGRITY weight: 0.5 options: - node_ref: database_server + node_hostname: database_server folder_name: database file_name: database.db @@ -521,8 +514,8 @@ agents: - type: WEB_SERVER_404_PENALTY weight: 0.5 options: - node_ref: web_server - service_ref: web_server_web_service + node_hostname: web_server + service_name: web_server_web_service agent_settings: diff --git a/tests/assets/configs/train_only_primaite_session.yaml b/tests/assets/configs/train_only_primaite_session.yaml index b89349c0..ebef7f6a 100644 --- a/tests/assets/configs/train_only_primaite_session.yaml +++ b/tests/assets/configs/train_only_primaite_session.yaml @@ -105,25 +105,23 @@ agents: num_files_per_folder: 1 num_nics_per_node: 2 nodes: - - node_ref: domain_controller + - node_hostname: domain_controller services: - - service_ref: domain_controller_dns_server - - node_ref: web_server + - service_name: domain_controller_dns_server + - node_hostname: web_server services: - - service_ref: web_server_database_client - - node_ref: database_server + - service_name: web_server_database_client + - node_hostname: database_server services: - - service_ref: database_service + - service_name: database_service folders: - folder_name: database files: - file_name: database.db - - node_ref: backup_server - # services: - # - service_ref: backup_service - - node_ref: security_suite - - node_ref: client_1 - - node_ref: client_2 + - node_hostname: backup_server + - node_hostname: security_suite + - node_hostname: client_1 + - node_hostname: client_2 links: - link_ref: router_1___switch_1 - link_ref: router_1___switch_2 @@ -138,7 +136,7 @@ agents: acl: options: max_acl_rules: 10 - router_node_ref: router_1 + router_hostname: router_1 ip_address_order: - node_ref: domain_controller nic_num: 1 @@ -509,7 +507,7 @@ agents: - type: DATABASE_FILE_INTEGRITY weight: 0.5 options: - node_ref: database_server + node_hostname: database_server folder_name: database file_name: database.db @@ -517,8 +515,8 @@ agents: - type: WEB_SERVER_404_PENALTY weight: 0.5 options: - node_ref: web_server - service_ref: web_server_web_service + node_hostname: web_server + service_name: web_service agent_settings: diff --git a/tests/integration_tests/game_layer/test_observations.py b/tests/integration_tests/game_layer/test_observations.py index 97154f62..07f3d25c 100644 --- a/tests/integration_tests/game_layer/test_observations.py +++ b/tests/integration_tests/game_layer/test_observations.py @@ -14,7 +14,7 @@ def test_file_observation(): state = sim.describe_state() dog_file_obs = FileObservation( - where=["network", "nodes", pc.uuid, "file_system", "folders", "root", "files", "dog.png"] + where=["network", "nodes", pc.hostname, "file_system", "folders", "root", "files", "dog.png"] ) assert dog_file_obs.observe(state) == {"health_status": 1} assert dog_file_obs.space == spaces.Dict({"health_status": spaces.Discrete(6)})