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
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
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)