From aaa3aade20aa57ba708a87507e69379e1fa84f1d Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 17 May 2022 15:29:55 +0300 Subject: [PATCH] Island: Define repository interfaces for config and edge --- monkey/monkey_island/cc/dal/IRepository.py | 59 +++++++++++++++++++ monkey/monkey_island/cc/services/config.py | 7 +++ monkey/monkey_island/cc/services/edge/edge.py | 3 + 3 files changed, 69 insertions(+) create mode 100644 monkey/monkey_island/cc/dal/IRepository.py diff --git a/monkey/monkey_island/cc/dal/IRepository.py b/monkey/monkey_island/cc/dal/IRepository.py new file mode 100644 index 000000000..8dd84a330 --- /dev/null +++ b/monkey/monkey_island/cc/dal/IRepository.py @@ -0,0 +1,59 @@ +from abc import ABC +from typing import Any, Optional, Sequence + +from monkey_island.cc.models import Config, Monkey +from monkey_island.cc.models.edge import Edge + + +class IRepository(ABC): + + # Config + ############################################### + + # This returns the current config + # TODO investigate if encryption should be here or where + def get_config(self) -> dict: + pass + + def set_config(self, config: dict): + pass + + # Used when only a subset of config is submitted, for example only PBAFiles + # Used by passing keys, like ['monkey', 'post_breach_actions', 'linux_filename'] + # Using a list is less ambiguous IMO, than using . notation + def set_config_field(self, key_list: Sequence[str], value: Any): + pass + + # Used when only a subset of config is needed, for example only PBAFiles + # Used by passing keys, like ['monkey', 'post_breach_actions', 'linux_filename'] + # Using a list is less ambiguous IMO, than using . notation + # TODO Still in doubt about encryption, this should probably be determined automatically + def get_config_field(self, key_list: Sequence[str]) -> Any: + pass + + # Edges + ############################################### + + def get_all_edges(self): + pass + + def get_edge(self, src_node_id: str, dst_node_id: str) -> Edge: + pass + + def save_edge(self, edge: Edge): + pass + + def get_by_dst_node(self, dst_node_id: str) -> Sequence[Edge]: + pass + + # If tunnel is None then it gets all edges, if True/False then gets only + # tunneling/non-tunneling edges + def get_by_src_node(self, src_node_id: str, tunnel: Optional[bool] = None) -> Sequence[Edge]: + pass + + def get_by_id(self, edge_id: str) -> Edge: + pass + + # Scan telemetries might change the label once we know more about the target system + def set_label(self, edge_id: str, label: str): + pass diff --git a/monkey/monkey_island/cc/services/config.py b/monkey/monkey_island/cc/services/config.py index f0977ef66..293d1bffb 100644 --- a/monkey/monkey_island/cc/services/config.py +++ b/monkey/monkey_island/cc/services/config.py @@ -70,6 +70,9 @@ class ConfigService: :param is_island: If True, will include island specific configuration parameters. :return: The entire global config. """ + + # is_initial_config and should_decrypt are only there to compare if we are on the + # default configuration or did user modified it already config = ( mongo.db.config.find_one({"name": "initial" if is_initial_config else "newconfig"}) or {} @@ -95,9 +98,12 @@ class ConfigService: :return: The value of the requested config key. """ config_key = functools.reduce(lambda x, y: x + "." + y, config_key_as_arr) + + # This should just call get_config from repository. If None, then call get_default prob config = mongo.db.config.find_one( {"name": "initial" if is_initial_config else "newconfig"}, {config_key: 1} ) + for config_key_part in config_key_as_arr: config = config[config_key_part] if should_decrypt: @@ -141,6 +147,7 @@ class ConfigService: def get_config_schema(): return SCHEMA + # Not added to interface because it's doable by get_config_field + set_config_field @staticmethod def add_item_to_config_set_if_dont_exist(item_path_array, item_value, should_encrypt): item_key = ".".join(item_path_array) diff --git a/monkey/monkey_island/cc/services/edge/edge.py b/monkey/monkey_island/cc/services/edge/edge.py index dae19ccd8..c62aae7a4 100644 --- a/monkey/monkey_island/cc/services/edge/edge.py +++ b/monkey/monkey_island/cc/services/edge/edge.py @@ -65,6 +65,9 @@ class EdgeService(Edge): except DoesNotExist: return [] + # TODO it's not entirelly clear why the tunnel is unset in + # monkey/monkey_island/cc/services/telemetry/processing/tunnel.py:15 + # Either way this can be done by fetching, modifying and saving def disable_tunnel(self): self.tunnel = False self.save()