From 3ca761f49217380ed29f708930b4807b96f4d1f2 Mon Sep 17 00:00:00 2001 From: "maor.rayzin" Date: Tue, 11 Dec 2018 12:14:38 +0200 Subject: [PATCH] RCR: - started the report exporter manager singleton. - added region parsing using regex - --- monkey/common/cloud/aws.py | 14 ++++++- monkey/monkey_island/cc/services/report.py | 17 +++----- .../monkey_island/report_exporter_manager.py | 40 +++++++++++++++++++ monkey/monkey_island/requirements.txt | 3 +- 4 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 monkey/monkey_island/report_exporter_manager.py diff --git a/monkey/common/cloud/aws.py b/monkey/common/cloud/aws.py index 7937815ef..401bbec40 100644 --- a/monkey/common/cloud/aws.py +++ b/monkey/common/cloud/aws.py @@ -1,3 +1,4 @@ +import re import urllib2 __author__ = 'itay.mizeretz' @@ -7,11 +8,22 @@ class AWS(object): def __init__(self): try: self.instance_id = urllib2.urlopen('http://169.254.169.254/latest/meta-data/instance-id').read() - self.region = urllib2.urlopen('http://169.254.169.254/latest/meta-data/placement/availability-zone').read()[:-1] + self.region = self._parse_region(urllib2.urlopen('http://169.254.169.254/latest/meta-data/placement/availability-zone').read()) except urllib2.URLError: self.instance_id = None self.region = None + @staticmethod + def _parse_region(region_url_response): + # For a list of regions: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html + # This regex will find any AWS region format string in the response. + re_phrase = r'((?:us|eu|ap|ca|cn|sa)-[a-z]*-[0-9])' + finding = re.findall(re_phrase, region_url_response, re.IGNORECASE) + if finding: + return finding[0] + else: + return None + def get_instance_id(self): return self.instance_id diff --git a/monkey/monkey_island/cc/services/report.py b/monkey/monkey_island/cc/services/report.py index bd03fb78c..8f72e1b17 100644 --- a/monkey/monkey_island/cc/services/report.py +++ b/monkey/monkey_island/cc/services/report.py @@ -8,7 +8,6 @@ from enum import Enum from six import text_type from cc.database import mongo -from cc.environment.environment import load_env_from_file, AWS from cc.resources.aws_exporter import AWSExporter from cc.services.config import ConfigService from cc.services.edge import EdgeService @@ -677,9 +676,7 @@ class ReportService: @staticmethod def is_report_generated(): generated_report = mongo.db.report.find_one({}) - if generated_report is None: - return False - return True + return generated_report is not None @staticmethod def generate_report(): @@ -734,6 +731,10 @@ class ReportService: @staticmethod def is_latest_report_exists(): + """ + This function checks if a monkey report was already generated and if it's the latest one. + :return: True if report is the latest one, False if there isn't a report or its not the latest. + """ latest_report_doc = mongo.db.report.find_one({}, {'meta.latest_monkey_modifytime': 1}) if latest_report_doc: @@ -755,14 +756,6 @@ class ReportService: {'exploits': {'$elemMatch': {'exploiter': exploit_type, 'result': True}}}, limit=1) > 0 - @staticmethod - def get_active_exporters(): - # This function should be in another module in charge of building a list of active exporters - exporters_list = [] - if str(load_env_from_file()) == AWS: - exporters_list.append(AWSExporter) - return exporters_list - @staticmethod def export_to_exporters(report): for exporter in ReportService.get_active_exporters(): diff --git a/monkey/monkey_island/report_exporter_manager.py b/monkey/monkey_island/report_exporter_manager.py new file mode 100644 index 000000000..7e9afc8a9 --- /dev/null +++ b/monkey/monkey_island/report_exporter_manager.py @@ -0,0 +1,40 @@ +from cc.environment.environment import load_env_from_file, AWS +from cc.resources.aws_exporter import AWSExporter +import logging + +logger = logging.getLogger(__name__) + + +class Borg: + _shared_state = {} + + def __init__(self): + self.__dict__ = self._shared_state + + +class ReportExporterManager(Borg): + def __init__(self): + Borg.__init__(self) + self._exporters_list = [] + self._init_exporters() + + def get_exporters_list(self): + return self._exporters_list + + def _init_exporters(self): + self._init_aws_exporter() + + def _init_aws_exporter(self): + if str(load_env_from_file()) == AWS: + self._exporters_list.append(AWSExporter) + + def export(self): + try: + for exporter in self._exporters_list: + exporter().handle_report() + except Exception as e: + logger.exception('Failed to export report') + +if __name__ == '__main__': + print ReportExporterManager().get_exporters_list() + print ReportExporterManager().get_exporters_list() diff --git a/monkey/monkey_island/requirements.txt b/monkey/monkey_island/requirements.txt index f094df947..858642d19 100644 --- a/monkey/monkey_island/requirements.txt +++ b/monkey/monkey_island/requirements.txt @@ -14,4 +14,5 @@ netifaces ipaddress enum34 PyCrypto -boto3 \ No newline at end of file +boto3 +awscli \ No newline at end of file