diff --git a/build_scripts/appimage/server_config.json.standard b/build_scripts/appimage/server_config.json.standard index 889654ea2b2..0fee130ccb5 100644 --- a/build_scripts/appimage/server_config.json.standard +++ b/build_scripts/appimage/server_config.json.standard @@ -1,9 +1,6 @@ { "data_dir": "~/.monkey_island", "log_level": "DEBUG", - "environment": { - "server_config": "password" - }, "mongodb": { "start_mongodb": true } diff --git a/envs/monkey_zoo/blackbox/island_client/monkey_island_client.py b/envs/monkey_zoo/blackbox/island_client/monkey_island_client.py index 6df9878e091..7d5124c51d4 100644 --- a/envs/monkey_zoo/blackbox/island_client/monkey_island_client.py +++ b/envs/monkey_zoo/blackbox/island_client/monkey_island_client.py @@ -2,9 +2,11 @@ import logging import time from http import HTTPStatus -from typing import List, Mapping, Optional, Sequence +from threading import Thread +from typing import Any, Dict, List, Mapping, Optional, Sequence from common import OperatingSystem +from common.agent_plugins import AgentPluginRepositoryIndex, AgentPluginType from common.credentials import Credentials from common.types import AgentID, MachineID from envs.monkey_zoo.blackbox.island_client.i_monkey_island_requests import IMonkeyIslandRequests @@ -19,6 +21,7 @@ GET_AGENT_EVENTS_ENDPOINT = "api/agent-events" LOGOUT_ENDPOINT = "api/logout" GET_AGENT_OTP_ENDPOINT = "/api/agent-otp" +INSTALL_PLUGIN_URL = "api/install-agent-plugin" logger = logging.getLogger(__name__) @@ -35,6 +38,86 @@ def __init__(self, requests: IMonkeyIslandRequests): def get_api_status(self): return self.requests.get("api") + def install_agent_plugins(self): + available_plugins_index_url = "api/agent-plugins/available/index" + installed_plugins_manifests_url = "api/agent-plugins/installed/manifests" + + response = self.requests.get(available_plugins_index_url) + plugin_repository_index = AgentPluginRepositoryIndex(**response.json()) + + response = self.requests.get(installed_plugins_manifests_url) + installed_plugins = response.json() + + install_threads: List[Thread] = [] + + # all of the responses from the API endpoints are serialized + # so we don't need to worry about type conversion + for plugin_type in plugin_repository_index.plugins: + install_threads.extend( + self._install_all_agent_plugins_of_type( + plugin_type, plugin_repository_index, installed_plugins + ) + ) + + for t in install_threads: + t.join() + + def _install_all_agent_plugins_of_type( + self, + plugin_type: AgentPluginType, + plugin_repository_index: AgentPluginRepositoryIndex, + installed_plugins: Dict[str, Any], + ) -> Sequence[Thread]: + logger.info(f"Installing {plugin_type} plugins") + install_threads: List[Thread] = [] + for plugin_name in plugin_repository_index.plugins[plugin_type]: + plugin_versions = plugin_repository_index.plugins[plugin_type][plugin_name] + latest_version = str(plugin_versions[-1].version) + + if self._latest_version_already_installed( + installed_plugins, plugin_type, plugin_name, latest_version + ): + logger.info(f"{plugin_type}-{plugin_name}-v{latest_version} is already installed") + continue + + t = Thread( + target=self._install_single_agent_plugin, + args=(plugin_name, plugin_type, latest_version), + daemon=True, + ) + t.start() + install_threads.append(t) + + return install_threads + + def _latest_version_already_installed( + self, + installed_plugins: Dict[str, Any], + plugin_type: AgentPluginType, + plugin_name: str, + latest_version: str, + ) -> bool: + installed_plugin = installed_plugins.get(plugin_type, {}).get(plugin_name, {}) + return installed_plugin and installed_plugin.get("version", "") == latest_version + + def _install_single_agent_plugin( + self, + plugin_name: str, + plugin_type: AgentPluginType, + latest_version: str, + ): + install_plugin_request = { + "plugin_type": plugin_type, + "name": plugin_name, + "version": latest_version, + } + if self.requests.put_json(url=INSTALL_PLUGIN_URL, json=install_plugin_request).ok: + logger.info(f"Installed {plugin_name} {plugin_type} v{latest_version} to Island") + else: + logger.error( + f"Could not install {plugin_name} {plugin_type} " f"v{latest_version} to Island" + ) + @avoid_race_condition def set_masque(self, masque): masque = b"" if masque is None else masque diff --git a/envs/monkey_zoo/blackbox/test_blackbox.py b/envs/monkey_zoo/blackbox/test_blackbox.py index 4ef035c22be..3efad11ced9 100644 --- a/envs/monkey_zoo/blackbox/test_blackbox.py +++ b/envs/monkey_zoo/blackbox/test_blackbox.py @@ -118,10 +118,13 @@ def island_client(monkey_island_requests): @pytest.fixture(autouse=True, scope="session") -def register(island_client): +def setup_island(island_client): logging.info("Registering a new user") island_client.register() + logging.info("Installing all available plugins") + island_client.install_agent_plugins() + @pytest.mark.parametrize( "authenticated_endpoint", @@ -599,6 +602,7 @@ def test_credentials_reuse_ssh_key(self, island_client): def test_depth_2_a(self, island_client): test_name = "Depth2A test suite" + communication_analyzer = CommunicationAnalyzer( island_client, get_target_ips(depth_2_a_test_configuration), @@ -659,6 +663,7 @@ def test_depth_1_a(self, island_client): def test_depth_3_a(self, island_client): test_name = "Depth3A test suite" + communication_analyzer = CommunicationAnalyzer( island_client, get_target_ips(depth_3_a_test_configuration), diff --git a/monkey/common/agent_plugins/agent_plugin_manifest.py b/monkey/common/agent_plugins/agent_plugin_manifest.py index 8ce67cb65b8..3b2239aefa9 100644 --- a/monkey/common/agent_plugins/agent_plugin_manifest.py +++ b/monkey/common/agent_plugins/agent_plugin_manifest.py @@ -1,5 +1,5 @@ import re -from typing import Callable, Mapping, Optional, Tuple, Type +from typing import Callable, Mapping, Optional, Self, Tuple, Type from pydantic import ConstrainedStr, HttpUrl from semver import VersionInfo @@ -24,7 +24,7 @@ class PluginVersion(VersionInfo): @classmethod def __get_validators__(cls): """Return a list of validator methods for pydantic models.""" - yield cls.parse + yield cls.from_str @classmethod def __modify_schema__(cls, field_schema): @@ -37,6 +37,11 @@ def __modify_schema__(cls, field_schema): ] ) + @classmethod + def from_str(cls, version: str) -> Self: + """Convert a string to a PluginVersion.""" + return cls.parse(version) + class AgentPluginManifest(InfectionMonkeyBaseModel): """ diff --git a/monkey/common/agent_plugins/agent_plugin_repository_index.py b/monkey/common/agent_plugins/agent_plugin_repository_index.py index c55cbadec63..03ee3c1ffa1 100644 --- a/monkey/common/agent_plugins/agent_plugin_repository_index.py +++ b/monkey/common/agent_plugins/agent_plugin_repository_index.py @@ -63,3 +63,7 @@ def _infection_monkey_version_parser( return VersionInfo.parse(value) raise TypeError(f'Expected "{DEVELOPMENT}" or a valid semantic version, got {type(value)}') + + @validator("plugins") + def _convert_str_type_to_enum(cls, plugins): + return {AgentPluginType(t): plugins for t, plugins in plugins.items()} diff --git a/monkey/common/agent_plugins/agent_plugin_type.py b/monkey/common/agent_plugins/agent_plugin_type.py index da598676750..1e92c326f78 100644 --- a/monkey/common/agent_plugins/agent_plugin_type.py +++ b/monkey/common/agent_plugins/agent_plugin_type.py @@ -1,7 +1,7 @@ -from enum import Enum +from enum import StrEnum -class AgentPluginType(Enum): +class AgentPluginType(StrEnum): CREDENTIALS_COLLECTOR = "Credentials_Collector" EXPLOITER = "Exploiter" FINGERPRINTER = "Fingerprinter" diff --git a/monkey/monkey_island/cc/server_setup.py b/monkey/monkey_island/cc/server_setup.py index 00fdfb3de39..84f657d6934 100644 --- a/monkey/monkey_island/cc/server_setup.py +++ b/monkey/monkey_island/cc/server_setup.py @@ -37,7 +37,6 @@ from monkey_island.cc.services.initialize import initialize_services # noqa: E402 from monkey_island.cc.setup import ( # noqa: E402 PyWSGILoggingFilter, - install_plugins, island_config_options_validator, setup_agent_event_handlers, setup_island_event_handlers, @@ -68,7 +67,6 @@ def run_monkey_island(): container = _initialize_di_container(ip_addresses, version, config_options.data_dir) setup_island_event_handlers(container) setup_agent_event_handlers(container) - install_plugins(container, config_options.data_dir) _start_island_server(ip_addresses, island_args.setup_only, config_options, container) @@ -104,7 +102,11 @@ def _configure_logging(config_options): def _collect_system_info() -> Tuple[Sequence[IPv4Address], Deployment, Version]: deployment = _get_deployment() + logger.info(f"Monkey Island deployment: {deployment}") + version = Version(get_version(), deployment) + logger.info(f"Monkey Island version: {version.version_number}") + return (get_my_ip_addresses(), deployment, version) diff --git a/monkey/monkey_island/cc/server_utils/consts.py b/monkey/monkey_island/cc/server_utils/consts.py index 0030dc223f6..4d961ecf057 100644 --- a/monkey/monkey_island/cc/server_utils/consts.py +++ b/monkey/monkey_island/cc/server_utils/consts.py @@ -36,8 +36,6 @@ def _get_monkey_island_abs_path() -> str: DEFAULT_LOG_LEVEL = "INFO" -PLUGIN_DIR_NAME = "plugins" - DEFAULT_START_MONGO_DB = True DEFAULT_CRT_PATH = str(Path(MONKEY_ISLAND_ABS_PATH, "cc", "server.crt")) diff --git a/monkey/monkey_island/cc/services/agent_configuration_service/agent_configuration_schema_compiler.py b/monkey/monkey_island/cc/services/agent_configuration_service/agent_configuration_schema_compiler.py index c50dee9c572..a2f57ba5020 100644 --- a/monkey/monkey_island/cc/services/agent_configuration_service/agent_configuration_schema_compiler.py +++ b/monkey/monkey_island/cc/services/agent_configuration_service/agent_configuration_schema_compiler.py @@ -41,13 +41,12 @@ def _add_plugins(self, schema: Dict[str, Any]) -> Dict[str, Any]: schema = self._add_hard_coded_plugins(schema) config_schemas = deepcopy(self._agent_plugin_service.get_all_plugin_configuration_schemas()) + all_plugin_manifests = self._agent_plugin_service.get_all_plugin_manifests() for plugin_type in config_schemas.keys(): for plugin_name in config_schemas[plugin_type].keys(): config_schema = config_schemas[plugin_type][plugin_name] - plugin_manifest = self._agent_plugin_service.get_all_plugin_manifests()[ - plugin_type - ][plugin_name] + plugin_manifest = all_plugin_manifests[plugin_type][plugin_name] config_schema.update(plugin_manifest.dict(simplify=True)) schema = self._add_plugin_to_schema(schema, plugin_type, plugin_name, config_schema) return schema diff --git a/monkey/monkey_island/cc/services/agent_plugin_service/flask_resources/install_agent_plugin.py b/monkey/monkey_island/cc/services/agent_plugin_service/flask_resources/install_agent_plugin.py index bbe75886aad..4de68ef8544 100644 --- a/monkey/monkey_island/cc/services/agent_plugin_service/flask_resources/install_agent_plugin.py +++ b/monkey/monkey_island/cc/services/agent_plugin_service/flask_resources/install_agent_plugin.py @@ -66,7 +66,7 @@ def _get_plugin_information_from_request( raise ValueError(message) try: - plugin_version = PluginVersion(**plugin_version_arg) + plugin_version = PluginVersion.from_str(plugin_version_arg) except ValueError as err: message = f"Invalid plugin version argument: {plugin_version_arg}: {err}." raise ValueError(message) diff --git a/monkey/monkey_island/cc/services/initialize.py b/monkey/monkey_island/cc/services/initialize.py index db225efb514..d9b99881a3f 100644 --- a/monkey/monkey_island/cc/services/initialize.py +++ b/monkey/monkey_island/cc/services/initialize.py @@ -46,7 +46,7 @@ NetworkModelUpdateFacade, initialize_machine_repository, ) -from monkey_island.cc.server_utils.consts import MONKEY_ISLAND_ABS_PATH, PLUGIN_DIR_NAME +from monkey_island.cc.server_utils.consts import MONKEY_ISLAND_ABS_PATH from monkey_island.cc.server_utils.encryption import ILockableEncryptor, RepositoryEncryptor from monkey_island.cc.services import ( AgentSignalsService, @@ -133,13 +133,6 @@ def _register_repositories(container: DIContainer, data_dir: Path): IFileRepository, _decorate_file_repository(LocalStorageFileRepository(data_dir / "runtime_data")), ) - container.register_convention( - IFileRepository, - "plugin_file_repository", - FileRepositoryLockingDecorator( - FileRepositoryLoggingDecorator(LocalStorageFileRepository(data_dir / PLUGIN_DIR_NAME)) - ), - ) container.register_instance(ISimulationRepository, container.resolve(FileSimulationRepository)) container.register_instance( diff --git a/monkey/monkey_island/cc/setup/__init__.py b/monkey/monkey_island/cc/setup/__init__.py index 20b7b9b9e7d..97a7ccfc2ed 100644 --- a/monkey/monkey_island/cc/setup/__init__.py +++ b/monkey/monkey_island/cc/setup/__init__.py @@ -1,4 +1,3 @@ from .pywsgi_logging_filter import PyWSGILoggingFilter from .island_event_handlers import setup_island_event_handlers from .agent_event_handlers import setup_agent_event_handlers -from .plugin_installation import install_plugins diff --git a/monkey/monkey_island/cc/setup/data_dir.py b/monkey/monkey_island/cc/setup/data_dir.py index 66696a61a74..e4c33182c40 100644 --- a/monkey/monkey_island/cc/setup/data_dir.py +++ b/monkey/monkey_island/cc/setup/data_dir.py @@ -5,7 +5,6 @@ from common.utils.file_utils import create_secure_directory from common.version import get_version -from monkey_island.cc.server_utils.consts import MONKEY_ISLAND_ABS_PATH, PLUGIN_DIR_NAME from monkey_island.cc.setup.env_utils import is_running_on_docker from monkey_island.cc.setup.version_file_setup import get_version_from_dir, write_version @@ -23,7 +22,6 @@ def setup_data_dir(data_dir_path: Path): _handle_old_data_directory(data_dir_path) create_secure_directory(data_dir_path) write_version(data_dir_path) - _copy_plugins_into_data_dir(data_dir_path) logger.info(f"Data directory set up in {data_dir_path}.") @@ -92,42 +90,3 @@ def _data_dir_version_mismatch_exists(data_dir_path: Path) -> bool: island_version = get_version() return island_version != data_dir_version - - -def _copy_plugins_into_data_dir(data_dir_path: Path): - plugin_source_dir = Path(MONKEY_ISLAND_ABS_PATH) / PLUGIN_DIR_NAME - try: - plugins_dir = _create_plugins_dir(data_dir_path) - plugin_tar_files = list(plugin_source_dir.glob("*.tar")) - except Exception: - logger.exception( - f"An error occured while creating plugins data directory: {plugin_source_dir}" - ) - return - - for plugin_tar_file in plugin_tar_files: - plugin_dest_path = plugins_dir / plugin_tar_file.name - if plugin_dest_path.exists(): - logger.info( - "Skipping plugin tar file copy: " - f"destination file {plugin_dest_path} already exists." - ) - continue - - try: - logger.info(f"Copying plugin tar file: {plugin_tar_file} -> {plugin_dest_path}") - shutil.copy2(plugin_tar_file, plugin_dest_path) - except FileNotFoundError: - logger.exception( - f"An error occured while copying plugin {plugin_tar_file} " - f"to the data directory: {data_dir_path}" - ) - - -def _create_plugins_dir(plugins_dir_parent_dir: Path) -> Path: - plugins_dir = plugins_dir_parent_dir / PLUGIN_DIR_NAME - logger.info(f"Plugins directory: {plugins_dir}") - - if not plugins_dir.exists(): - create_secure_directory(plugins_dir) - return plugins_dir diff --git a/monkey/monkey_island/cc/setup/plugin_installation.py b/monkey/monkey_island/cc/setup/plugin_installation.py deleted file mode 100644 index 52360b8656f..00000000000 --- a/monkey/monkey_island/cc/setup/plugin_installation.py +++ /dev/null @@ -1,31 +0,0 @@ -import logging -from pathlib import Path - -from common import DIContainer -from monkey_island.cc.services.agent_plugin_service import IAgentPluginService -from monkey_island.cc.services.agent_plugin_service.errors import PluginInstallationError - -from .data_dir import PLUGIN_DIR_NAME - -logger = logging.getLogger(__name__) - - -def install_plugins(container: DIContainer, data_dir: Path): - agent_plugin_service = container.resolve(IAgentPluginService) - - plugins_dir = data_dir / PLUGIN_DIR_NAME - - for path in plugins_dir.iterdir(): - if path.is_symlink(): - logger.warning(f"Skipping symlink at {path}") - continue - if not path.is_file(): - logger.warning(f"Skipping non-file at {path}") - continue - - with open(path, "rb") as f: - plugin_archive = f.read() - try: - agent_plugin_service.install_plugin_archive(plugin_archive) - except PluginInstallationError: - logger.warning(f"Failed to install plugin at {path}") diff --git a/monkey/tests/unit_tests/common/agent_plugins/test_agent_plugin_repository_index.py b/monkey/tests/unit_tests/common/agent_plugins/test_agent_plugin_repository_index.py index 5016141c401..d013159a6e0 100644 --- a/monkey/tests/unit_tests/common/agent_plugins/test_agent_plugin_repository_index.py +++ b/monkey/tests/unit_tests/common/agent_plugins/test_agent_plugin_repository_index.py @@ -1,4 +1,5 @@ import random +from enum import Enum from pathlib import PurePosixPath import pytest @@ -32,7 +33,7 @@ def get_plugin_metadata_with_given_version(version: str) -> AgentPluginMetadata: PLUGIN_VERSION_3_0_1 = get_plugin_metadata_with_given_version("3.0.1") PLUGIN_VERSION_3_0_1_SERIALIZED = { "name": PAYLOAD_PLUGIN_NAME, - "type_": AgentPluginType.PAYLOAD.value, + "type_": str(AgentPluginType.PAYLOAD), "resource_path": "/tmp", "sha256": "7ac0f5c62a9bcb81af3e9d67a764d7bbd3cce9af7cd26c211f136400ebe703c4", "description": "an awesome payload plugin", @@ -51,7 +52,7 @@ def get_plugin_metadata_with_given_version(version: str) -> AgentPluginMetadata: REPOSITORY_INDEX_PLUGINS = {AgentPluginType.PAYLOAD: {PAYLOAD_PLUGIN_NAME: [PLUGIN_VERSION_3_0_1]}} REPOSITORY_INDEX_PLUGINS_SERIALIZED = { - AgentPluginType.PAYLOAD.value: {PAYLOAD_PLUGIN_NAME: [PLUGIN_VERSION_3_0_1_SERIALIZED]} + str(AgentPluginType.PAYLOAD): {PAYLOAD_PLUGIN_NAME: [PLUGIN_VERSION_3_0_1_SERIALIZED]} } @@ -99,7 +100,11 @@ def test_agent_plugin_repository_index_serialization(object_, expected_serializa ], ) def test_agent_plugin_repository_index_deserialization(expected_object, serialized): - assert AgentPluginRepositoryIndex(**serialized) == expected_object + repository_index = AgentPluginRepositoryIndex(**serialized) + + assert repository_index == expected_object + for agent_plugin_type in repository_index.plugins.keys(): + assert isinstance(agent_plugin_type, Enum) def test_plugins_sorted_by_version(): @@ -111,16 +116,14 @@ def test_plugins_sorted_by_version(): repository_index = AgentPluginRepositoryIndex( compatible_infection_monkey_version="development", plugins={ - AgentPluginType.PAYLOAD.value: {PAYLOAD_PLUGIN_NAME: UNSORTED_PLUGIN_VERSIONS}, - AgentPluginType.EXPLOITER.value: {}, - AgentPluginType.CREDENTIALS_COLLECTOR.value: { - PAYLOAD_PLUGIN_NAME: [PLUGIN_VERSION_1_0_0] - }, + AgentPluginType.PAYLOAD: {PAYLOAD_PLUGIN_NAME: UNSORTED_PLUGIN_VERSIONS}, + AgentPluginType.EXPLOITER: {}, + AgentPluginType.CREDENTIALS_COLLECTOR: {PAYLOAD_PLUGIN_NAME: [PLUGIN_VERSION_1_0_0]}, }, ) assert repository_index.plugins == { - AgentPluginType.PAYLOAD.value: {PAYLOAD_PLUGIN_NAME: SORTED_PLUGIN_VERSIONS}, - AgentPluginType.EXPLOITER.value: {}, - AgentPluginType.CREDENTIALS_COLLECTOR.value: {PAYLOAD_PLUGIN_NAME: [PLUGIN_VERSION_1_0_0]}, + AgentPluginType.PAYLOAD: {PAYLOAD_PLUGIN_NAME: SORTED_PLUGIN_VERSIONS}, + AgentPluginType.EXPLOITER: {}, + AgentPluginType.CREDENTIALS_COLLECTOR: {PAYLOAD_PLUGIN_NAME: [PLUGIN_VERSION_1_0_0]}, } diff --git a/monkey/tests/unit_tests/monkey_island/cc/services/agent_plugin_service/flask_resources/test_install_agent_plugin.py b/monkey/tests/unit_tests/monkey_island/cc/services/agent_plugin_service/flask_resources/test_install_agent_plugin.py index 4dbe884164b..e2bd5c68aa3 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/services/agent_plugin_service/flask_resources/test_install_agent_plugin.py +++ b/monkey/tests/unit_tests/monkey_island/cc/services/agent_plugin_service/flask_resources/test_install_agent_plugin.py @@ -17,9 +17,9 @@ PLUGIN_TYPE = "Exploiter" PLUGIN_NAME = "RDP" VERSION_DICT = {"major": "1", "minor": "0", "patch": "1"} -VERSION = '{"major": "1", "minor": "0", "patch": "1"}' +VERSION = "1.0.1" REQUEST_JSON_DATA = ( - f'{{"plugin_type": "{PLUGIN_TYPE}", "name": "{PLUGIN_NAME}", "version": {VERSION}}}' + f'{{"plugin_type": "{PLUGIN_TYPE}", "name": "{PLUGIN_NAME}", "version": "{VERSION}"}}' ) @@ -64,7 +64,7 @@ def test_install_plugin__json(agent_plugin_service, flask_client): agent_plugin_service.install_plugin_from_repository.assert_called_with( plugin_type=AgentPluginType(PLUGIN_TYPE), plugin_name=PLUGIN_NAME, - plugin_version=PluginVersion(**VERSION_DICT), + plugin_version=PluginVersion.from_str(VERSION), ) diff --git a/monkey/tests/unit_tests/monkey_island/cc/setup/test_data_dir.py b/monkey/tests/unit_tests/monkey_island/cc/setup/test_data_dir.py index 3be7807c9f3..e476784b11d 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/setup/test_data_dir.py +++ b/monkey/tests/unit_tests/monkey_island/cc/setup/test_data_dir.py @@ -1,10 +1,7 @@ from pathlib import Path import pytest -from tests.monkey_island.utils import assert_linux_permissions, assert_windows_permissions -from common.utils.environment import is_windows_os -from monkey_island.cc.server_utils.consts import PLUGIN_DIR_NAME from monkey_island.cc.setup.data_dir import IncompatibleDataDirectory, setup_data_dir from monkey_island.cc.setup.env_utils import DOCKER_ENV_VAR from monkey_island.cc.setup.version_file_setup import _version_filename @@ -132,70 +129,3 @@ def test_old_data_dir_docker_no_version(monkeypatch, temp_data_dir_path): with pytest.raises(IncompatibleDataDirectory): setup_data_dir(temp_data_dir_path) - - -def test_plugin_dir_created(temp_data_dir_path): - setup_data_dir(temp_data_dir_path) - assert (temp_data_dir_path / PLUGIN_DIR_NAME).is_dir() - - -def test_plugin_dir_permissions(temp_data_dir_path): - setup_data_dir(temp_data_dir_path) - if is_windows_os(): - assert_windows_permissions(temp_data_dir_path / PLUGIN_DIR_NAME) - else: - assert_linux_permissions(temp_data_dir_path / PLUGIN_DIR_NAME) - - -def test_plugins_copied_to_plugin_dir(monkeypatch, tmp_path, temp_data_dir_path): - plugin_contents = "test plugin" - plugin_src_dir = tmp_path / PLUGIN_DIR_NAME - plugin_src_dir.mkdir() - test_plugin = plugin_src_dir / "test_plugin.tar" - test_plugin.write_text(plugin_contents) - monkeypatch.setattr("monkey_island.cc.setup.data_dir.MONKEY_ISLAND_ABS_PATH", tmp_path) - - setup_data_dir(temp_data_dir_path) - assert (temp_data_dir_path / PLUGIN_DIR_NAME / test_plugin.name).read_text() == plugin_contents - - -def test_plugins_in_plugin_dir_not_overwitten( - monkeypatch, tmp_path, temp_data_dir_path, temp_version_file_path -): - temp_data_dir_path.mkdir() - temp_version_file_path.write_text(current_version) - - test_plugin_name = "test_plugin.tar" - original_plugin_contents = "original plugin" - plugin_dir = temp_data_dir_path / PLUGIN_DIR_NAME - plugin_dir.mkdir() - plugin_dir_plugin = plugin_dir / test_plugin_name - plugin_dir_plugin.write_text(original_plugin_contents) - - plugin_src_dir = tmp_path / PLUGIN_DIR_NAME - plugin_src_dir.mkdir() - new_plugin = plugin_src_dir / test_plugin_name - new_plugin.write_text("new plugin") - monkeypatch.setattr("monkey_island.cc.setup.data_dir.MONKEY_ISLAND_ABS_PATH", tmp_path) - - setup_data_dir(temp_data_dir_path) - - assert plugin_dir_plugin.read_text() == original_plugin_contents - - -def test_setup_plugin_dir_existing_dir_permissions(temp_data_dir_path): - if is_windows_os(): - assert_permissions = assert_windows_permissions - else: - assert_permissions = assert_linux_permissions - - plugin_dir_path = temp_data_dir_path / PLUGIN_DIR_NAME - temp_data_dir_path.mkdir() - plugin_dir_path.mkdir() - - assert plugin_dir_path.is_dir() - with pytest.raises(AssertionError): - assert_permissions(plugin_dir_path) - - setup_data_dir(plugin_dir_path) - assert_permissions(plugin_dir_path) diff --git a/vulture_allowlist.py b/vulture_allowlist.py index 49e501e8950..af213b6d5ef 100644 --- a/vulture_allowlist.py +++ b/vulture_allowlist.py @@ -199,6 +199,7 @@ AgentPluginRepositoryIndex._infection_monkey_version_parser AgentPluginRepositoryIndex._sort_plugins_by_version AgentPluginRepositoryIndex.use_enum_values +AgentPluginRepositoryIndex._convert_str_type_to_enum CPUConsumptionEvent.cpu_number CPUConsumptionEvent.utilization