diff --git a/monkey/monkey_island/cc/server_setup.py b/monkey/monkey_island/cc/server_setup.py index 1d5bfa9da..91332d7b3 100644 --- a/monkey/monkey_island/cc/server_setup.py +++ b/monkey/monkey_island/cc/server_setup.py @@ -3,6 +3,7 @@ import json import logging import sys from pathlib import Path +from typing import Sequence, Tuple import gevent.hub import requests @@ -27,6 +28,7 @@ from monkey_island.cc.arg_parser import parse_cli_args # noqa: E402 from monkey_island.cc.server_utils.consts import ( # noqa: E402 GEVENT_EXCEPTION_LOG, MONGO_CONNECTION_TIMEOUT, + MONKEY_ISLAND_ABS_PATH, ) from monkey_island.cc.server_utils.island_logger import reset_logger, setup_logging # noqa: E402 from monkey_island.cc.services.initialize import initialize_services # noqa: E402 @@ -50,7 +52,9 @@ def run_monkey_island(): _exit_on_invalid_config_options(config_options) _configure_logging(config_options) - container = _initialize_di_container(config_options.data_dir) + ip_addresses, deployment, version = _collect_system_info() + _send_analytics(deployment, version) + container = _initialize_di_container(ip_addresses, version, config_options.data_dir) _initialize_mongodb_connection(config_options.start_mongodb, config_options.data_dir) _start_island_server(island_args.setup_only, config_options, container) @@ -85,8 +89,39 @@ def _configure_logging(config_options): setup_logging(config_options.data_dir, config_options.log_level) -def _initialize_di_container(data_dir: Path) -> DIContainer: - return initialize_services(data_dir) +def _collect_system_info() -> Tuple[Sequence[str], Deployment, Version]: + deployment = _get_deployment() + version = Version(get_version(), deployment) + return (get_ip_addresses(), deployment, version) + + +def _get_deployment() -> Deployment: + deployment_file_path = Path(MONKEY_ISLAND_ABS_PATH) / "cc" / "deployment.json" + try: + with open(deployment_file_path, "r") as deployment_info_file: + deployment_info = json.load(deployment_info_file) + return Deployment[deployment_info["deployment"].upper()] + except KeyError as err: + raise Exception( + f"The deployment file ({deployment_file_path}) did not contain the expected data: " + f"missing key {err}" + ) + except Exception as err: + raise Exception(f"Failed to fetch the deployment from {deployment_file_path}: {err}") + + +def _initialize_di_container( + ip_addresses: Sequence[str], version: Version, data_dir: Path +) -> DIContainer: + container = DIContainer() + + container.register_convention(Sequence[str], "ip_addresses", ip_addresses) + container.register_instance(Version, version) + container.register_convention(Path, "data_dir", data_dir) + + initialize_services(container, data_dir) + + return container def _initialize_mongodb_connection(start_mongodb: bool, data_dir: Path): @@ -145,7 +180,6 @@ def _start_island_server( error_log=logger, ) _log_init_info() - _send_analytics(container) http_server.serve_forever() @@ -189,9 +223,7 @@ ANALYTICS_URL = ( ) -def _send_analytics(di_container): - version = di_container.resolve(Version) - deployment = di_container.resolve(Deployment) +def _send_analytics(deployment: Deployment, version: Version): url = ANALYTICS_URL.format(deployment=deployment.value, version=version.version_number) try: response = requests.get(url).json() diff --git a/monkey/monkey_island/cc/services/initialize.py b/monkey/monkey_island/cc/services/initialize.py index fc7b6e432..2a824e752 100644 --- a/monkey/monkey_island/cc/services/initialize.py +++ b/monkey/monkey_island/cc/services/initialize.py @@ -1,7 +1,5 @@ -import json import logging from pathlib import Path -from typing import Sequence from pubsub.core import Publisher from pymongo import MongoClient @@ -16,9 +14,6 @@ from common.aws import AWSInstance from common.common_consts.telem_categories import TelemCategoryEnum from common.event_queue import IEventQueue, PyPubSubEventQueue from common.utils.file_utils import get_binary_io_sha256_hash -from common.version import get_version -from monkey_island.cc import Version -from monkey_island.cc.deployment import Deployment from monkey_island.cc.repository import ( AgentBinaryRepository, FileAgentConfigurationRepository, @@ -49,7 +44,6 @@ from monkey_island.cc.services.telemetry.processing.credentials.credentials_pars from monkey_island.cc.services.telemetry.processing.processing import ( TELEMETRY_CATEGORY_TO_PROCESSING_FUNC, ) -from monkey_island.cc.services.utils.network_utils import get_ip_addresses from monkey_island.cc.setup.mongo.mongo_setup import MONGO_URL from . import AuthenticationService @@ -58,21 +52,17 @@ from .reporting.report import ReportService logger = logging.getLogger(__name__) AGENT_BINARIES_PATH = Path(MONKEY_ISLAND_ABS_PATH) / "cc" / "binaries" -DEPLOYMENT_FILE_PATH = Path(MONKEY_ISLAND_ABS_PATH) / "cc" / "deployment.json" REPOSITORY_KEY_FILE_NAME = "repository_key.bin" -def initialize_services(data_dir: Path) -> DIContainer: - container = DIContainer() +def initialize_services(container: DIContainer, data_dir: Path): _register_conventions(container, data_dir) - container.register_instance(Deployment, _get_depyloyment_from_file(DEPLOYMENT_FILE_PATH)) container.register_instance(AWSInstance, AWSInstance()) container.register_instance(MongoClient, MongoClient(MONGO_URL, serverSelectionTimeoutMS=100)) container.register_instance( ILockableEncryptor, RepositoryEncryptor(data_dir / REPOSITORY_KEY_FILE_NAME) ) - container.register_instance(Version, container.resolve(Version)) container.register(Publisher, Publisher) container.register_instance(IEventQueue, container.resolve(PyPubSubEventQueue)) @@ -88,11 +78,8 @@ def initialize_services(data_dir: Path) -> DIContainer: container.resolve(ICredentialsRepository), ) - return container - def _register_conventions(container: DIContainer, data_dir: Path): - container.register_convention(Path, "data_dir", data_dir) container.register_convention( AgentConfiguration, "default_agent_configuration", DEFAULT_AGENT_CONFIGURATION ) @@ -102,8 +89,6 @@ def _register_conventions(container: DIContainer, data_dir: Path): DEFAULT_RANSOMWARE_AGENT_CONFIGURATION, ) container.register_convention(Path, "island_log_file_path", get_log_file_path(data_dir)) - container.register_convention(str, "version_number", get_version()) - container.register_convention(Sequence[str], "ip_addresses", get_ip_addresses()) def _register_repositories(container: DIContainer, data_dir: Path): @@ -161,22 +146,6 @@ def _log_agent_binary_hashes(agent_binary_repository: IAgentBinaryRepository): logger.info(f"{os} agent: SHA-256 hash: {binary_sha256_hash}") -# TODO: The deployment should probably be passed into initialize_services(), but we can rework that -# when we refactor this file. -def _get_depyloyment_from_file(file_path: Path) -> Deployment: - try: - with open(file_path, "r") as deployment_info_file: - deployment_info = json.load(deployment_info_file) - return Deployment[deployment_info["deployment"].upper()] - except KeyError as err: - raise Exception( - f"The deployment file ({file_path}) did not contain the expected data: " - f"missing key {err}" - ) - except Exception as err: - raise Exception(f"Failed to fetch the deployment from {file_path}: {err}") - - def _register_services(container: DIContainer): container.register_instance(AWSService, container.resolve(AWSService)) container.register_instance(LocalMonkeyRunService, container.resolve(LocalMonkeyRunService))