Added the API /test/clear_caches

Currently clears only the reports from Mongo
This commit is contained in:
Shay Nehmad 2020-02-23 14:02:18 +02:00
parent 51099504e3
commit 4461097c60
7 changed files with 77 additions and 1 deletions

View File

@ -85,3 +85,13 @@ class MonkeyIslandClient(object):
def is_all_monkeys_dead(self):
query = {'dead': False}
return len(self.find_monkeys_in_db(query)) == 0
def clear_caches(self):
"""
Tries to clear caches.
:raises: If error (by error code), raises the error
:return: The response
"""
response = self.requests.delete("api/test/clear_caches")
response.raise_for_status()
return response

View File

@ -61,6 +61,14 @@ class MonkeyIslandRequests(object):
headers=self.get_jwt_header(),
verify=False)
@_Decorators.refresh_jwt_token
def delete(self, url):
return requests.delete( # noqa: DOU123
self.addr + url,
headers=self.get_jwt_header(),
verify=False
)
@_Decorators.refresh_jwt_token
def get_jwt_header(self):
return {"Authorization": "JWT " + self.token}

View File

@ -25,6 +25,7 @@ from monkey_island.cc.resources.root import Root
from monkey_island.cc.resources.telemetry import Telemetry
from monkey_island.cc.resources.telemetry_feed import TelemetryFeed
from monkey_island.cc.resources.pba_file_download import PBAFileDownload
from monkey_island.cc.resources.test.clear_caches import ClearCaches
from monkey_island.cc.resources.version_update import VersionUpdate
from monkey_island.cc.resources.pba_file_upload import FileUpload
from monkey_island.cc.resources.attack.attack_config import AttackConfiguration
@ -116,6 +117,7 @@ def init_api_resources(api):
api.add_resource(VersionUpdate, '/api/version-update', '/api/version-update/')
api.add_resource(MonkeyTest, '/api/test/monkey')
api.add_resource(ClearCaches, '/api/test/clear_caches')
api.add_resource(LogTest, '/api/test/log')

View File

@ -1,4 +1,4 @@
"""
This package contains resources used by blackbox tests
to analize test results, download logs and so on.
to analyze test results, download logs and so on.
"""

View File

@ -0,0 +1,35 @@
import logging
import flask_restful
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.services.attack.attack_report import AttackReportService
from monkey_island.cc.services.reporting.report import ReportService
NOT_ALL_REPORTS_DELETED = "Not all reports have been cleared from the DB!"
logger = logging.getLogger(__name__)
class ClearCaches(flask_restful.Resource):
"""
Used for timing tests - we want to get actual execution time of functions in BlackBox without caching - so we use this
to clear the caches.
:note: DO NOT CALL THIS IN PRODUCTION CODE as this will slow down the user experience.
"""
@jwt_required()
def delete(self, **kw):
try:
logger.warning("Trying to clear caches! Make sure this is not production")
ReportService.delete_saved_report_if_exists()
AttackReportService.delete_saved_report_if_exists()
# TODO: Monkey.clear_caches(), clear LRU caches of function in the Monkey object
except RuntimeError as e:
logger.exception(e)
flask_restful.abort(500, error_info=str(e))
if ReportService.is_report_generated() or AttackReportService.is_report_generated():
logger.exception(NOT_ALL_REPORTS_DELETED)
flask_restful.abort(500, error_info=NOT_ALL_REPORTS_DELETED)
return {"success": "true"}

View File

@ -103,3 +103,11 @@ class AttackReportService:
"""
generated_report = mongo.db.attack_report.find_one({})
return generated_report is not None
@staticmethod
def delete_saved_report_if_exists():
if AttackReportService.is_report_generated():
latest_report = mongo.db.attack_report.find_one({'name': REPORT_NAME})
delete_result = mongo.db.report.delete_one({"_id": latest_report['_id']})
if delete_result.deleted_count != 1:
raise RuntimeError("Error while deleting report:" + str(delete_result))

View File

@ -773,6 +773,19 @@ class ReportService:
return False
@staticmethod
def delete_saved_report_if_exists():
"""
This function clears the saved report from the DB.
:raises RuntimeError if deletion failed
"""
latest_report_doc = mongo.db.report.find_one({}, {'meta.latest_monkey_modifytime': 1})
if latest_report_doc:
delete_result = mongo.db.report.delete_one({"_id": latest_report_doc['_id']})
if delete_result.deleted_count != 1:
raise RuntimeError("Error while deleting report:" + str(delete_result))
@staticmethod
def decode_dot_char_before_mongo_insert(report_dict):
"""