diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py index 3d127d985..7438f1eac 100644 --- a/monkey/monkey_island/cc/app.py +++ b/monkey/monkey_island/cc/app.py @@ -49,6 +49,7 @@ from monkey_island.cc.resources.root import Root from monkey_island.cc.resources.security_report import SecurityReport from monkey_island.cc.resources.telemetry import Telemetry from monkey_island.cc.resources.telemetry_feed import TelemetryFeed +from monkey_island.cc.resources.terminate_all_agents import TerminateAllAgents from monkey_island.cc.resources.version import Version from monkey_island.cc.resources.zero_trust.finding_event import ZeroTrustFindingEvent from monkey_island.cc.resources.zero_trust.zero_trust_report import ZeroTrustReport @@ -212,6 +213,7 @@ def init_restful_endpoints(api: FlaskDIWrapper): def init_rpc_endpoints(api: FlaskDIWrapper): api.add_resource(ResetAgentConfiguration) api.add_resource(ClearSimulationData) + api.add_resource(TerminateAllAgents) def init_app(mongo_url: str, container: DIContainer): diff --git a/monkey/monkey_island/cc/resources/terminate_all_agents.py b/monkey/monkey_island/cc/resources/terminate_all_agents.py new file mode 100644 index 000000000..70603305f --- /dev/null +++ b/monkey/monkey_island/cc/resources/terminate_all_agents.py @@ -0,0 +1,39 @@ +import logging +from http import HTTPStatus +from json import JSONDecodeError + +from flask import request + +from monkey_island.cc.event_queue import IIslandEventQueue, IslandEventTopic +from monkey_island.cc.resources.AbstractResource import AbstractResource +from monkey_island.cc.resources.request_authentication import jwt_required + +logger = logging.getLogger(__name__) + + +class TerminateAllAgents(AbstractResource): + urls = ["/api/terminate-all-agents"] + + def __init__( + self, + island_event_queue: IIslandEventQueue, + ): + self._island_event_queue = island_event_queue + + @jwt_required + def post(self): + try: + terminate_timestamp = request.json["terminate_time"] + if terminate_timestamp is None: + raise ValueError("Terminate signal's timestamp is empty") + elif terminate_timestamp <= 0: + raise ValueError("Terminate signal's timestamp is not a positive integer") + + self._island_event_queue.publish( + IslandEventTopic.TERMINATE_AGENTS, timestamp=terminate_timestamp + ) + + except (JSONDecodeError, TypeError, ValueError, KeyError) as err: + return {"error": err}, HTTPStatus.BAD_REQUEST + + return {}, HTTPStatus.NO_CONTENT