Initialise observations in agent interface

This commit is contained in:
Marek Wolan
2023-09-21 10:13:01 +01:00
parent fd1a4403f4
commit f54f278fca
10 changed files with 333 additions and 7 deletions

134
sandbox.ipynb Normal file
View File

@@ -0,0 +1,134 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from primaite.simulator.network.networks import arcd_uc2_network\n",
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"net = arcd_uc2_network()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"random_node = list(net.nodes.keys())[0]\n",
"f = net.nodes[random_node].file_system.create_file(file_name=\"testfile\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f.describe_state()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def test_file_observation():\n",
" from primaite.simulator.sim_container import Simulation\n",
" from primaite.simulator.network.hardware.nodes.computer import Computer\n",
" from primaite.game.actor.observations import FileObservation\n",
"\n",
" sim = Simulation()\n",
" pc = Computer(hostname=\"beep\", ip_address=\"123.123.123.123\", subnet_mask=\"255.255.255.0\")\n",
" sim.network.add_node(pc)\n",
" f = pc.file_system.create_file(file_name=\"dog.png\")\n",
"\n",
" dog_file_obs = FileObservation(where=['network','nodes',pc.uuid,'file_system'])\n",
" print(sim.describe_state())\n",
"test_file_observation()"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"ename": "AttributeError",
"evalue": "'NIC' object has no attribute 'gateway'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
"File \u001b[0;32m~/repos/PrimAITE/venv/lib/python3.10/site-packages/pydantic/main.py:718\u001b[0m, in \u001b[0;36mBaseModel.__getattr__\u001b[0;34m(self, item)\u001b[0m\n\u001b[1;32m 717\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m--> 718\u001b[0m \u001b[39mreturn\u001b[39;00m pydantic_extra[item]\n\u001b[1;32m 719\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m exc:\n",
"\u001b[0;31mKeyError\u001b[0m: 'gateway'",
"\nThe above exception was the direct cause of the following exception:\n",
"\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m/home/cade/repos/PrimAITE/test.ipynb Cell 6\u001b[0m line \u001b[0;36m1\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Bubuntu/home/cade/repos/PrimAITE/test.ipynb#W5sdnNjb2RlLXJlbW90ZQ%3D%3D?line=6'>7</a>\u001b[0m sim\u001b[39m.\u001b[39mnetwork\u001b[39m.\u001b[39madd_node(pc)\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Bubuntu/home/cade/repos/PrimAITE/test.ipynb#W5sdnNjb2RlLXJlbW90ZQ%3D%3D?line=7'>8</a>\u001b[0m f \u001b[39m=\u001b[39m pc\u001b[39m.\u001b[39mfile_system\u001b[39m.\u001b[39mcreate_file(file_name\u001b[39m=\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mdog.png\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m---> <a href='vscode-notebook-cell://wsl%2Bubuntu/home/cade/repos/PrimAITE/test.ipynb#W5sdnNjb2RlLXJlbW90ZQ%3D%3D?line=9'>10</a>\u001b[0m sim\u001b[39m.\u001b[39;49mdescribe_state()\n",
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/simulator/sim_container.py:54\u001b[0m, in \u001b[0;36mSimulation.describe_state\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 43\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 44\u001b[0m \u001b[39mProduce a dictionary describing the current state of this object.\u001b[39;00m\n\u001b[1;32m 45\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[39m:rtype: Dict\u001b[39;00m\n\u001b[1;32m 50\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 51\u001b[0m state \u001b[39m=\u001b[39m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39mdescribe_state()\n\u001b[1;32m 52\u001b[0m state\u001b[39m.\u001b[39mupdate(\n\u001b[1;32m 53\u001b[0m {\n\u001b[0;32m---> 54\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mnetwork\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mnetwork\u001b[39m.\u001b[39;49mdescribe_state(),\n\u001b[1;32m 55\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mdomain\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdomain\u001b[39m.\u001b[39mdescribe_state(),\n\u001b[1;32m 56\u001b[0m }\n\u001b[1;32m 57\u001b[0m )\n\u001b[1;32m 58\u001b[0m \u001b[39mreturn\u001b[39;00m state\n",
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/simulator/network/container.py:166\u001b[0m, in \u001b[0;36mNetwork.describe_state\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 159\u001b[0m \u001b[39mProduce a dictionary describing the current state of the Network.\u001b[39;00m\n\u001b[1;32m 160\u001b[0m \n\u001b[1;32m 161\u001b[0m \u001b[39m:return: A dictionary capturing the current state of the Network and its child objects.\u001b[39;00m\n\u001b[1;32m 162\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 163\u001b[0m state \u001b[39m=\u001b[39m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39mdescribe_state()\n\u001b[1;32m 164\u001b[0m state\u001b[39m.\u001b[39mupdate(\n\u001b[1;32m 165\u001b[0m {\n\u001b[0;32m--> 166\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mnodes\u001b[39m\u001b[39m\"\u001b[39m: {uuid:node\u001b[39m.\u001b[39mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, node \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnodes\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 167\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mlinks\u001b[39m\u001b[39m\"\u001b[39m: {uuid:link\u001b[39m.\u001b[39mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, link \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mlinks\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 168\u001b[0m }\n\u001b[1;32m 169\u001b[0m )\n\u001b[1;32m 170\u001b[0m \u001b[39mreturn\u001b[39;00m state\n",
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/simulator/network/container.py:166\u001b[0m, in \u001b[0;36m<dictcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 159\u001b[0m \u001b[39mProduce a dictionary describing the current state of the Network.\u001b[39;00m\n\u001b[1;32m 160\u001b[0m \n\u001b[1;32m 161\u001b[0m \u001b[39m:return: A dictionary capturing the current state of the Network and its child objects.\u001b[39;00m\n\u001b[1;32m 162\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 163\u001b[0m state \u001b[39m=\u001b[39m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39mdescribe_state()\n\u001b[1;32m 164\u001b[0m state\u001b[39m.\u001b[39mupdate(\n\u001b[1;32m 165\u001b[0m {\n\u001b[0;32m--> 166\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mnodes\u001b[39m\u001b[39m\"\u001b[39m: {uuid:node\u001b[39m.\u001b[39;49mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, node \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnodes\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 167\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mlinks\u001b[39m\u001b[39m\"\u001b[39m: {uuid:link\u001b[39m.\u001b[39mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, link \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mlinks\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 168\u001b[0m }\n\u001b[1;32m 169\u001b[0m )\n\u001b[1;32m 170\u001b[0m \u001b[39mreturn\u001b[39;00m state\n",
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/simulator/network/hardware/base.py:954\u001b[0m, in \u001b[0;36mNode.describe_state\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 941\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 942\u001b[0m \u001b[39mProduce a dictionary describing the current state of this object.\u001b[39;00m\n\u001b[1;32m 943\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 947\u001b[0m \u001b[39m:rtype: Dict\u001b[39;00m\n\u001b[1;32m 948\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 949\u001b[0m state \u001b[39m=\u001b[39m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39mdescribe_state()\n\u001b[1;32m 950\u001b[0m state\u001b[39m.\u001b[39mupdate(\n\u001b[1;32m 951\u001b[0m {\n\u001b[1;32m 952\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mhostname\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mhostname,\n\u001b[1;32m 953\u001b[0m \u001b[39m\"\u001b[39m\u001b[39moperating_state\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39moperating_state\u001b[39m.\u001b[39mvalue,\n\u001b[0;32m--> 954\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mNICs\u001b[39m\u001b[39m\"\u001b[39m: {uuid: nic\u001b[39m.\u001b[39mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, nic \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnics\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 955\u001b[0m \u001b[39m# \"switch_ports\": {uuid, sp for uuid, sp in self.switch_ports.items()},\u001b[39;00m\n\u001b[1;32m 956\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mfile_system\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mfile_system\u001b[39m.\u001b[39mdescribe_state(),\n\u001b[1;32m 957\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mapplications\u001b[39m\u001b[39m\"\u001b[39m: {uuid: app\u001b[39m.\u001b[39mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, app \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mapplications\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 958\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mservices\u001b[39m\u001b[39m\"\u001b[39m: {uuid: svc\u001b[39m.\u001b[39mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, svc \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mservices\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 959\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mprocess\u001b[39m\u001b[39m\"\u001b[39m: {uuid: proc\u001b[39m.\u001b[39mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, proc \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mprocesses\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 960\u001b[0m }\n\u001b[1;32m 961\u001b[0m )\n\u001b[1;32m 962\u001b[0m \u001b[39mreturn\u001b[39;00m state\n",
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/simulator/network/hardware/base.py:954\u001b[0m, in \u001b[0;36m<dictcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 941\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 942\u001b[0m \u001b[39mProduce a dictionary describing the current state of this object.\u001b[39;00m\n\u001b[1;32m 943\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 947\u001b[0m \u001b[39m:rtype: Dict\u001b[39;00m\n\u001b[1;32m 948\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 949\u001b[0m state \u001b[39m=\u001b[39m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39mdescribe_state()\n\u001b[1;32m 950\u001b[0m state\u001b[39m.\u001b[39mupdate(\n\u001b[1;32m 951\u001b[0m {\n\u001b[1;32m 952\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mhostname\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mhostname,\n\u001b[1;32m 953\u001b[0m \u001b[39m\"\u001b[39m\u001b[39moperating_state\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39moperating_state\u001b[39m.\u001b[39mvalue,\n\u001b[0;32m--> 954\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mNICs\u001b[39m\u001b[39m\"\u001b[39m: {uuid: nic\u001b[39m.\u001b[39;49mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, nic \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnics\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 955\u001b[0m \u001b[39m# \"switch_ports\": {uuid, sp for uuid, sp in self.switch_ports.items()},\u001b[39;00m\n\u001b[1;32m 956\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mfile_system\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mfile_system\u001b[39m.\u001b[39mdescribe_state(),\n\u001b[1;32m 957\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mapplications\u001b[39m\u001b[39m\"\u001b[39m: {uuid: app\u001b[39m.\u001b[39mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, app \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mapplications\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 958\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mservices\u001b[39m\u001b[39m\"\u001b[39m: {uuid: svc\u001b[39m.\u001b[39mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, svc \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mservices\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 959\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mprocess\u001b[39m\u001b[39m\"\u001b[39m: {uuid: proc\u001b[39m.\u001b[39mdescribe_state() \u001b[39mfor\u001b[39;00m uuid, proc \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mprocesses\u001b[39m.\u001b[39mitems()},\n\u001b[1;32m 960\u001b[0m }\n\u001b[1;32m 961\u001b[0m )\n\u001b[1;32m 962\u001b[0m \u001b[39mreturn\u001b[39;00m state\n",
"File \u001b[0;32m~/repos/PrimAITE/src/primaite/simulator/network/hardware/base.py:138\u001b[0m, in \u001b[0;36mNIC.describe_state\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 125\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 126\u001b[0m \u001b[39mProduce a dictionary describing the current state of this object.\u001b[39;00m\n\u001b[1;32m 127\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 131\u001b[0m \u001b[39m:rtype: Dict\u001b[39;00m\n\u001b[1;32m 132\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 133\u001b[0m state \u001b[39m=\u001b[39m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39mdescribe_state()\n\u001b[1;32m 134\u001b[0m state\u001b[39m.\u001b[39mupdate(\n\u001b[1;32m 135\u001b[0m {\n\u001b[1;32m 136\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mip_adress\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mstr\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mip_address),\n\u001b[1;32m 137\u001b[0m \u001b[39m\"\u001b[39m\u001b[39msubnet_mask\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mstr\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39msubnet_mask),\n\u001b[0;32m--> 138\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mgateway\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mstr\u001b[39m(\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mgateway),\n\u001b[1;32m 139\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mmac_address\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mmac_address,\n\u001b[1;32m 140\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mspeed\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mspeed,\n\u001b[1;32m 141\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mmtu\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mmtu,\n\u001b[1;32m 142\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mwake_on_lan\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mwake_on_lan,\n\u001b[1;32m 143\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mdns_servers\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdns_servers,\n\u001b[1;32m 144\u001b[0m \u001b[39m\"\u001b[39m\u001b[39menabled\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39menabled,\n\u001b[1;32m 145\u001b[0m }\n\u001b[1;32m 146\u001b[0m )\n\u001b[1;32m 147\u001b[0m \u001b[39mreturn\u001b[39;00m state\n",
"File \u001b[0;32m~/repos/PrimAITE/venv/lib/python3.10/site-packages/pydantic/main.py:720\u001b[0m, in \u001b[0;36mBaseModel.__getattr__\u001b[0;34m(self, item)\u001b[0m\n\u001b[1;32m 718\u001b[0m \u001b[39mreturn\u001b[39;00m pydantic_extra[item]\n\u001b[1;32m 719\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m exc:\n\u001b[0;32m--> 720\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mAttributeError\u001b[39;00m(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39m{\u001b[39;00m\u001b[39mtype\u001b[39m(\u001b[39mself\u001b[39m)\u001b[39m.\u001b[39m\u001b[39m__name__\u001b[39m\u001b[39m!r}\u001b[39;00m\u001b[39m object has no attribute \u001b[39m\u001b[39m{\u001b[39;00mitem\u001b[39m!r}\u001b[39;00m\u001b[39m'\u001b[39m) \u001b[39mfrom\u001b[39;00m \u001b[39mexc\u001b[39;00m\n\u001b[1;32m 721\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 722\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mhasattr\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m\u001b[39m__class__\u001b[39m, item):\n",
"\u001b[0;31mAttributeError\u001b[0m: 'NIC' object has no attribute 'gateway'"
]
}
],
"source": [
"from primaite.simulator.sim_container import Simulation\n",
"from primaite.simulator.network.hardware.nodes.computer import Computer\n",
"from primaite.game.actor.observations import FileObservation\n",
"\n",
"sim = Simulation()\n",
"pc = Computer(hostname=\"beep\", ip_address=\"123.123.123.123\", subnet_mask=\"255.255.255.0\")\n",
"sim.network.add_node(pc)\n",
"f = pc.file_system.create_file(file_name=\"dog.png\")\n",
"\n",
"sim.describe_state()"
]
},
{
"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
}

View File

View File

View File

@@ -0,0 +1,21 @@
from abc import ABC, abstractmethod
from typing import Any, Dict, List
from pydantic import BaseModel
class AbstractAction(BaseModel):
@abstractmethod
def __call__(self, action: Any) -> List[str]:
"""_summary_
:param action: _description_
:type action: Any
:return: _description_
:rtype: List[str]
"""
...
class ActionSpace:
...

View File

@@ -0,0 +1,32 @@
# TODO: remove this comment... This is just here to point out that I've named this 'actor' rather than 'agent'
# That's because I want to point out that this is disctinct from 'agent' in the reinforcement learning sense of the word
# If you disagree, make a comment in the PR review and we can discuss
from abc import ABC, abstractmethod
from typing import Any, Dict, List
from pydantic import BaseModel
from primaite.game.actor.actions import ActionSpace
from primaite.game.actor.observations import ObservationSpace
from primaite.game.actor.rewards import RewardFunction
class AbstractActor(BaseModel):
"""Base class for scripted and RL agents."""
...
class AbstractScriptedActor(AbstractActor):
"""Base class for actors which generate their own behaviour."""
...
class AbstractPuppetActor(AbstractActor):
"""Base class for actors controlled via external messages, such as RL policies."""
...
# class AbstractRLActor(AbstractPuppetActor): ??

View File

@@ -0,0 +1,107 @@
from abc import ABC, abstractmethod
from typing import Any, Dict, Hashable, List
from pydantic import BaseModel
def access_from_nested_dict(dictionary: Dict, keys: List[Hashable]) -> Any:
"""
Access an item from a deeply dictionary with a list of keys.
For example, if the dictionary is {1: 'a', 2: {3: {4: 'b'}}}, then the key [2, 3, 4] would return 'b', and the key
[2, 3] would return {4: 'b'}. Raises a KeyError if specified key does not exist at any level of nesting.
:param dictionary: Deeply nested dictionary
:type dictionary: Dict
:param keys: List of dict keys used to traverse the nested dict. Each item corresponds to one level of depth.
:type keys: List[Hashable]
:return: The value in the dictionary
:rtype: Any
"""
if not keys:
return dictionary
k = keys.pop(0)
try:
return access_from_nested_dict(dictionary[k], keys)
except (TypeError, KeyError):
raise KeyError(f"Cannot find requested key `{k}` in nested dictionary")
class AbstractObservation(BaseModel):
@abstractmethod
def __call__(self, state: Dict) -> Any:
"""_summary_
:param state: _description_
:type state: Dict
:return: _description_
:rtype: Any
"""
...
# receive state dict
class FileObservation(AbstractObservation):
where: List[str]
"""Store information about where in the simulation state dictionary to find the relevatn information."""
def __call__(self, state: Dict) -> Dict:
file_state = access_from_nested_dict(state, self.where)
class ObservationSpace:
"""Manage the observations of an Actor."""
...
# what this class does:
# keep a list of observations
# create observations for an actor from the config
# Example YAML file for agent observation space
"""
arcd_gate:
rl_framework: SB3
rl_algo: PPO
n_learn_steps: 128
n_learn_episodes: 1000
game_layer:
agents:
- ref: client_1_green_user
type: GREEN
node_ref: client_1
service: WebBrowser
pol:
- step: 1
action: START
- ref: client_1_data_manip_red_bot
node_ref: client_1
service: DataManipulationBot
execution_definition:
- server_ip_address: 192.168.1.10
- server_password:
- payload: 'ATTACK'
pol:
- step: 75
action: EXECUTE
simulation:
nodes:
- ref: client_1
hostname: client_1
node_type: Computer
ip_address: 192.168.10.100
services:
- name: DataManipulationBot
links:
endpoint_a:
endpoint_b: 1524552-fgfg4147gdh-25gh4gd
rewards:
"""

View File

@@ -0,0 +1,20 @@
from abc import ABC, abstractmethod
from typing import Any, Dict, List
from pydantic import BaseModel
class AbstractReward(BaseModel):
def __call__(self, states: List[Dict]) -> float:
"""_summary_
:param state: _description_
:type state: Dict
:return: _description_
:rtype: float
"""
...
class RewardFunction(BaseModel):
...

View File

@@ -0,0 +1,6 @@
# What do? Be an entry point for using PrimAITE
# 1. parse monoconfig
# 2. craete simulation
# 3. create actors and configure their actions/observations/rewards/ anything else
# 4. Create connection with ARCD GATE
# 5. idk

View File

@@ -3,6 +3,7 @@ from __future__ import annotations
import math
import os.path
import shutil
from enum import Enum
from pathlib import Path
from typing import Dict, Optional
@@ -42,6 +43,14 @@ def convert_size(size_bytes: int) -> str:
return f"{s} {size_name[i]}"
class FileSystemItemHealthStatus(Enum):
GOOD = 1
COMPROMISED = 2
CORRUPT = 3
RESTORING = 4
REPAIRING = 5
class FileSystemItemABC(SimComponent):
"""
Abstract base class for file system items used in the file system simulation.
@@ -51,6 +60,7 @@ class FileSystemItemABC(SimComponent):
name: str
"The name of the FileSystemItemABC."
health_status: FileSystemItemHealthStatus = FileSystemItemHealthStatus.GOOD
def describe_state(self) -> Dict:
"""
@@ -59,11 +69,7 @@ class FileSystemItemABC(SimComponent):
:return: Current state of this object and child objects.
"""
state = super().describe_state()
state.update(
{
"name": self.name,
}
)
state.update({"name": self.name, "health_status": self.health_status.value})
return state
@property

View File

@@ -163,8 +163,8 @@ class Network(SimComponent):
state = super().describe_state()
state.update(
{
"nodes": {i for i, node in self._node_id_map.items()},
"links": {i: link.describe_state() for i, link in self._link_id_map.items()},
"nodes": {uuid: node.describe_state() for uuid, node in self.nodes.items()},
"links": {uuid: link.describe_state() for uuid, link in self.links.items()},
}
)
return state