def __init__(self):
        log.info("load node config...")

        self.is_interrupted = False

        config_parser = SafeConfigParser()
        config_parser.read(self.CONFIG_FILE)

        self.name = config_parser.get("node", "name")
        self.network_address = config_parser.get("node", "network_address")
        self.metadata = config_parser.get("node", "metadata")
        self.download_dir = config_parser.get("node", "download_dir")
        self.hermes = Connector(config_parser.get("hermes", "hermes_url"))
        self.username = config_parser.get("hermes", "username")
        self.password = config_parser.get("hermes", "password")

        cuckoo_instances = config_parser.get("node", "cuckoo_instances")\
            .split(",")

        self._mt = MonitorThread()
        self._mt.start()
        self._mt.attach(self)

        self.cuckoo_instances = dict()
        for instance in cuckoo_instances:
            hypervisor = config_parser.get(instance, "hypervisor")
            ip = config_parser.get(instance, "rest_api_ip")
            port = config_parser.get(instance, "rest_api_port")
            cuckoo_base_dir = config_parser.get(instance, "cuckoo_base_dir")
            sensor_dir = cuckoo_base_dir + config_parser.get(instance, "sensor_dir")
            self.storage_dir = cuckoo_base_dir + config_parser.get(instance, "storage_dir")
            self.binaries_dir = cuckoo_base_dir + config_parser.get(instance, "binaries_dir")
            db_dir = cuckoo_base_dir + config_parser.get(instance, "db_dir")
            cuckoo_config = CuckooInstance(hypervisor, ip, port, sensor_dir,
                                           self.storage_dir)
            self.cuckoo_instances[hypervisor] = cuckoo_config

            # cleanup old files
            self.cleanup_cuckoo(db_dir, self.storage_dir)

            # launch cuckoo and api processes
            cuckoo_py = cuckoo_base_dir + config_parser.get(instance, "cuckoo_py")
            api_py = cuckoo_base_dir + config_parser.get(instance, "api_py")
            self.init_subprocesses(cuckoo_py, api_py)

        self.jobs = []
        self.failed_job_ids = []

        self.login()

        config_parser.read(self.SYSTEM_FILE)
        if config_parser.has_option("system", "node_id"):
            self.id = config_parser.get("system", "node_id")
        else:
            # this means node is not registered
            log.info("no node id found, registering node on hermes")
            self.register_node()
class Secretary(Observer):
    """A manager class for a cuckoo node, used to poll jobs from the hermes
    system and submit them to the node.
    Uses the cuckoo REST-API for submitting jobs.

    Attributes:
        name -- the name of the node on which secretary is running
        network_address -- the ip address of the node
        metadata -- some descriptive metadata about the node
        download_dir -- the directory that is used to download files
                        from hermes
        cuckoo_instances -- dictionary with configured cuckoo instances. The
                            keys are the used hypervisors.
        jobs -- a list of all active jobs
        hermes -- the interface to the hermes server
        id -- the id of the node on which secretary is running
    """

    ERROR_MSG_NO_HYPERVISOR = "no corresponding hypervisor found"
    CONFIG_FILE = "secretary.conf"
    SYSTEM_FILE = "system.conf"

    def __init__(self):
        log.info("load node config...")

        self.is_interrupted = False

        config_parser = SafeConfigParser()
        config_parser.read(self.CONFIG_FILE)

        self.name = config_parser.get("node", "name")
        self.network_address = config_parser.get("node", "network_address")
        self.metadata = config_parser.get("node", "metadata")
        self.download_dir = config_parser.get("node", "download_dir")
        self.hermes = Connector(config_parser.get("hermes", "hermes_url"))
        self.username = config_parser.get("hermes", "username")
        self.password = config_parser.get("hermes", "password")

        cuckoo_instances = config_parser.get("node", "cuckoo_instances")\
            .split(",")

        self._mt = MonitorThread()
        self._mt.start()
        self._mt.attach(self)

        self.cuckoo_instances = dict()
        for instance in cuckoo_instances:
            hypervisor = config_parser.get(instance, "hypervisor")
            ip = config_parser.get(instance, "rest_api_ip")
            port = config_parser.get(instance, "rest_api_port")
            cuckoo_base_dir = config_parser.get(instance, "cuckoo_base_dir")
            sensor_dir = cuckoo_base_dir + config_parser.get(
                instance, "sensor_dir")
            self.storage_dir = cuckoo_base_dir + config_parser.get(
                instance, "storage_dir")
            self.binaries_dir = cuckoo_base_dir + config_parser.get(
                instance, "binaries_dir")
            db_dir = cuckoo_base_dir + config_parser.get(instance, "db_dir")
            cuckoo_config = CuckooInstance(hypervisor, ip, port, sensor_dir,
                                           self.storage_dir)
            self.cuckoo_instances[hypervisor] = cuckoo_config

            # cleanup old files
            self.cleanup_cuckoo(db_dir, self.storage_dir)

            # launch cuckoo and api processes
            cuckoo_py = cuckoo_base_dir + config_parser.get(
                instance, "cuckoo_py")
            api_py = cuckoo_base_dir + config_parser.get(instance, "api_py")
            self.init_subprocesses(cuckoo_py, api_py)

        self.jobs = []
        self.failed_job_ids = []

        self.login()

        config_parser.read(self.SYSTEM_FILE)
        if config_parser.has_option("system", "node_id"):
            self.id = config_parser.get("system", "node_id")
        else:
            # this means node is not registered
            log.info("no node id found, registering node on hermes")
            self.register_node()

    def update(self):
        log.error("update from observable")

    def init_subprocesses(self, cuckoo_path, api_path):
        self._mt.attach_process(
            CuckooCoreWrapper(target=cuckoo_path,
                              name="CuckooCore",
                              respawn=True))
        time.sleep(5)  # Wait for cuckoo core to become ready
        self._mt.attach_process(
            CuckooApiWrapper(target=api_path, name="CuckooApi", respawn=True))

    def login(self):
        try:
            self.hermes.login(self.username, self.password)
        except ApiError, e:
            raise HermesError(str(e))
        except RequestError, e:
            raise HermesError(str(e))
    def __init__(self):
        log.info("load node config...")

        self.is_interrupted = False

        config_parser = SafeConfigParser()
        config_parser.read(self.CONFIG_FILE)

        self.name = config_parser.get("node", "name")
        self.network_address = config_parser.get("node", "network_address")
        self.metadata = config_parser.get("node", "metadata")
        self.download_dir = config_parser.get("node", "download_dir")
        self.hermes = Connector(config_parser.get("hermes", "hermes_url"))
        self.username = config_parser.get("hermes", "username")
        self.password = config_parser.get("hermes", "password")

        cuckoo_instances = config_parser.get("node", "cuckoo_instances")\
            .split(",")

        self._mt = MonitorThread()
        self._mt.start()
        self._mt.attach(self)

        self.cuckoo_instances = dict()
        for instance in cuckoo_instances:
            hypervisor = config_parser.get(instance, "hypervisor")
            ip = config_parser.get(instance, "rest_api_ip")
            port = config_parser.get(instance, "rest_api_port")
            cuckoo_base_dir = config_parser.get(instance, "cuckoo_base_dir")
            sensor_dir = cuckoo_base_dir + config_parser.get(
                instance, "sensor_dir")
            self.storage_dir = cuckoo_base_dir + config_parser.get(
                instance, "storage_dir")
            self.binaries_dir = cuckoo_base_dir + config_parser.get(
                instance, "binaries_dir")
            db_dir = cuckoo_base_dir + config_parser.get(instance, "db_dir")
            cuckoo_config = CuckooInstance(hypervisor, ip, port, sensor_dir,
                                           self.storage_dir)
            self.cuckoo_instances[hypervisor] = cuckoo_config

            # cleanup old files
            self.cleanup_cuckoo(db_dir, self.storage_dir)

            # launch cuckoo and api processes
            cuckoo_py = cuckoo_base_dir + config_parser.get(
                instance, "cuckoo_py")
            api_py = cuckoo_base_dir + config_parser.get(instance, "api_py")
            self.init_subprocesses(cuckoo_py, api_py)

        self.jobs = []
        self.failed_job_ids = []

        self.login()

        config_parser.read(self.SYSTEM_FILE)
        if config_parser.has_option("system", "node_id"):
            self.id = config_parser.get("system", "node_id")
        else:
            # this means node is not registered
            log.info("no node id found, registering node on hermes")
            self.register_node()
class Secretary(Observer):
    """A manager class for a cuckoo node, used to poll jobs from the hermes
    system and submit them to the node.
    Uses the cuckoo REST-API for submitting jobs.

    Attributes:
        name -- the name of the node on which secretary is running
        network_address -- the ip address of the node
        metadata -- some descriptive metadata about the node
        download_dir -- the directory that is used to download files
                        from hermes
        cuckoo_instances -- dictionary with configured cuckoo instances. The
                            keys are the used hypervisors.
        jobs -- a list of all active jobs
        hermes -- the interface to the hermes server
        id -- the id of the node on which secretary is running
    """

    ERROR_MSG_NO_HYPERVISOR = "no corresponding hypervisor found"
    CONFIG_FILE = "secretary.conf"
    SYSTEM_FILE = "system.conf"

    def __init__(self):
        log.info("load node config...")

        self.is_interrupted = False

        config_parser = SafeConfigParser()
        config_parser.read(self.CONFIG_FILE)

        self.name = config_parser.get("node", "name")
        self.network_address = config_parser.get("node", "network_address")
        self.metadata = config_parser.get("node", "metadata")
        self.download_dir = config_parser.get("node", "download_dir")
        self.hermes = Connector(config_parser.get("hermes", "hermes_url"))
        self.username = config_parser.get("hermes", "username")
        self.password = config_parser.get("hermes", "password")

        cuckoo_instances = config_parser.get("node", "cuckoo_instances")\
            .split(",")

        self._mt = MonitorThread()
        self._mt.start()
        self._mt.attach(self)

        self.cuckoo_instances = dict()
        for instance in cuckoo_instances:
            hypervisor = config_parser.get(instance, "hypervisor")
            ip = config_parser.get(instance, "rest_api_ip")
            port = config_parser.get(instance, "rest_api_port")
            cuckoo_base_dir = config_parser.get(instance, "cuckoo_base_dir")
            sensor_dir = cuckoo_base_dir + config_parser.get(instance, "sensor_dir")
            self.storage_dir = cuckoo_base_dir + config_parser.get(instance, "storage_dir")
            self.binaries_dir = cuckoo_base_dir + config_parser.get(instance, "binaries_dir")
            db_dir = cuckoo_base_dir + config_parser.get(instance, "db_dir")
            cuckoo_config = CuckooInstance(hypervisor, ip, port, sensor_dir,
                                           self.storage_dir)
            self.cuckoo_instances[hypervisor] = cuckoo_config

            # cleanup old files
            self.cleanup_cuckoo(db_dir, self.storage_dir)

            # launch cuckoo and api processes
            cuckoo_py = cuckoo_base_dir + config_parser.get(instance, "cuckoo_py")
            api_py = cuckoo_base_dir + config_parser.get(instance, "api_py")
            self.init_subprocesses(cuckoo_py, api_py)

        self.jobs = []
        self.failed_job_ids = []

        self.login()

        config_parser.read(self.SYSTEM_FILE)
        if config_parser.has_option("system", "node_id"):
            self.id = config_parser.get("system", "node_id")
        else:
            # this means node is not registered
            log.info("no node id found, registering node on hermes")
            self.register_node()

    def update(self):
        log.error("update from observable")

    def init_subprocesses(self, cuckoo_path, api_path):
        self._mt.attach_process(CuckooCoreWrapper(target=cuckoo_path, name="CuckooCore", respawn=True))
        time.sleep(5)  # Wait for cuckoo core to become ready
        self._mt.attach_process(CuckooApiWrapper(target=api_path, name="CuckooApi", respawn=True))

    def login(self):
        try:
            self.hermes.login(self.username, self.password)
        except ApiError, e:
            raise HermesError(str(e))
        except RequestError, e:
            raise HermesError(str(e))