Refactor subcommands, config etc.
This commit is contained in:
parent
7e3e101987
commit
ec08bf71ab
42
.idea/workspace.xml
generated
42
.idea/workspace.xml
generated
@ -4,26 +4,15 @@
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="7a3ac8e1-7fbf-4aa7-9cf9-a51d7ade8503" name="Changes" comment="SYNC">
|
||||
<change afterPath="$PROJECT_DIR$/code/iottb/cli.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/code/iottb/utils/__init__.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/2024-bsc-sebastian-lenzlinger.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/2024-bsc-sebastian-lenzlinger.iml" afterDir="false" />
|
||||
<list default="true" id="7a3ac8e1-7fbf-4aa7-9cf9-a51d7ade8503" name="Changes" comment="Refactor various names.">
|
||||
<change afterPath="$PROJECT_DIR$/code/iottb/subcommands/add_device.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/archive/metadata_utils.py" beforeDir="false" afterPath="$PROJECT_DIR$/archive/metadata_utils.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/__init__.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/__main__.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/__main__.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/config.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/definitions.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/models/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/models/__init__.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/models/capture_metadata_model.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/models/capture_metadata_model.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/models/device_metadata_model.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/models/device_metadata_model.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/subcommands/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/subcommands/__init__.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/subcommands/initialize_device_root_dir.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/subcommands/init.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/subcommands/sniff.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/subcommands/capture.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/utils/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/subcommands/config.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/utils/capture_metadata_utils.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/utils/capture_metadata_utils.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/utils/device_metadata_utils.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/utils/device_metadata_utils.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/kydcap/utils/tcpdump_utils.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/utils/tcpdump_utils.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/tests/utils/test_capture_metadata_utils.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/tests/utils/test_capture_metadata_utils.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/iottb/__main__.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/__main__.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/iottb/definitions.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/definitions.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/iottb/models/capture_metadata_model.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/models/capture_metadata_model.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/iottb/models/device_metadata_model.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/models/device_metadata_model.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/iottb/subcommands/capture.py" beforeDir="false" afterPath="$PROJECT_DIR$/code/iottb/subcommands/capture.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/code/iottb/subcommands/init.py" beforeDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@ -165,7 +154,7 @@
|
||||
<workItem from="1714554269789" duration="56478000" />
|
||||
<workItem from="1714616237168" duration="6135000" />
|
||||
<workItem from="1714850899817" duration="2659000" />
|
||||
<workItem from="1714917763516" duration="1306000" />
|
||||
<workItem from="1714917763516" duration="6656000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="Add code for capture testbed. This is a huge commit. End of day sync...">
|
||||
<option name="closed" value="true" />
|
||||
@ -223,7 +212,15 @@
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1714823516954</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="8" />
|
||||
<task id="LOCAL-00008" summary="Refactor various names.">
|
||||
<option name="closed" value="true" />
|
||||
<created>1714919098392</created>
|
||||
<option name="number" value="00008" />
|
||||
<option name="presentableId" value="LOCAL-00008" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1714919098392</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="9" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
@ -280,7 +277,8 @@
|
||||
<MESSAGE value="Update gitignore again." />
|
||||
<MESSAGE value="Start tracking development config files." />
|
||||
<MESSAGE value="SYNC" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="SYNC" />
|
||||
<MESSAGE value="Refactor various names." />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="Refactor various names." />
|
||||
</component>
|
||||
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
||||
<SUITE FILE_PATH="coverage/2024_bsc_sebastian_lenzlinger$__init__.coverage" NAME="__init__ Coverage Results" MODIFIED="1714619300966" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/code/kydcap" />
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import argparse
|
||||
|
||||
from iottb.subcommands.capture import setup_capture_parser
|
||||
from iottb.subcommands.init import setup_init_iottb_root_parser
|
||||
from iottb.subcommands.add_device import setup_init_device_root_parser
|
||||
|
||||
CAP_DIR_PREFIX = ...
|
||||
|
||||
@ -16,7 +16,7 @@ def setup_argparse():
|
||||
subparsers = root_parser.add_subparsers(title="subcommands", required=True, dest="command")
|
||||
|
||||
setup_capture_parser(subparsers)
|
||||
setup_init_iottb_root_parser(subparsers)
|
||||
setup_init_device_root_parser(subparsers)
|
||||
|
||||
return root_parser
|
||||
|
||||
|
||||
@ -6,7 +6,10 @@ DEVICE_METADATA_FILE = "device-metadata.json"
|
||||
CAPTURE_METADATA_FILE = "capture-metadata.json"
|
||||
TODAY_DATE_STRING = datetime.now().strftime("%d%b%Y").lower() # TODO convert to function in utils or so
|
||||
|
||||
|
||||
AFFIRMATIVE_USER_RESPONSE = {"yes", "y", "true", "Y", "Yes", "YES"}
|
||||
NEGATIVE_USER_RESPONSE = {"no", "n", "N", "No"}
|
||||
YES_DEFAULT = AFFIRMATIVE_USER_RESPONSE.union({"", " "})
|
||||
NO_DEFAULT = NEGATIVE_USER_RESPONSE.union({"", " "})
|
||||
@unique
|
||||
@global_enum
|
||||
class ReturnCodes(Flag):
|
||||
|
||||
@ -9,7 +9,7 @@ from pydantic import BaseModel, Field
|
||||
from iottb.definitions import ReturnCodes
|
||||
|
||||
|
||||
class KydcapCaptureMetadata(BaseModel):
|
||||
class CaptureMetadata(BaseModel):
|
||||
# Required Fields
|
||||
device_id: str
|
||||
capture_id: uuid.UUID = Field(default_factory=lambda: str(uuid.uuid4()))
|
||||
|
||||
@ -21,6 +21,7 @@ class DeviceMetadata(BaseModel):
|
||||
date_created: str = Field(default_factory=lambda: datetime.now().strftime('%d-%m-%YT%H:%M:%S').lower())
|
||||
|
||||
# Optional Fields
|
||||
aliases: List[str] = Field(default_factory=lambda: [])
|
||||
device_type: Optional[str] = None
|
||||
device_serial_number: Optional[str] = None
|
||||
device_firmware_version: Optional[str] = None
|
||||
|
||||
59
code/iottb/subcommands/add_device.py
Normal file
59
code/iottb/subcommands/add_device.py
Normal file
@ -0,0 +1,59 @@
|
||||
import pathlib
|
||||
|
||||
from iottb import definitions
|
||||
from iottb.definitions import DEVICE_METADATA_FILE, ReturnCodes
|
||||
from iottb.models.device_metadata_model import DeviceMetadata
|
||||
from iottb.utils.device_metadata_utils import *
|
||||
|
||||
|
||||
def setup_init_device_root_parser(subparsers):
|
||||
parser = subparsers.add_parser("add-device", aliases=["add-device-root", "add"])
|
||||
parser.add_argument("--root", type=pathlib.Path, default=pathlib.Path.cwd())
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument("--guided", action="store_true", help="Guided setup", default=False)
|
||||
group.add_argument("name", action="store", type=str, help="name of device")
|
||||
parser.set_defaults(func=handle_add)
|
||||
|
||||
|
||||
def handle_add(args):
|
||||
print("Entered add-device-root")
|
||||
metadata = None
|
||||
if args.guided:
|
||||
metadata = guided_setup(args.root_dir)
|
||||
else:
|
||||
device_name = args.name
|
||||
args.root_dir.mkdir(parents=True, exist_ok=True)
|
||||
args.root_dir.chdir()
|
||||
metadata = DeviceMetadata(device_name)
|
||||
|
||||
file_path = args.root_dir / DEVICE_METADATA_FILE
|
||||
response = input(f"Confirm device metadata: {metadata.model_dump()} [y/N]")
|
||||
if response.lower() not in definitions.AFFIRMATIVE_USER_RESPONSE.add(""):
|
||||
configure_metadata()
|
||||
assert False, "TODO implement dynamic setup"
|
||||
assert metadata.model_dump() != ""
|
||||
if metadata.save_to_json(file_path) == ReturnCodes.FILE_ALREADY_EXISTS:
|
||||
print("Directory already contains a device metadata file. Aborting operation.")
|
||||
return ReturnCodes.ABORTED
|
||||
assert Path(file_path).exists(), f"{file_path} does not exist"
|
||||
return ReturnCodes.SUCCESS
|
||||
|
||||
|
||||
def configure_metadata():
|
||||
pass
|
||||
|
||||
|
||||
def guided_setup(device_root) -> DeviceMetadata:
|
||||
response = "N"
|
||||
device_name = ""
|
||||
while response.upper() == "N":
|
||||
device_name = input("Please enter name of device: ")
|
||||
if device_name == "" or device_name is None:
|
||||
print("Name cannot be empty")
|
||||
response = input(f"Confirm device name: {device_name} [y/N]")
|
||||
|
||||
assert response.lower() in definitions.AFFIRMATIVE_USER_RESPONSE.add(""), f"{response.upper()} not supported"
|
||||
assert device_name != ""
|
||||
assert device_name is not None
|
||||
return DeviceMetadata(device_name)
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import subprocess
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
||||
from iottb.definitions import *
|
||||
from iottb.models.device_metadata_model import DeviceMetadata
|
||||
from iottb.models.capture_metadata_model import CaptureMetadata
|
||||
|
||||
|
||||
def setup_capture_parser(subparsers):
|
||||
@ -37,7 +39,7 @@ def setup_capture_parser(subparsers):
|
||||
|
||||
def cwd_is_device_root_dir() -> bool:
|
||||
device_metadata_file = Path.cwd() / DEVICE_METADATA_FILE
|
||||
return device_metadata_file.exists()
|
||||
return device_metadata_file.is_file()
|
||||
|
||||
|
||||
def get_user_capture_config():
|
||||
@ -61,57 +63,63 @@ def handle_metadata():
|
||||
return ReturnCodes.SUCCESS
|
||||
|
||||
|
||||
def handle_capture_metadata():
|
||||
device_metadata_json = Path.cwd() / DEVICE_METADATA_FILE
|
||||
device_metadata = DeviceMetadata.load_from_json(device_metadata_json)
|
||||
def get_device_id_from_file(device_metadata_filename: Path) -> str:
|
||||
assert device_metadata_filename.is_file(), f"Device metadata file '{device_metadata_filename} does not exist"
|
||||
device_metadata = DeviceMetadata.load_from_json(device_metadata_filename)
|
||||
device_id = device_metadata.device_id
|
||||
return device_id
|
||||
|
||||
|
||||
def handle_date_dir():
|
||||
def setup_capture_folder():
|
||||
pass
|
||||
|
||||
|
||||
def run_tcpdum(cmd):
|
||||
subprocess.run(cmd)
|
||||
try:
|
||||
p = subprocess.run(cmd)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
def generate_capfile_name():
|
||||
name = datetime.now().strftime("%Y%m%d_%H%M%S") + uuid.uuid4().hex
|
||||
|
||||
def handle_capture(args):
|
||||
if cwd_is_device_root_dir():
|
||||
handle_date_dir()
|
||||
cmd = ['sudo tcpdump', '-i', args.capture_interface]
|
||||
if args.monitor_mode:
|
||||
cmd.append('-I')
|
||||
if args.no_name_resolution:
|
||||
cmd.append('-n')
|
||||
if args.number:
|
||||
cmd.append('-#')
|
||||
if args.print_link_layer:
|
||||
cmd.append('-e')
|
||||
if args.count:
|
||||
cmd.append('-c')
|
||||
cmd.append(str(args.count))
|
||||
elif args.mins:
|
||||
pass
|
||||
print('Executing: ' + ' '.join(cmd))
|
||||
# TODO maybe dump this into file -> put into device metadata
|
||||
try:
|
||||
start_time = datetime.now().strftime('%H:%M:%S')
|
||||
run_tcpdum(cmd)
|
||||
stop_time = datetime.now().strftime('%H:%M:%S')
|
||||
except KeyboardInterrupt:
|
||||
print("Received keyboard interrupt.")
|
||||
exit(ReturnCodes.ABORTED)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Failed to capture packet: {e}")
|
||||
exit(ReturnCodes.FAILURE)
|
||||
except Exception as e:
|
||||
print(f"Failed to capture packet: {e}")
|
||||
exit(ReturnCodes.FAILURE)
|
||||
assert args.device_root is not None, f"Device root directory is required"
|
||||
device_metadata_file = Path.cwd() / DEVICE_METADATA_FILE
|
||||
device_id = get_device_id_from_file(device_metadata_file)
|
||||
assert device_metadata_file.is_file(), f"Device metadata file '{device_metadata_file} does not exist"
|
||||
capture_dir = setup_capture_folder(args.dev_root)
|
||||
cmd = ['sudo', 'tcpdump', '-i', args.capture_interface]
|
||||
if args.monitor_mode:
|
||||
cmd.append('-I')
|
||||
if args.no_name_resolution:
|
||||
cmd.append('-n')
|
||||
if args.number:
|
||||
cmd.append('-#')
|
||||
if args.print_link_layer:
|
||||
cmd.append('-e')
|
||||
if args.count:
|
||||
cmd.append('-c')
|
||||
cmd.append(str(args.count))
|
||||
elif args.mins:
|
||||
pass
|
||||
print('Executing: ' + ' '.join(cmd))
|
||||
# TODO maybe dump this into file -> put into device metadata
|
||||
try:
|
||||
start_time = datetime.now().strftime('%H:%M:%S')
|
||||
run_tcpdum(cmd)
|
||||
stop_time = datetime.now().strftime('%H:%M:%S')
|
||||
except KeyboardInterrupt:
|
||||
print("Received keyboard interrupt.")
|
||||
exit(ReturnCodes.ABORTED)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Failed to capture packet: {e}")
|
||||
exit(ReturnCodes.FAILURE)
|
||||
except Exception as e:
|
||||
print(f"Failed to capture packet: {e}")
|
||||
exit(ReturnCodes.FAILURE)
|
||||
|
||||
return ReturnCodes.SUCCESS
|
||||
else:
|
||||
handle_metadata()
|
||||
return ReturnCodes.SUCCESS
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
import pathlib
|
||||
|
||||
from iottb.definitions import DEVICE_METADATA_FILE
|
||||
from iottb.models.device_metadata_model import DeviceMetadata
|
||||
|
||||
|
||||
def setup_init_iottb_root_parser(subparsers):
|
||||
parser = subparsers.add_parser("init", aliases=["idr"])
|
||||
parser.add_argument("--root_dir", type=pathlib.Path, default=pathlib.Path.cwd())
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument("--dynamic", action="store_true", help="enable guided setup", default=False)
|
||||
group.add_argument("-n", "--name", action="store", type=str, help="name of device")
|
||||
parser.set_defaults(func=handle_idr)
|
||||
|
||||
|
||||
def handle_idr(args):
|
||||
print("Entered iottb initialize-device-root")
|
||||
root_dir = args.root_dir
|
||||
device_name = None
|
||||
if args.dynamic:
|
||||
response = "N"
|
||||
while response == "N":
|
||||
name = input("Please enter name of device: ")
|
||||
# TODO extended config for other fields like apps, firmware etc.
|
||||
response = input(f"Confirm device name: {name} [y/N]")
|
||||
device_name = name
|
||||
else:
|
||||
device_name = args.name
|
||||
root_dir.mkdir(parents=True, exist_ok=True)
|
||||
root_dir.chdir()
|
||||
dev_metadata_model = DeviceMetadata(device_name)
|
||||
file_path = root_dir / device_name / DEVICE_METADATA_FILE
|
||||
assert not file_path.exists(), f"{file_path} already exists"
|
||||
if args.dynamic:
|
||||
response = input(f"Confirm device metadata: {dev_metadata_model.model_dump()} [y/N]")
|
||||
if response.lower() != "y":
|
||||
assert False, "TODO implement dynamic setup"
|
||||
code = dev_metadata_model.save_to_json(file_path)
|
||||
print(f"Device metadata saved to {file_path}")
|
||||
return code
|
||||
Loading…
x
Reference in New Issue
Block a user