Ejemplo n.º 1
0
    def test_connectivity(self):
        try:
            resp = self.get('version/')
        except requests.Timeout:
            raise errors.TransientDriverError("Timeout connection to MaaS")

        if resp.status_code in [500, 503]:
            raise errors.TransientDriverError("Received 50x error from MaaS")

        if resp.status_code != 200:
            raise errors.PersistentDriverError(
                "Received unexpected error from MaaS")

        return True
Ejemplo n.º 2
0
    def test_authentication(self):
        try:
            resp = self.get('account/', op='list_authorisation_tokens')
        except requests.Timeout as ex:
            raise errors.TransientDriverError("Timeout connection to MaaS")
        except Exception as ex:
            raise errors.PersistentDriverError("Error accessing MaaS: %s" %
                                               str(ex))

        if resp.status_code in [401, 403]:
            raise errors.PersistentDriverError(
                "MaaS API Authentication Failed")

        if resp.status_code in [500, 503]:
            raise errors.TransientDriverError("Received 50x error from MaaS")

        if resp.status_code != 200:
            raise errors.PersistentDriverError(
                "Received unexpected error from MaaS")

        return True
Ejemplo n.º 3
0
    def execute_task(self, task_id):
        task = self.state_manager.get_task(task_id)

        if task is None:
            raise errors.DriverError("Invalid task %s" % (task_id))

        if task.action not in self.supported_actions:
            raise errors.DriverError(
                "Driver %s doesn't support task action %s" %
                (self.driver_desc, task.action))

        if task.action == hd_fields.OrchestratorAction.ValidateNodeServices:
            self.orchestrator.task_field_update(
                task.get_id(), status=hd_fields.TaskStatus.Running)
            maas_client = MaasRequestFactory(self.config['api_url'],
                                             self.config['api_key'])

            try:
                if maas_client.test_connectivity():
                    if maas_client.test_authentication():
                        self.orchestrator.task_field_update(
                            task.get_id(),
                            status=hd_fields.TaskStatus.Complete,
                            result=hd_fields.ActionResult.Success)
                        return
            except errors.TransientDriverError(ex):
                result = {
                    'retry': True,
                    'detail': str(ex),
                }
                self.orchestrator.task_field_update(
                    task.get_id(),
                    status=hd_fields.TaskStatus.Complete,
                    result=hd_fields.ActionResult.Failure,
                    result_details=result)
                return
            except errors.PersistentDriverError(ex):
                result = {
                    'retry': False,
                    'detail': str(ex),
                }
                self.orchestrator.task_field_update(
                    task.get_id(),
                    status=hd_fields.TaskStatus.Complete,
                    result=hd_fields.ActionResult.Failure,
                    result_details=result)
                return
            except Exception(ex):
                result = {
                    'retry': False,
                    'detail': str(ex),
                }
                self.orchestrator.task_field_update(
                    task.get_id(),
                    status=hd_fields.TaskStatus.Complete,
                    result=hd_fields.ActionResult.Failure,
                    result_details=result)
                return

        design_id = getattr(task, 'design_id', None)

        if design_id is None:
            raise errors.DriverError("No design ID specified in task %s" %
                                     (task_id))

        if task.site_name is None:
            raise errors.DriverError("No site specified for task %s." %
                                     (task_id))

        self.orchestrator.task_field_update(
            task.get_id(), status=hd_fields.TaskStatus.Running)

        site_design = self.orchestrator.get_effective_site(design_id)

        if task.action == hd_fields.OrchestratorAction.CreateNetworkTemplate:
            self.orchestrator.task_field_update(
                task.get_id(), status=hd_fields.TaskStatus.Running)

            subtask = self.orchestrator.create_task(
                task_model.DriverTask,
                parent_task_id=task.get_id(),
                design_id=design_id,
                action=task.action,
                site_name=task.site_name,
                task_scope={'site': task.site_name})
            runner = MaasTaskRunner(state_manager=self.state_manager,
                                    orchestrator=self.orchestrator,
                                    task_id=subtask.get_id(),
                                    config=self.config)

            self.logger.info(
                "Starting thread for task %s to create network templates" %
                (subtask.get_id()))

            runner.start()

            # TODO Figure out coherent system for putting all the timeouts in
            # the config
            runner.join(timeout=120)

            if runner.is_alive():
                result = {
                    'retry': False,
                    'detail': 'MaaS Network creation timed-out'
                }
                self.logger.warn("Thread for task %s timed out after 120s" %
                                 (subtask.get_id()))
                self.orchestrator.task_field_update(
                    task.get_id(),
                    status=hd_fields.TaskStatus.Complete,
                    result=hd_fields.ActionResult.Failure,
                    result_detail=result)
            else:
                subtask = self.state_manager.get_task(subtask.get_id())
                self.logger.info("Thread for task %s completed - result %s" %
                                 (subtask.get_id(), subtask.get_result()))
                self.orchestrator.task_field_update(
                    task.get_id(),
                    status=hd_fields.TaskStatus.Complete,
                    result=subtask.get_result())

            return
        elif task.action == hd_fields.OrchestratorAction.IdentifyNode:
            self.orchestrator.task_field_update(
                task.get_id(), status=hd_fields.TaskStatus.Running)

            subtasks = []

            result_detail = {'detail': []}

            for n in task.node_list:
                subtask = self.orchestrator.create_task(
                    task_model.DriverTask,
                    parent_task_id=task.get_id(),
                    design_id=design_id,
                    action=hd_fields.OrchestratorAction.IdentifyNode,
                    site_name=task.site_name,
                    task_scope={
                        'site': task.site_name,
                        'node_names': [n]
                    })
                runner = MaasTaskRunner(state_manager=self.state_manager,
                                        orchestrator=self.orchestrator,
                                        task_id=subtask.get_id(),
                                        config=self.config)

                self.logger.info(
                    "Starting thread for task %s to identify node %s" %
                    (subtask.get_id(), n))

                runner.start()
                subtasks.append(subtask.get_id())

            running_subtasks = len(subtasks)
            attempts = 0
            worked = failed = False

            #TODO Add timeout to config
            while running_subtasks > 0 and attempts < 3:
                for t in subtasks:
                    subtask = self.state_manager.get_task(t)

                    if subtask.status == hd_fields.TaskStatus.Complete:
                        self.logger.info(
                            "Task %s to identify node %s complete - status %s"
                            % (subtask.get_id(), n, subtask.get_result()))

                        result_detail['detail'].extend(
                            subtask.result_detail['detail'])
                        running_subtasks = running_subtasks - 1

                        if subtask.result in [
                                hd_fields.ActionResult.Success,
                                hd_fields.ActionResult.PartialSuccess
                        ]:
                            worked = True
                        elif subtask.result in [
                                hd_fields.ActionResult.Failure,
                                hd_fields.ActionResult.PartialSuccess
                        ]:
                            failed = True

                time.sleep(1 * 60)
                attempts = attempts + 1

            if running_subtasks > 0:
                self.logger.warn(
                    "Time out for task %s before all subtask threads complete"
                    % (task.get_id()))
                result = hd_fields.ActionResult.DependentFailure
                result_detail['detail'].append(
                    'Some subtasks did not complete before the timeout threshold'
                )
            if worked and failed:
                result = hd_fields.ActionResult.PartialSuccess
            elif worked:
                result = hd_fields.ActionResult.Success
            else:
                result = hd_fields.ActionResult.Failure

            self.orchestrator.task_field_update(
                task.get_id(),
                status=hd_fields.TaskStatus.Complete,
                result=result,
                result_detail=result_detail)