832 lines
48 KiB
Plaintext
832 lines
48 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"%load_ext autoreload\n",
|
|
"%autoreload 2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from primaite.game.session import PrimaiteSession\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"from primaite import _PRIMAITE_CONFIG, PRIMAITE_PATHS\n",
|
|
"import logging\n",
|
|
"_PRIMAITE_CONFIG['log_level']=logging.DEBUG\n",
|
|
"print(PRIMAITE_PATHS.app_log_dir_path)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import itertools"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from primaite.game.session import PrimaiteSession\n",
|
|
"from primaite.simulator.sim_container import Simulation\n",
|
|
"from primaite.game.agent.interface import AbstractAgent\n",
|
|
"from primaite.simulator.network.networks import arcd_uc2_network\n",
|
|
"import yaml\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"with open('example_config.yaml', 'r') as file:\n",
|
|
" cfg = yaml.safe_load(file)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"2023-10-08 17:56:35,831: Added node af2f9c15-ecb4-4b65-b48f-63f12acddb88 to Network cbd56fbb-104f-4823-9ee6-f4a968343b31\n",
|
|
"2023-10-08 17:56:35,836: Added node 47158854-0917-4037-a6a2-33dde56a120f to Network cbd56fbb-104f-4823-9ee6-f4a968343b31\n",
|
|
"2023-10-08 17:56:35,840: Added node cba8ce63-8064-4f80-bcfe-95ca65221dfa to Network cbd56fbb-104f-4823-9ee6-f4a968343b31\n",
|
|
"2023-10-08 17:56:35,846: Added node e01e7c2b-02ac-4e2d-b7bb-8bc3b6ea6509 to Network cbd56fbb-104f-4823-9ee6-f4a968343b31\n",
|
|
"2023-10-08 17:56:35,857: Added node bd5d85ba-5980-45c7-8b28-020a2cfeba0f to Network cbd56fbb-104f-4823-9ee6-f4a968343b31\n",
|
|
"2023-10-08 17:56:35,863: Added node 39e0e37c-4d72-4c76-93cb-4f9c29651ef4 to Network cbd56fbb-104f-4823-9ee6-f4a968343b31\n",
|
|
"2023-10-08 17:56:35,878: Added node 7d1063f9-b5e5-4753-966e-1b630325b266 to Network cbd56fbb-104f-4823-9ee6-f4a968343b31\n",
|
|
"2023-10-08 17:56:35,881: Added node d85b6abb-0f9e-4853-af26-c9b410e1cb94 to Network cbd56fbb-104f-4823-9ee6-f4a968343b31\n",
|
|
"2023-10-08 17:56:35,884: Added node 63b18888-98aa-4182-a014-02999d095bd0 to Network cbd56fbb-104f-4823-9ee6-f4a968343b31\n",
|
|
"2023-10-08 17:56:35,888: Added node f514cf8a-a3f1-46d6-be00-994364241ef4 to Network cbd56fbb-104f-4823-9ee6-f4a968343b31\n",
|
|
"2023-10-08 17:56:35,890: NIC 27:a9:09:ed:30:5a/192.168.1.1 connected to Link 27:a9:09:ed:30:5a/192.168.1.1<-->cb:6f:24:8c:7a:20\n",
|
|
"2023-10-08 17:56:35,891: SwitchPort cb:6f:24:8c:7a:20 connected to Link 27:a9:09:ed:30:5a/192.168.1.1<-->cb:6f:24:8c:7a:20\n",
|
|
"2023-10-08 17:56:35,893: Link 27:a9:09:ed:30:5a/192.168.1.1<-->cb:6f:24:8c:7a:20 up\n",
|
|
"2023-10-08 17:56:35,896: Link 27:a9:09:ed:30:5a/192.168.1.1<-->cb:6f:24:8c:7a:20 up\n",
|
|
"2023-10-08 17:56:35,897: Added link 41d994cb-2976-4aa2-b306-649cef4deb80 to connect 27:a9:09:ed:30:5a/192.168.1.1 and cb:6f:24:8c:7a:20\n",
|
|
"2023-10-08 17:56:35,899: NIC 5c:fa:b1:a4:69:ec/192.168.1.1 connected to Link 5c:fa:b1:a4:69:ec/192.168.1.1<-->68:54:d7:42:04:87\n",
|
|
"2023-10-08 17:56:35,900: SwitchPort 68:54:d7:42:04:87 connected to Link 5c:fa:b1:a4:69:ec/192.168.1.1<-->68:54:d7:42:04:87\n",
|
|
"2023-10-08 17:56:35,901: Link 5c:fa:b1:a4:69:ec/192.168.1.1<-->68:54:d7:42:04:87 up\n",
|
|
"2023-10-08 17:56:35,903: Link 5c:fa:b1:a4:69:ec/192.168.1.1<-->68:54:d7:42:04:87 up\n",
|
|
"2023-10-08 17:56:35,904: Added link d582a248-e968-40eb-9d1b-67143d729e0c to connect 5c:fa:b1:a4:69:ec/192.168.1.1 and 68:54:d7:42:04:87\n",
|
|
"2023-10-08 17:56:35,905: SwitchPort c6:bd:77:78:4b:5d connected to Link c6:bd:77:78:4b:5d<-->1c:d9:92:e8:d6:3b/192.168.1.10\n",
|
|
"2023-10-08 17:56:35,908: Link c6:bd:77:78:4b:5d<-->1c:d9:92:e8:d6:3b/192.168.1.10 up\n",
|
|
"2023-10-08 17:56:35,909: NIC 1c:d9:92:e8:d6:3b/192.168.1.10 connected to Link c6:bd:77:78:4b:5d<-->1c:d9:92:e8:d6:3b/192.168.1.10\n",
|
|
"2023-10-08 17:56:35,911: Link c6:bd:77:78:4b:5d<-->1c:d9:92:e8:d6:3b/192.168.1.10 up\n",
|
|
"2023-10-08 17:56:35,912: Added link 13315780-1fcc-4c85-b94b-ef8f14c88a8a to connect c6:bd:77:78:4b:5d and 1c:d9:92:e8:d6:3b/192.168.1.10\n",
|
|
"2023-10-08 17:56:35,913: SwitchPort cd:46:af:c4:33:65 connected to Link cd:46:af:c4:33:65<-->aa:cf:2f:71:13:5b/192.168.1.12\n",
|
|
"2023-10-08 17:56:35,916: Link cd:46:af:c4:33:65<-->aa:cf:2f:71:13:5b/192.168.1.12 up\n",
|
|
"2023-10-08 17:56:35,917: NIC aa:cf:2f:71:13:5b/192.168.1.12 connected to Link cd:46:af:c4:33:65<-->aa:cf:2f:71:13:5b/192.168.1.12\n",
|
|
"2023-10-08 17:56:35,918: Link cd:46:af:c4:33:65<-->aa:cf:2f:71:13:5b/192.168.1.12 up\n",
|
|
"2023-10-08 17:56:35,919: Added link 6c2a80f7-f36d-4df6-ac84-d354e5d517dd to connect cd:46:af:c4:33:65 and aa:cf:2f:71:13:5b/192.168.1.12\n",
|
|
"2023-10-08 17:56:35,920: SwitchPort 2c:d2:67:ef:68:a8 connected to Link 2c:d2:67:ef:68:a8<-->e1:09:5e:98:ee:a2/192.168.1.14\n",
|
|
"2023-10-08 17:56:35,923: Link 2c:d2:67:ef:68:a8<-->e1:09:5e:98:ee:a2/192.168.1.14 up\n",
|
|
"2023-10-08 17:56:35,924: NIC e1:09:5e:98:ee:a2/192.168.1.14 connected to Link 2c:d2:67:ef:68:a8<-->e1:09:5e:98:ee:a2/192.168.1.14\n",
|
|
"2023-10-08 17:56:35,925: Link 2c:d2:67:ef:68:a8<-->e1:09:5e:98:ee:a2/192.168.1.14 up\n",
|
|
"2023-10-08 17:56:35,926: Added link 1cfdd4f2-22be-4e69-8f1f-daef8e18f543 to connect 2c:d2:67:ef:68:a8 and e1:09:5e:98:ee:a2/192.168.1.14\n",
|
|
"2023-10-08 17:56:35,927: SwitchPort 9b:13:8c:a0:8c:82 connected to Link 9b:13:8c:a0:8c:82<-->cc:c2:84:03:1c:42/192.168.1.16\n",
|
|
"2023-10-08 17:56:35,929: Link 9b:13:8c:a0:8c:82<-->cc:c2:84:03:1c:42/192.168.1.16 up\n",
|
|
"2023-10-08 17:56:35,930: NIC cc:c2:84:03:1c:42/192.168.1.16 connected to Link 9b:13:8c:a0:8c:82<-->cc:c2:84:03:1c:42/192.168.1.16\n",
|
|
"2023-10-08 17:56:35,932: Link 9b:13:8c:a0:8c:82<-->cc:c2:84:03:1c:42/192.168.1.16 up\n",
|
|
"2023-10-08 17:56:35,933: Added link 031111e1-3b05-49ce-bd1f-2cdf77b210f4 to connect 9b:13:8c:a0:8c:82 and cc:c2:84:03:1c:42/192.168.1.16\n",
|
|
"2023-10-08 17:56:35,934: SwitchPort a1:70:9e:43:1c:07 connected to Link a1:70:9e:43:1c:07<-->e7:58:3c:ed:f7:37/192.168.1.110\n",
|
|
"2023-10-08 17:56:35,937: Link a1:70:9e:43:1c:07<-->e7:58:3c:ed:f7:37/192.168.1.110 up\n",
|
|
"2023-10-08 17:56:35,938: NIC e7:58:3c:ed:f7:37/192.168.1.110 connected to Link a1:70:9e:43:1c:07<-->e7:58:3c:ed:f7:37/192.168.1.110\n",
|
|
"2023-10-08 17:56:35,939: Link a1:70:9e:43:1c:07<-->e7:58:3c:ed:f7:37/192.168.1.110 up\n",
|
|
"2023-10-08 17:56:35,941: Added link f15884e7-0df6-4fa5-bb72-406cb2bdff45 to connect a1:70:9e:43:1c:07 and e7:58:3c:ed:f7:37/192.168.1.110\n",
|
|
"2023-10-08 17:56:35,943: SwitchPort a5:da:f2:03:21:e3 connected to Link a5:da:f2:03:21:e3<-->cf:63:9f:62:fe:df/192.168.10.21\n",
|
|
"2023-10-08 17:56:35,946: Link a5:da:f2:03:21:e3<-->cf:63:9f:62:fe:df/192.168.10.21 up\n",
|
|
"2023-10-08 17:56:35,947: NIC cf:63:9f:62:fe:df/192.168.10.21 connected to Link a5:da:f2:03:21:e3<-->cf:63:9f:62:fe:df/192.168.10.21\n",
|
|
"2023-10-08 17:56:35,948: Link a5:da:f2:03:21:e3<-->cf:63:9f:62:fe:df/192.168.10.21 up\n",
|
|
"2023-10-08 17:56:35,950: Added link cc6767fa-25de-4daa-bd47-37b49b15a881 to connect a5:da:f2:03:21:e3 and cf:63:9f:62:fe:df/192.168.10.21\n",
|
|
"2023-10-08 17:56:35,951: SwitchPort eb:5b:86:14:bd:d1 connected to Link eb:5b:86:14:bd:d1<-->3d:73:a6:62:97:3a/192.168.10.22\n",
|
|
"2023-10-08 17:56:35,953: Link eb:5b:86:14:bd:d1<-->3d:73:a6:62:97:3a/192.168.10.22 up\n",
|
|
"2023-10-08 17:56:35,954: NIC 3d:73:a6:62:97:3a/192.168.10.22 connected to Link eb:5b:86:14:bd:d1<-->3d:73:a6:62:97:3a/192.168.10.22\n",
|
|
"2023-10-08 17:56:35,955: Link eb:5b:86:14:bd:d1<-->3d:73:a6:62:97:3a/192.168.10.22 up\n",
|
|
"2023-10-08 17:56:35,958: Added link b29563ed-0636-4188-ba28-52b74a04da27 to connect eb:5b:86:14:bd:d1 and 3d:73:a6:62:97:3a/192.168.10.22\n",
|
|
"2023-10-08 17:56:35,959: SwitchPort e3:3a:0b:03:0b:8c connected to Link e3:3a:0b:03:0b:8c<-->d4:ff:37:8d:e4:3d/192.168.10.110\n",
|
|
"2023-10-08 17:56:35,961: Link e3:3a:0b:03:0b:8c<-->d4:ff:37:8d:e4:3d/192.168.10.110 up\n",
|
|
"2023-10-08 17:56:35,963: NIC d4:ff:37:8d:e4:3d/192.168.10.110 connected to Link e3:3a:0b:03:0b:8c<-->d4:ff:37:8d:e4:3d/192.168.10.110\n",
|
|
"2023-10-08 17:56:35,963: Link e3:3a:0b:03:0b:8c<-->d4:ff:37:8d:e4:3d/192.168.10.110 up\n",
|
|
"2023-10-08 17:56:35,964: Added link f6fe7757-a8c1-4cdc-a2b2-49d247117903 to connect e3:3a:0b:03:0b:8c and d4:ff:37:8d:e4:3d/192.168.10.110\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"service type not found DatabaseBackup\n",
|
|
"service type not found WebBrowser\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"sess = PrimaiteSession.from_config(cfg)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[<primaite.game.agent.interface.RandomAgent at 0x7f76ca118610>,\n",
|
|
" <primaite.game.agent.interface.RandomAgent at 0x7f76ca1188e0>,\n",
|
|
" <primaite.game.agent.interface.RandomAgent at 0x7f76ca1199f0>]"
|
|
]
|
|
},
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"sess.agents"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"network = sess.simulation.network"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"2023-10-08 17:56:36,041: Stepping primaite session. Step counter: 0\n",
|
|
"2023-10-08 17:56:36,043: Sending simulation state to agent client_1_green_user\n",
|
|
"2023-10-08 17:56:36,045: Getting agent action\n",
|
|
"2023-10-08 17:56:36,047: Formatting agent action DONOTHING\n",
|
|
"2023-10-08 17:56:36,048: Sending request to simulation: ['do_nothing']\n",
|
|
"2023-10-08 17:56:36,050: Sending simulation state to agent client_1_data_manipulation_red_bot\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[<primaite.game.agent.observations.ServiceObservation object at 0x7f76ca118700>]\n",
|
|
"[]\n"
|
|
]
|
|
},
|
|
{
|
|
"ename": "TypeError",
|
|
"evalue": "unhashable type: 'DataManipulationBot'",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m/home/cade/repos/PrimAITE/sandbox.ipynb Cell 10\u001b[0m line \u001b[0;36m1\n\u001b[0;32m----> <a href='vscode-notebook-cell://wsl%2Bubuntu/home/cade/repos/PrimAITE/sandbox.ipynb#X11sdnNjb2RlLXJlbW90ZQ%3D%3D?line=0'>1</a>\u001b[0m sess\u001b[39m.\u001b[39;49mstep()\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/session.py:80\u001b[0m, in \u001b[0;36mPrimaiteSession.step\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 77\u001b[0m sim_state \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39msimulation\u001b[39m.\u001b[39mdescribe_state()\n\u001b[1;32m 79\u001b[0m \u001b[39m# 6. each agent takes most recent state and converts it to CAOS observation\u001b[39;00m\n\u001b[0;32m---> 80\u001b[0m agent_obs \u001b[39m=\u001b[39m agent\u001b[39m.\u001b[39;49mconvert_state_to_obs(sim_state)\n\u001b[1;32m 82\u001b[0m \u001b[39m# 7. meanwhile each agent also takes state and calculates reward\u001b[39;00m\n\u001b[1;32m 83\u001b[0m agent_reward \u001b[39m=\u001b[39m agent\u001b[39m.\u001b[39mcalculate_reward_from_state(sim_state)\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/agent/interface.py:40\u001b[0m, in \u001b[0;36mAbstractAgent.convert_state_to_obs\u001b[0;34m(self, state)\u001b[0m\n\u001b[1;32m 35\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mconvert_state_to_obs\u001b[39m(\u001b[39mself\u001b[39m, state: Dict) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m ObsType:\n\u001b[1;32m 36\u001b[0m \u001b[39m \u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 37\u001b[0m \u001b[39m state : dict state directly from simulation.describe_state\u001b[39;00m\n\u001b[1;32m 38\u001b[0m \u001b[39m output : dict state according to CAOS.\u001b[39;00m\n\u001b[1;32m 39\u001b[0m \u001b[39m \"\"\"\u001b[39;00m\n\u001b[0;32m---> 40\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mobservation_space\u001b[39m.\u001b[39;49mobserve(state)\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/agent/observations.py:608\u001b[0m, in \u001b[0;36mObservationSpace.observe\u001b[0;34m(self, state)\u001b[0m\n\u001b[1;32m 607\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mobserve\u001b[39m(\u001b[39mself\u001b[39m, state) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m Dict:\n\u001b[0;32m--> 608\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mobs\u001b[39m.\u001b[39;49mobserve(state)\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/agent/observations.py:571\u001b[0m, in \u001b[0;36mUC2RedObservation.observe\u001b[0;34m(self, state)\u001b[0m\n\u001b[1;32m 568\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdefault_observation\n\u001b[1;32m 570\u001b[0m obs \u001b[39m=\u001b[39m {}\n\u001b[0;32m--> 571\u001b[0m obs[\u001b[39m'\u001b[39m\u001b[39mNODES\u001b[39m\u001b[39m'\u001b[39m] \u001b[39m=\u001b[39m {i\u001b[39m+\u001b[39m\u001b[39m1\u001b[39m: node\u001b[39m.\u001b[39mobserve(state) \u001b[39mfor\u001b[39;00m i, node \u001b[39min\u001b[39;00m \u001b[39menumerate\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnodes)}\n\u001b[1;32m 572\u001b[0m \u001b[39mreturn\u001b[39;00m obs\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/agent/observations.py:571\u001b[0m, in \u001b[0;36m<dictcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 568\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdefault_observation\n\u001b[1;32m 570\u001b[0m obs \u001b[39m=\u001b[39m {}\n\u001b[0;32m--> 571\u001b[0m obs[\u001b[39m'\u001b[39m\u001b[39mNODES\u001b[39m\u001b[39m'\u001b[39m] \u001b[39m=\u001b[39m {i\u001b[39m+\u001b[39m\u001b[39m1\u001b[39m: node\u001b[39m.\u001b[39;49mobserve(state) \u001b[39mfor\u001b[39;00m i, node \u001b[39min\u001b[39;00m \u001b[39menumerate\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnodes)}\n\u001b[1;32m 572\u001b[0m \u001b[39mreturn\u001b[39;00m obs\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/agent/observations.py:328\u001b[0m, in \u001b[0;36mNodeObservation.observe\u001b[0;34m(self, state)\u001b[0m\n\u001b[1;32m 326\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mservices)\n\u001b[1;32m 327\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mfolders)\n\u001b[0;32m--> 328\u001b[0m obs[\u001b[39m\"\u001b[39m\u001b[39mSERVICES\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m {i \u001b[39m+\u001b[39m \u001b[39m1\u001b[39m: service\u001b[39m.\u001b[39mobserve(state) \u001b[39mfor\u001b[39;00m i, service \u001b[39min\u001b[39;00m \u001b[39menumerate\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mservices)}\n\u001b[1;32m 329\u001b[0m obs[\u001b[39m\"\u001b[39m\u001b[39mFOLDERS\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m {i \u001b[39m+\u001b[39m \u001b[39m1\u001b[39m: folder\u001b[39m.\u001b[39mobserve(state) \u001b[39mfor\u001b[39;00m i, folder \u001b[39min\u001b[39;00m \u001b[39menumerate\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mfolders)}\n\u001b[1;32m 330\u001b[0m obs[\u001b[39m\"\u001b[39m\u001b[39moperating_status\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m node_state[\u001b[39m\"\u001b[39m\u001b[39moperating_state\u001b[39m\u001b[39m\"\u001b[39m]\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/agent/observations.py:328\u001b[0m, in \u001b[0;36m<dictcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 326\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mservices)\n\u001b[1;32m 327\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mfolders)\n\u001b[0;32m--> 328\u001b[0m obs[\u001b[39m\"\u001b[39m\u001b[39mSERVICES\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m {i \u001b[39m+\u001b[39m \u001b[39m1\u001b[39m: service\u001b[39m.\u001b[39;49mobserve(state) \u001b[39mfor\u001b[39;00m i, service \u001b[39min\u001b[39;00m \u001b[39menumerate\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mservices)}\n\u001b[1;32m 329\u001b[0m obs[\u001b[39m\"\u001b[39m\u001b[39mFOLDERS\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m {i \u001b[39m+\u001b[39m \u001b[39m1\u001b[39m: folder\u001b[39m.\u001b[39mobserve(state) \u001b[39mfor\u001b[39;00m i, folder \u001b[39min\u001b[39;00m \u001b[39menumerate\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mfolders)}\n\u001b[1;32m 330\u001b[0m obs[\u001b[39m\"\u001b[39m\u001b[39moperating_status\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m node_state[\u001b[39m\"\u001b[39m\u001b[39moperating_state\u001b[39m\u001b[39m\"\u001b[39m]\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/agent/observations.py:124\u001b[0m, in \u001b[0;36mServiceObservation.observe\u001b[0;34m(self, state)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mwhere \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m 122\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdefault_observation\n\u001b[0;32m--> 124\u001b[0m service_state \u001b[39m=\u001b[39m access_from_nested_dict(state, \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mwhere)\n\u001b[1;32m 125\u001b[0m \u001b[39mif\u001b[39;00m service_state \u001b[39mis\u001b[39;00m NOT_PRESENT_IN_STATE:\n\u001b[1;32m 126\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdefault_observation\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/agent/observations.py:37\u001b[0m, in \u001b[0;36maccess_from_nested_dict\u001b[0;34m(dictionary, keys)\u001b[0m\n\u001b[1;32m 35\u001b[0m \u001b[39mif\u001b[39;00m k \u001b[39mnot\u001b[39;00m \u001b[39min\u001b[39;00m dictionary:\n\u001b[1;32m 36\u001b[0m \u001b[39mreturn\u001b[39;00m NOT_PRESENT_IN_STATE\n\u001b[0;32m---> 37\u001b[0m \u001b[39mreturn\u001b[39;00m access_from_nested_dict(dictionary[k], keys)\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/agent/observations.py:37\u001b[0m, in \u001b[0;36maccess_from_nested_dict\u001b[0;34m(dictionary, keys)\u001b[0m\n\u001b[1;32m 35\u001b[0m \u001b[39mif\u001b[39;00m k \u001b[39mnot\u001b[39;00m \u001b[39min\u001b[39;00m dictionary:\n\u001b[1;32m 36\u001b[0m \u001b[39mreturn\u001b[39;00m NOT_PRESENT_IN_STATE\n\u001b[0;32m---> 37\u001b[0m \u001b[39mreturn\u001b[39;00m access_from_nested_dict(dictionary[k], keys)\n",
|
|
" \u001b[0;31m[... skipping similar frames: access_from_nested_dict at line 37 (1 times)]\u001b[0m\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/agent/observations.py:37\u001b[0m, in \u001b[0;36maccess_from_nested_dict\u001b[0;34m(dictionary, keys)\u001b[0m\n\u001b[1;32m 35\u001b[0m \u001b[39mif\u001b[39;00m k \u001b[39mnot\u001b[39;00m \u001b[39min\u001b[39;00m dictionary:\n\u001b[1;32m 36\u001b[0m \u001b[39mreturn\u001b[39;00m NOT_PRESENT_IN_STATE\n\u001b[0;32m---> 37\u001b[0m \u001b[39mreturn\u001b[39;00m access_from_nested_dict(dictionary[k], keys)\n",
|
|
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/game/agent/observations.py:35\u001b[0m, in \u001b[0;36maccess_from_nested_dict\u001b[0;34m(dictionary, keys)\u001b[0m\n\u001b[1;32m 33\u001b[0m \u001b[39mreturn\u001b[39;00m dictionary\n\u001b[1;32m 34\u001b[0m k \u001b[39m=\u001b[39m keys\u001b[39m.\u001b[39mpop(\u001b[39m0\u001b[39m)\n\u001b[0;32m---> 35\u001b[0m \u001b[39mif\u001b[39;00m k \u001b[39mnot\u001b[39;49;00m \u001b[39min\u001b[39;49;00m dictionary:\n\u001b[1;32m 36\u001b[0m \u001b[39mreturn\u001b[39;00m NOT_PRESENT_IN_STATE\n\u001b[1;32m 37\u001b[0m \u001b[39mreturn\u001b[39;00m access_from_nested_dict(dictionary[k], keys)\n",
|
|
"\u001b[0;31mTypeError\u001b[0m: unhashable type: 'DataManipulationBot'"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"sess.step()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from ipaddress import IPv4Address\n",
|
|
"\n",
|
|
"from primaite.simulator.network.container import Network\n",
|
|
"from primaite.simulator.network.hardware.base import NIC\n",
|
|
"from primaite.simulator.network.hardware.nodes.computer import Computer\n",
|
|
"from primaite.simulator.network.hardware.nodes.router import ACLAction, Router\n",
|
|
"from primaite.simulator.network.hardware.nodes.server import Server\n",
|
|
"from primaite.simulator.network.hardware.nodes.switch import Switch\n",
|
|
"from primaite.simulator.network.transmission.network_layer import IPProtocol\n",
|
|
"from primaite.simulator.network.transmission.transport_layer import Port\n",
|
|
"from primaite.simulator.system.applications.database_client import DatabaseClient\n",
|
|
"from primaite.simulator.system.services.database_service import DatabaseService\n",
|
|
"from primaite.simulator.system.services.dns_client import DNSClient\n",
|
|
"from primaite.simulator.system.services.dns_server import DNSServer\n",
|
|
"from primaite.simulator.system.services.red_services.data_manipulation_bot import DataManipulationBot"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"router_1 = Router(hostname=\"router_1\", num_ports=5)\n",
|
|
"router_1.power_on()\n",
|
|
"router_1.configure_port(port=1, ip_address=\"192.168.1.1\", subnet_mask=\"255.255.255.0\")\n",
|
|
"router_1.configure_port(port=2, ip_address=\"192.168.10.1\", subnet_mask=\"255.255.255.0\")\n",
|
|
"\n",
|
|
"# Switch 1\n",
|
|
"switch_1 = Switch(hostname=\"switch_1\", num_ports=8)\n",
|
|
"switch_1.power_on()\n",
|
|
"network.connect(endpoint_a=router_1.ethernet_ports[1], endpoint_b=switch_1.switch_ports[8])\n",
|
|
"router_1.enable_port(1)\n",
|
|
"\n",
|
|
"# Switch 2\n",
|
|
"switch_2 = Switch(hostname=\"switch_2\", num_ports=8)\n",
|
|
"switch_2.power_on()\n",
|
|
"network.connect(endpoint_a=router_1.ethernet_ports[2], endpoint_b=switch_2.switch_ports[8])\n",
|
|
"router_1.enable_port(2)\n",
|
|
"\n",
|
|
"# Client 1\n",
|
|
"client_1 = Computer(\n",
|
|
" hostname=\"client_1\",\n",
|
|
" ip_address=\"192.168.10.21\",\n",
|
|
" subnet_mask=\"255.255.255.0\",\n",
|
|
" default_gateway=\"192.168.10.1\",\n",
|
|
" dns_server=IPv4Address(\"192.168.1.10\"),\n",
|
|
")\n",
|
|
"client_1.power_on()\n",
|
|
"client_1.software_manager.install(DNSClient)\n",
|
|
"client_1_dns_client_service: DNSServer = client_1.software_manager.software[\"DNSClient\"] # noqa\n",
|
|
"client_1_dns_client_service.start()\n",
|
|
"network.connect(endpoint_b=client_1.ethernet_port[1], endpoint_a=switch_2.switch_ports[1])\n",
|
|
"client_1.software_manager.install(DataManipulationBot)\n",
|
|
"db_manipulation_bot: DataManipulationBot = client_1.software_manager.software[\"DataManipulationBot\"]\n",
|
|
"db_manipulation_bot.configure(server_ip_address=IPv4Address(\"192.168.1.14\"), payload=\"DROP TABLE IF EXISTS user;\")\n",
|
|
"\n",
|
|
"# Client 2\n",
|
|
"client_2 = Computer(\n",
|
|
" hostname=\"client_2\",\n",
|
|
" ip_address=\"192.168.10.22\",\n",
|
|
" subnet_mask=\"255.255.255.0\",\n",
|
|
" default_gateway=\"192.168.10.1\",\n",
|
|
" dns_server=IPv4Address(\"192.168.1.10\"),\n",
|
|
")\n",
|
|
"client_2.power_on()\n",
|
|
"client_2.software_manager.install(DNSClient)\n",
|
|
"client_2_dns_client_service: DNSServer = client_2.software_manager.software[\"DNSClient\"] # noqa\n",
|
|
"client_2_dns_client_service.start()\n",
|
|
"network.connect(endpoint_b=client_2.ethernet_port[1], endpoint_a=switch_2.switch_ports[2])\n",
|
|
"\n",
|
|
"# Domain Controller\n",
|
|
"domain_controller = Server(\n",
|
|
" hostname=\"domain_controller\",\n",
|
|
" ip_address=\"192.168.1.10\",\n",
|
|
" subnet_mask=\"255.255.255.0\",\n",
|
|
" default_gateway=\"192.168.1.1\",\n",
|
|
")\n",
|
|
"domain_controller.power_on()\n",
|
|
"domain_controller.software_manager.install(DNSServer)\n",
|
|
"\n",
|
|
"network.connect(endpoint_b=domain_controller.ethernet_port[1], endpoint_a=switch_1.switch_ports[1])\n",
|
|
"\n",
|
|
"# Database Server\n",
|
|
"database_server = Server(\n",
|
|
" hostname=\"database_server\",\n",
|
|
" ip_address=\"192.168.1.14\",\n",
|
|
" subnet_mask=\"255.255.255.0\",\n",
|
|
" default_gateway=\"192.168.1.1\",\n",
|
|
" dns_server=IPv4Address(\"192.168.1.10\"),\n",
|
|
")\n",
|
|
"database_server.power_on()\n",
|
|
"network.connect(endpoint_b=database_server.ethernet_port[1], endpoint_a=switch_1.switch_ports[3])\n",
|
|
"\n",
|
|
"ddl = \"\"\"\n",
|
|
"CREATE TABLE IF NOT EXISTS user (\n",
|
|
"id INTEGER PRIMARY KEY AUTOINCREMENT,\n",
|
|
"name VARCHAR(50) NOT NULL,\n",
|
|
"email VARCHAR(50) NOT NULL,\n",
|
|
"age INT,\n",
|
|
"city VARCHAR(50),\n",
|
|
"occupation VARCHAR(50)\n",
|
|
");\"\"\"\n",
|
|
"\n",
|
|
"user_insert_statements = [\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('John Doe', 'johndoe@example.com', 32, 'New York', 'Engineer');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Jane Smith', 'janesmith@example.com', 27, 'Los Angeles', 'Designer');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Bob Johnson', 'bobjohnson@example.com', 45, 'Chicago', 'Manager');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Alice Lee', 'alicelee@example.com', 22, 'San Francisco', 'Student');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('David Kim', 'davidkim@example.com', 38, 'Houston', 'Consultant');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Emily Chen', 'emilychen@example.com', 29, 'Seattle', 'Software Developer');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Frank Wang', 'frankwang@example.com', 55, 'New York', 'Entrepreneur');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Grace Park', 'gracepark@example.com', 31, 'Los Angeles', 'Marketing Specialist');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Henry Wu', 'henrywu@example.com', 40, 'Chicago', 'Accountant');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Isabella Kim', 'isabellakim@example.com', 26, 'San Francisco', 'Graphic Designer');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Jake Lee', 'jakelee@example.com', 33, 'Houston', 'Sales Manager');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Kelly Chen', 'kellychen@example.com', 28, 'Seattle', 'Web Developer');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Lucas Liu', 'lucasliu@example.com', 42, 'New York', 'Lawyer');\", # noqa\n",
|
|
" \"INSERT INTO user (name, email, age, city, occupation) VALUES ('Maggie Wang', 'maggiewang@example.com', 30, 'Los Angeles', 'Data Analyst');\", # noqa\n",
|
|
"]\n",
|
|
"database_server.software_manager.install(DatabaseService)\n",
|
|
"database_service: DatabaseService = database_server.software_manager.software[\"DatabaseService\"] # noqa\n",
|
|
"database_service.start()\n",
|
|
"database_service._process_sql(ddl, None) # noqa\n",
|
|
"for insert_statement in user_insert_statements:\n",
|
|
" database_service._process_sql(insert_statement, None) # noqa\n",
|
|
"\n",
|
|
"# Web Server\n",
|
|
"web_server = Server(\n",
|
|
" hostname=\"web_server\",\n",
|
|
" ip_address=\"192.168.1.12\",\n",
|
|
" subnet_mask=\"255.255.255.0\",\n",
|
|
" default_gateway=\"192.168.1.1\",\n",
|
|
" dns_server=IPv4Address(\"192.168.1.10\"),\n",
|
|
")\n",
|
|
"web_server.power_on()\n",
|
|
"web_server.software_manager.install(DatabaseClient)\n",
|
|
"\n",
|
|
"database_client: DatabaseClient = web_server.software_manager.software[\"DatabaseClient\"]\n",
|
|
"database_client.configure(server_ip_address=IPv4Address(\"192.168.1.14\"))\n",
|
|
"network.connect(endpoint_b=web_server.ethernet_port[1], endpoint_a=switch_1.switch_ports[2])\n",
|
|
"database_client.run()\n",
|
|
"database_client.connect()\n",
|
|
"\n",
|
|
"# register the web_server to a domain\n",
|
|
"dns_server_service: DNSServer = domain_controller.software_manager.software[\"DNSServer\"] # noqa\n",
|
|
"dns_server_service.start()\n",
|
|
"dns_server_service.dns_register(\"arcd.com\", web_server.ip_address)\n",
|
|
"\n",
|
|
"# Backup Server\n",
|
|
"backup_server = Server(\n",
|
|
" hostname=\"backup_server\",\n",
|
|
" ip_address=\"192.168.1.16\",\n",
|
|
" subnet_mask=\"255.255.255.0\",\n",
|
|
" default_gateway=\"192.168.1.1\",\n",
|
|
" dns_server=IPv4Address(\"192.168.1.10\"),\n",
|
|
")\n",
|
|
"backup_server.power_on()\n",
|
|
"network.connect(endpoint_b=backup_server.ethernet_port[1], endpoint_a=switch_1.switch_ports[4])\n",
|
|
"\n",
|
|
"# Security Suite\n",
|
|
"security_suite = Server(\n",
|
|
" hostname=\"security_suite\",\n",
|
|
" ip_address=\"192.168.1.110\",\n",
|
|
" subnet_mask=\"255.255.255.0\",\n",
|
|
" default_gateway=\"192.168.1.1\",\n",
|
|
" dns_server=IPv4Address(\"192.168.1.10\"),\n",
|
|
")\n",
|
|
"security_suite.power_on()\n",
|
|
"network.connect(endpoint_b=security_suite.ethernet_port[1], endpoint_a=switch_1.switch_ports[7])\n",
|
|
"security_suite.connect_nic(NIC(ip_address=\"192.168.10.110\", subnet_mask=\"255.255.255.0\"))\n",
|
|
"network.connect(endpoint_b=security_suite.ethernet_port[2], endpoint_a=switch_2.switch_ports[7])\n",
|
|
"\n",
|
|
"router_1.acl.add_rule(action=ACLAction.PERMIT, src_port=Port.ARP, dst_port=Port.ARP, position=22)\n",
|
|
"\n",
|
|
"router_1.acl.add_rule(action=ACLAction.PERMIT, protocol=IPProtocol.ICMP, position=23)\n",
|
|
"\n",
|
|
"# Allow PostgreSQL requests\n",
|
|
"router_1.acl.add_rule(\n",
|
|
" action=ACLAction.PERMIT, src_port=Port.POSTGRES_SERVER, dst_port=Port.POSTGRES_SERVER, position=0\n",
|
|
")\n",
|
|
"\n",
|
|
"# Allow DNS requests\n",
|
|
"router_1.acl.add_rule(action=ACLAction.PERMIT, src_port=Port.DNS, dst_port=Port.DNS, position=1)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"node_uuid_list = list(sess.simulation.network.nodes.keys())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from primaite.game.agent.actions import ActionManager"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"actman = ActionManager(sess.simulation, [\"DONOTHING\", \"NODE_SERVICE_SCAN\", \"NODE_SERVICE_STOP\", \"NODE_FOLDER_SCAN\"],node_uuid_list,act_map={\n",
|
|
" 0:{\n",
|
|
" \"action\": \"DONOTHING\",\n",
|
|
" \"options\": {}\n",
|
|
" },\n",
|
|
" 1:{\n",
|
|
" \"action\": \"NODE_SERVICE_SCAN\",\n",
|
|
" \"options\": {\"node_id\":0, \"service_id\":0},\n",
|
|
" },\n",
|
|
" 2:{\n",
|
|
" \"action\": \"NODE_SERVICE_SCAN\",\n",
|
|
" \"options\": {\"node_id\":1, \"service_id\":0},\n",
|
|
" },\n",
|
|
" 3:{\n",
|
|
" \"action\": \"NODE_FOLDER_SCAN\",\n",
|
|
" \"options\": {\"node_id\":4, \"folder_id\":0},\n",
|
|
" }\n",
|
|
"})"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"act_id, act_options = actman.get_action(3)\n",
|
|
"my_trial_act = actman.form_request(action_identifier=act_id, action_options=act_options)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"sess.simulation.apply_action(my_trial_act)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"my_trial_act"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"sess.step()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"sess.step_counter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from gym import spaces"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"sp = spaces.Tuple( (spaces.MultiDiscrete([3, 2]), spaces.MultiDiscrete([3, 2]), spaces.MultiDiscrete([3, 2]),))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"sp.sample()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import yaml\n",
|
|
"from primaite.simulator.sim_container import Simulation\n",
|
|
"from primaite.simulator.network.hardware.nodes.computer import Computer\n",
|
|
"from primaite.simulator.network.hardware.nodes.server import Server\n",
|
|
"from primaite.simulator.network.hardware.nodes.switch import Switch\n",
|
|
"from primaite.simulator.network.hardware.nodes.router import Router\n",
|
|
"\n",
|
|
"from primaite.simulator.system.applications.database_client import DatabaseClient\n",
|
|
"from primaite.simulator.system.services.database_service import DatabaseService\n",
|
|
"from primaite.simulator.system.services.dns_client import DNSClient\n",
|
|
"from primaite.simulator.system.services.dns_server import DNSServer\n",
|
|
"from primaite.simulator.system.services.red_services.data_manipulation_bot import DataManipulationBot\n",
|
|
"\n",
|
|
"\n",
|
|
"from primaite.simulator.network.hardware.nodes.router import ACLAction\n",
|
|
"from primaite.simulator.network.transmission.network_layer import IPProtocol\n",
|
|
"from primaite.simulator.network.transmission.transport_layer import Port\n",
|
|
"\n",
|
|
"from ipaddress import IPv4Address\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# import yaml\n",
|
|
"\n",
|
|
"\n",
|
|
"from typing import Dict\n",
|
|
"from primaite.game.agent.interface import AbstractAgent\n",
|
|
"from primaite.game.agent.observations import AclObservation, FileObservation, FolderObservation, ICSObservation, LinkObservation, NicObservation, NodeObservation, NullObservation, ServiceObservation, UC2BlueObservation, UC2RedObservation\n",
|
|
"from primaite.simulator.network.hardware.base import NIC, Link, Node\n",
|
|
"from primaite.simulator.system.services.service import Service\n",
|
|
"\n",
|
|
"from primaite.game.agent.scripted_agents import GreenWebBrowsingAgent, RedDatabaseCorruptingAgent\n",
|
|
"from primaite.game.agent.GATE_agents import GATERLAgent\n",
|
|
"\n",
|
|
"class PrimaiteSession:\n",
|
|
"\n",
|
|
" def __init__(self):\n",
|
|
" self.simulation: Simulation\n",
|
|
" self.agents = []\n",
|
|
"\n",
|
|
" @classmethod\n",
|
|
" def from_config(cls, cfg_path):\n",
|
|
" ref_map_nodes: Dict[str,Node] = {}\n",
|
|
" ref_map_services: Dict[str, Service] = {}\n",
|
|
" ref_map_links: Dict[str, Link] = {}\n",
|
|
" # ref_map_agents: Dict[str, AgentInterface] = {}\n",
|
|
"\n",
|
|
"\n",
|
|
" session = cls()\n",
|
|
" with open(cfg_path, 'r') as file:\n",
|
|
" conf = yaml.safe_load(file)\n",
|
|
"\n",
|
|
" #1. create nodes\n",
|
|
" sim = Simulation()\n",
|
|
" net = sim.network\n",
|
|
" nodes_cfg = conf['simulation']['network']['nodes']\n",
|
|
" links_cfg = conf['simulation']['network']['links']\n",
|
|
" for node_cfg in nodes_cfg:\n",
|
|
" node_ref = node_cfg['ref']\n",
|
|
" n_type = node_cfg['type']\n",
|
|
" if n_type == 'computer':\n",
|
|
" new_node = Computer(hostname = node_cfg['hostname'],\n",
|
|
" ip_address = node_cfg['ip_address'],\n",
|
|
" subnet_mask = node_cfg['subnet_mask'],\n",
|
|
" default_gateway = node_cfg['default_gateway'],\n",
|
|
" dns_server = node_cfg['dns_server'])\n",
|
|
" elif n_type == 'server':\n",
|
|
" new_node = Server(hostname = node_cfg['hostname'],\n",
|
|
" ip_address = node_cfg['ip_address'],\n",
|
|
" subnet_mask = node_cfg['subnet_mask'],\n",
|
|
" default_gateway = node_cfg['default_gateway'],\n",
|
|
" dns_server = node_cfg.get('dns_server'))\n",
|
|
" elif n_type == 'switch':\n",
|
|
" new_node = Switch(hostname = node_cfg['hostname'],\n",
|
|
" num_ports = node_cfg.get('num_ports'))\n",
|
|
" elif n_type == 'router':\n",
|
|
" new_node = Router(hostname=node_cfg['hostname'],\n",
|
|
" num_ports = node_cfg.get('num_ports'))\n",
|
|
" if 'ports' in node_cfg:\n",
|
|
" for port_num, port_cfg in node_cfg['ports'].items():\n",
|
|
" new_node.configure_port(port=port_num,\n",
|
|
" ip_address=port_cfg['ip_address'],\n",
|
|
" subnet_mask=port_cfg['subnet_mask'])\n",
|
|
" if 'acl' in node_cfg:\n",
|
|
" for r_num, r_cfg in node_cfg['acl'].items():\n",
|
|
" # excuse the uncommon walrus operator ` := `. It's just here as a shorthand, to avoid repeating\n",
|
|
" # this: 'r_cfg.get('src_port')'\n",
|
|
" # Port/IPProtocol. TODO Refactor\n",
|
|
" new_node.acl.add_rule(\n",
|
|
" action = ACLAction[r_cfg['action']],\n",
|
|
" src_port = None if not (p:=r_cfg.get('src_port')) else Port[p],\n",
|
|
" dst_port = None if not (p:=r_cfg.get('dst_port')) else Port[p],\n",
|
|
" protocol = None if not (p:=r_cfg.get('protocol')) else IPProtocol[p],\n",
|
|
" src_ip_address = r_cfg.get('ip_address'),\n",
|
|
" dst_ip_address = r_cfg.get('ip_address'),\n",
|
|
" position = r_num\n",
|
|
" )\n",
|
|
" else:\n",
|
|
" print('invalid node type')\n",
|
|
" if 'services' in node_cfg:\n",
|
|
" for service_cfg in node_cfg['services']:\n",
|
|
" service_ref = service_cfg['ref']\n",
|
|
" service_type = service_cfg['type']\n",
|
|
" service_types_mapping = {\n",
|
|
" 'DNSClient': DNSClient, # key is equal to the 'name' attr of the service class itself.\n",
|
|
" 'DNSServer' : DNSServer,\n",
|
|
" 'DatabaseClient': DatabaseClient,\n",
|
|
" 'DatabaseService': DatabaseService,\n",
|
|
" # 'database_backup': ,\n",
|
|
" 'DataManipulationBot': DataManipulationBot,\n",
|
|
" # 'web_browser'\n",
|
|
" }\n",
|
|
" if service_type in service_types_mapping:\n",
|
|
" new_node.software_manager.install(service_types_mapping[service_type])\n",
|
|
" new_service = new_node.software_manager.software[service_type]\n",
|
|
" ref_map_services[service_ref] = new_service\n",
|
|
" else:\n",
|
|
" print(f\"service type not found {service_type}\")\n",
|
|
" # service-dependent options\n",
|
|
" if service_type == 'DatabaseClient':\n",
|
|
" if 'options' in service_cfg:\n",
|
|
" opt = service_cfg['options']\n",
|
|
" if 'db_server_ip' in opt:\n",
|
|
" new_service.configure(server_ip_address=IPv4Address(opt['db_server_ip']))\n",
|
|
" if service_type == 'DNSServer':\n",
|
|
" if 'options' in service_cfg:\n",
|
|
" opt = service_cfg['options']\n",
|
|
" if 'domain_mapping' in opt:\n",
|
|
" for domain, ip in opt['domain_mapping'].items():\n",
|
|
" new_service.dns_register(domain, ip)\n",
|
|
" if 'nics' in node_cfg:\n",
|
|
" for nic_num, nic_cfg in node_cfg['nics'].items():\n",
|
|
" new_node.connect_nic(NIC(ip_address=nic_cfg['ip_address'], subnet_mask=nic_cfg['subnet_mask']))\n",
|
|
"\n",
|
|
" net.add_node(new_node)\n",
|
|
" new_node.power_on()\n",
|
|
" ref_map_nodes[node_ref] = new_node.uuid\n",
|
|
"\n",
|
|
" #2. create links between nodes\n",
|
|
" for link_cfg in links_cfg:\n",
|
|
" node_a = net.nodes[ref_map_nodes[link_cfg['endpoint_a_ref']]]\n",
|
|
" node_b = net.nodes[ref_map_nodes[link_cfg['endpoint_b_ref']]]\n",
|
|
" if isinstance(node_a, Switch):\n",
|
|
" endpoint_a = node_a.switch_ports[link_cfg['endpoint_a_port']]\n",
|
|
" else:\n",
|
|
" endpoint_a = node_a.ethernet_port[link_cfg['endpoint_a_port']]\n",
|
|
" if isinstance(node_b, Switch):\n",
|
|
" endpoint_b = node_b.switch_ports[link_cfg['endpoint_b_port']]\n",
|
|
" else:\n",
|
|
" endpoint_b = node_b.ethernet_port[link_cfg['endpoint_b_port']]\n",
|
|
" new_link = net.connect(endpoint_a=endpoint_a, endpoint_b=endpoint_b)\n",
|
|
" ref_map_links[link_cfg['ref']] = new_link.uuid\n",
|
|
"\n",
|
|
" session.simulation = sim\n",
|
|
" #3. create agents\n",
|
|
" game_cfg = conf['game_config']\n",
|
|
" ports_cfg = game_cfg['ports']\n",
|
|
" protocols_cfg = game_cfg['protocols']\n",
|
|
" agents_cfg = game_cfg['agents']\n",
|
|
"\n",
|
|
" for agent_cfg in agents_cfg:\n",
|
|
" agent_ref = agent_cfg['ref']\n",
|
|
" agent_type = agent_cfg['type']\n",
|
|
" action_space_cfg = agent_cfg['action_space']\n",
|
|
" observation_space_cfg = agent_cfg['observation_space']\n",
|
|
" reward_function_cfg = agent_cfg['reward_function']\n",
|
|
"\n",
|
|
" # CREATE OBSERVATION SPACE\n",
|
|
" if observation_space_cfg is None:\n",
|
|
" obs_space = NullObservation()\n",
|
|
" elif observation_space_cfg['type'] == 'UC2BlueObservation':\n",
|
|
" node_obs_list = []\n",
|
|
" link_obs_list = []\n",
|
|
"\n",
|
|
"\n",
|
|
" #node ip to index maps ip addresses to node id, as there are potentially multiple nics on a node, there are multiple ip addresses\n",
|
|
" node_ip_to_index = {}\n",
|
|
" for node_idx, node_cfg in enumerate(nodes_cfg):\n",
|
|
" n_ref = node_cfg['ref']\n",
|
|
" n_obj = net.nodes[ref_map_nodes[n_ref]]\n",
|
|
" for nic_uuid, nic_obj in n_obj.nics.items():\n",
|
|
" node_ip_to_index[nic_obj.ip_address] = node_idx + 2\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
" for node_obs_cfg in observation_space_cfg['options']['nodes']:\n",
|
|
" node_ref = node_obs_cfg['node_ref']\n",
|
|
" folder_obs_list = []\n",
|
|
" service_obs_list = []\n",
|
|
" if 'services' in node_obs_cfg:\n",
|
|
" for service_obs_cfg in node_obs_cfg['services']:\n",
|
|
" service_obs_list.append(ServiceObservation(where=['network','nodes',ref_map_nodes[node_ref],'services',ref_map_services[service_obs_cfg['service_ref']]]))\n",
|
|
" if 'folders' in node_obs_cfg:\n",
|
|
" for folder_obs_cfg in node_obs_cfg['folders']:\n",
|
|
" file_obs_list = []\n",
|
|
" if 'files' in folder_obs_cfg:\n",
|
|
" for file_obs_cfg in folder_obs_cfg['files']:\n",
|
|
" file_obs_list.append(FileObservation(where=['network','nodes',ref_map_nodes[node_ref], 'folders',folder_obs_cfg['folder_name'], 'files', file_obs_cfg['file_name']]))\n",
|
|
" folder_obs_list.append(FolderObservation(where=['network','nodes',ref_map_nodes[node_ref], 'folders',folder_obs_cfg['folder_name']], files=file_obs_list))\n",
|
|
" nic_obs_list = []\n",
|
|
" for nic_uuid in net.nodes[ref_map_nodes[node_obs_cfg['node_ref']]].nics.keys():\n",
|
|
" nic_obs_list.append(NicObservation(where=['network','nodes',ref_map_nodes[node_ref],'NICs',nic_uuid]))\n",
|
|
" node_obs_list.append(NodeObservation(where=['network','nodes',ref_map_nodes[node_ref]], services=service_obs_list, folders=folder_obs_list,nics=nic_obs_list, logon_status=False))\n",
|
|
" for link_obs_cfg in observation_space_cfg['options']['links']:\n",
|
|
" link_ref = link_obs_cfg['link_ref']\n",
|
|
" link_obs_list.append(LinkObservation(where=['network' ,'links', ref_map_links[link_ref]]))\n",
|
|
"\n",
|
|
" acl_obs = AclObservation(node_ip_to_id=node_ip_to_index, ports=game_cfg['ports'], protocols=game_cfg['ports'], where=['network','nodes',observation_space_cfg['options']['acl']['router_node_ref']])\n",
|
|
" obs_space = UC2BlueObservation(nodes=node_obs_list,links=link_obs_list,acl=acl_obs, ics=ICSObservation())\n",
|
|
" elif observation_space_cfg['type'] == 'UC2RedObservation':\n",
|
|
" obs_space = UC2RedObservation.from_config(observation_space_cfg['options'], sim=sim)\n",
|
|
" else:\n",
|
|
" print(\"observation space config not specified correctly.\")\n",
|
|
" obs_space = NullObservation()\n",
|
|
"\n",
|
|
" # CREATE ACTION SPACE\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
" # CREATE REWARD FUNCTION\n",
|
|
"\n",
|
|
" # CREATE AGENT\n",
|
|
" if agent_type == 'GreenWebBrowsingAgent':\n",
|
|
" ...\n",
|
|
" elif agent_type == 'GATERLAgent':\n",
|
|
" ...\n",
|
|
" elif agent_type == 'RedDatabaseCorruptingAgent':\n",
|
|
" ...\n",
|
|
" else:\n",
|
|
" print(\"agent type not found\")\n",
|
|
"\n",
|
|
"\n",
|
|
" #4. set up agents' actions and observation spaces.\n",
|
|
" return session\n",
|
|
"\n",
|
|
"s = PrimaiteSession.from_config('example_config.yaml')\n",
|
|
"# print(s.simulation.describe_state())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"s.agents"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "venv",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.10.12"
|
|
},
|
|
"orig_nbformat": 4
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|