def bay_create(self, context, bay, bay_create_timeout): LOG.debug('bay_heat bay_create') osc = clients.OpenStackClients(context) bay.uuid = uuid.uuid4() try: # Create trustee/trust and set them to bay trust_manager.create_trustee_and_trust(osc, bay) # Generate certificate and set the cert reference to bay cert_manager.generate_certificates_to_bay(bay, context=context) conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_CREATE, taxonomy.OUTCOME_PENDING) created_stack = _create_stack(context, osc, bay, bay_create_timeout) except Exception as e: cert_manager.delete_certificates_from_bay(bay, context=context) trust_manager.delete_trustee_and_trust(osc, context, bay) conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_CREATE, taxonomy.OUTCOME_FAILURE) if isinstance(e, exc.HTTPBadRequest): e = exception.InvalidParameterValue(message=six.text_type(e)) raise e bay.stack_id = created_stack['stack']['id'] bay.status = bay_status.CREATE_IN_PROGRESS bay.create() self._poll_and_check(osc, bay) return bay
def bay_update(self, context, bay): LOG.debug('bay_heat bay_update') osc = clients.OpenStackClients(context) stack = osc.heat().stacks.get(bay.stack_id) allow_update_status = (bay_status.CREATE_COMPLETE, bay_status.UPDATE_COMPLETE, bay_status.RESUME_COMPLETE, bay_status.RESTORE_COMPLETE, bay_status.ROLLBACK_COMPLETE, bay_status.SNAPSHOT_COMPLETE, bay_status.CHECK_COMPLETE, bay_status.ADOPT_COMPLETE) if stack.stack_status not in allow_update_status: conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE) operation = _('Updating a bay when stack status is ' '"%s"') % stack.stack_status raise exception.NotSupported(operation=operation) delta = bay.obj_what_changed() if not delta: return bay manager = scale_manager.ScaleManager(context, osc, bay) conductor_utils.notify_about_bay_operation(context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_PENDING) _update_stack(context, osc, bay, manager) self._poll_and_check(osc, bay) return bay
def bay_update(self, context, bay): LOG.debug('bay_heat bay_update') osc = clients.OpenStackClients(context) stack = osc.heat().stacks.get(bay.stack_id) allow_update_status = ( bay_status.CREATE_COMPLETE, bay_status.UPDATE_COMPLETE, bay_status.RESUME_COMPLETE, bay_status.RESTORE_COMPLETE, bay_status.ROLLBACK_COMPLETE, bay_status.SNAPSHOT_COMPLETE, bay_status.CHECK_COMPLETE, bay_status.ADOPT_COMPLETE ) if stack.stack_status not in allow_update_status: conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE) operation = _('Updating a bay when stack status is ' '"%s"') % stack.stack_status raise exception.NotSupported(operation=operation) delta = bay.obj_what_changed() if not delta: return bay manager = scale_manager.ScaleManager(context, osc, bay) conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_PENDING) _update_stack(context, osc, bay, manager) self._poll_and_check(osc, bay) return bay
def bay_create(self, context, bay, bay_create_timeout): LOG.debug('bay_heat bay_create') osc = clients.OpenStackClients(context) bay.uuid = uuid.uuid4() try: # Create trustee/trust and set them to bay trust_manager.create_trustee_and_trust(osc, bay) # Generate certificate and set the cert reference to bay cert_manager.generate_certificates_to_bay(bay, context=context) conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_CREATE, taxonomy.OUTCOME_PENDING) created_stack = _create_stack(context, osc, bay, bay_create_timeout) except Exception as e: cert_manager.delete_certificates_from_bay(bay, context=context) trust_manager.delete_trustee_and_trust(osc, context, bay) conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_CREATE, taxonomy.OUTCOME_FAILURE) if isinstance(e, exc.HTTPBadRequest): e = exception.InvalidParameterValue(message=six.text_type(e)) raise e raise bay.stack_id = created_stack['stack']['id'] bay.status = bay_status.CREATE_IN_PROGRESS bay.create() self._poll_and_check(osc, bay) return bay
def bay_delete(self, context, uuid): LOG.debug('bay_heat bay_delete') osc = clients.OpenStackClients(context) bay = objects.Bay.get_by_uuid(context, uuid) stack_id = bay.stack_id # NOTE(sdake): This will execute a stack_delete operation. This will # Ignore HTTPNotFound exceptions (stack wasn't present). In the case # that Heat couldn't find the stack representing the bay, likely a user # has deleted the stack outside the context of Magnum. Therefore the # contents of the bay are forever lost. # # If the exception is unhandled, the original exception will be raised. try: conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_PENDING) osc.heat().stacks.delete(stack_id) except exc.HTTPNotFound: LOG.info(_LI('The stack %s was not found during bay' ' deletion.'), stack_id) try: trust_manager.delete_trustee_and_trust(osc, context, bay) cert_manager.delete_certificates_from_cluster(bay, context=context) bay.destroy() except exception.ClusterNotFound: LOG.info(_LI('The bay %s has been deleted by others.'), uuid) conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_SUCCESS) return None except exc.HTTPConflict: conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_FAILURE) raise exception.OperationInProgress(bay_name=bay.name) except Exception: conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_FAILURE) raise bay.status = bay_status.DELETE_IN_PROGRESS bay.save() self._poll_and_check(osc, bay) return None
def bay_delete(self, context, uuid): LOG.debug('bay_heat bay_delete') osc = clients.OpenStackClients(context) bay = objects.Bay.get_by_uuid(context, uuid) stack_id = bay.stack_id # NOTE(sdake): This will execute a stack_delete operation. This will # Ignore HTTPNotFound exceptions (stack wasn't present). In the case # that Heat couldn't find the stack representing the bay, likely a user # has deleted the stack outside the context of Magnum. Therefore the # contents of the bay are forever lost. # # If the exception is unhandled, the original exception will be raised. try: conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_PENDING) osc.heat().stacks.delete(stack_id) except exc.HTTPNotFound: LOG.info(_LI('The stack %s was not found during bay' ' deletion.'), stack_id) try: trust_manager.delete_trustee_and_trust(osc, context, bay) cert_manager.delete_certificates_from_bay(bay, context=context) bay.destroy() except exception.ClusterNotFound: LOG.info(_LI('The bay %s has been deleted by others.'), uuid) conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_SUCCESS) return None except exc.HTTPConflict: conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_FAILURE) raise exception.OperationInProgress(bay_name=bay.name) except Exception: conductor_utils.notify_about_bay_operation( context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_FAILURE) raise bay.status = bay_status.DELETE_IN_PROGRESS self._poll_and_check(osc, bay) return None
def poll_and_check(self): # TODO(yuanying): temporary implementation to update api_address, # node_addresses and bay status stack = self.openstack_client.heat().stacks.get(self.bay.stack_id) self.attempts += 1 status_to_event = { bay_status.DELETE_COMPLETE: taxonomy.ACTION_DELETE, bay_status.CREATE_COMPLETE: taxonomy.ACTION_CREATE, bay_status.UPDATE_COMPLETE: taxonomy.ACTION_UPDATE, bay_status.CREATE_FAILED: taxonomy.ACTION_CREATE, bay_status.DELETE_FAILED: taxonomy.ACTION_DELETE, bay_status.UPDATE_FAILED: taxonomy.ACTION_UPDATE } # poll_and_check is detached and polling long time to check status, # so another user/client can call delete bay/stack. if stack.stack_status == bay_status.DELETE_COMPLETE: self._delete_complete() conductor_utils.notify_about_bay_operation( self.context, status_to_event[stack.stack_status], taxonomy.OUTCOME_SUCCESS) raise loopingcall.LoopingCallDone() if stack.stack_status in (bay_status.CREATE_COMPLETE, bay_status.UPDATE_COMPLETE): self._sync_bay_and_template_status(stack) conductor_utils.notify_about_bay_operation( self.context, status_to_event[stack.stack_status], taxonomy.OUTCOME_SUCCESS) raise loopingcall.LoopingCallDone() elif stack.stack_status != self.bay.status: self._sync_bay_status(stack) if stack.stack_status in (bay_status.CREATE_FAILED, bay_status.DELETE_FAILED, bay_status.UPDATE_FAILED): self._sync_bay_and_template_status(stack) self._bay_failed(stack) conductor_utils.notify_about_bay_operation( self.context, status_to_event[stack.stack_status], taxonomy.OUTCOME_FAILURE) raise loopingcall.LoopingCallDone() # only check max attempts when the stack is being created when # the timeout hasn't been set. If the timeout has been set then # the loop will end when the stack completes or the timeout occurs if stack.stack_status == bay_status.CREATE_IN_PROGRESS: if (stack.timeout_mins is None and self.attempts > cfg.CONF.bay_heat.max_attempts): LOG.error( _LE('Bay check exit after %(attempts)s attempts,' 'stack_id: %(id)s, stack_status: %(status)s') % { 'attempts': cfg.CONF.bay_heat.max_attempts, 'id': self.bay.stack_id, 'status': stack.stack_status }) raise loopingcall.LoopingCallDone() else: if self.attempts > cfg.CONF.bay_heat.max_attempts: LOG.error( _LE('Bay check exit after %(attempts)s attempts,' 'stack_id: %(id)s, stack_status: %(status)s') % { 'attempts': cfg.CONF.bay_heat.max_attempts, 'id': self.bay.stack_id, 'status': stack.stack_status }) raise loopingcall.LoopingCallDone()
def poll_and_check(self): # TODO(yuanying): temporary implementation to update api_address, # node_addresses and bay status stack = self.openstack_client.heat().stacks.get(self.bay.stack_id) self.attempts += 1 status_to_event = { bay_status.DELETE_COMPLETE: taxonomy.ACTION_DELETE, bay_status.CREATE_COMPLETE: taxonomy.ACTION_CREATE, bay_status.UPDATE_COMPLETE: taxonomy.ACTION_UPDATE, bay_status.CREATE_FAILED: taxonomy.ACTION_CREATE, bay_status.DELETE_FAILED: taxonomy.ACTION_DELETE, bay_status.UPDATE_FAILED: taxonomy.ACTION_UPDATE } # poll_and_check is detached and polling long time to check status, # so another user/client can call delete bay/stack. if stack.stack_status == bay_status.DELETE_COMPLETE: self._delete_complete() conductor_utils.notify_about_bay_operation( self.context, status_to_event[stack.stack_status], taxonomy.OUTCOME_SUCCESS) raise loopingcall.LoopingCallDone() if stack.stack_status in (bay_status.CREATE_COMPLETE, bay_status.UPDATE_COMPLETE): self._sync_bay_and_template_status(stack) conductor_utils.notify_about_bay_operation( self.context, status_to_event[stack.stack_status], taxonomy.OUTCOME_SUCCESS) raise loopingcall.LoopingCallDone() elif stack.stack_status != self.bay.status: self._sync_bay_status(stack) if stack.stack_status in (bay_status.CREATE_FAILED, bay_status.DELETE_FAILED, bay_status.UPDATE_FAILED): self._sync_bay_and_template_status(stack) self._bay_failed(stack) conductor_utils.notify_about_bay_operation( self.context, status_to_event[stack.stack_status], taxonomy.OUTCOME_FAILURE) raise loopingcall.LoopingCallDone() # only check max attempts when the stack is being created when # the timeout hasn't been set. If the timeout has been set then # the loop will end when the stack completes or the timeout occurs if stack.stack_status == bay_status.CREATE_IN_PROGRESS: if (stack.timeout_mins is None and self.attempts > cfg.CONF.bay_heat.max_attempts): LOG.error(_LE('Bay check exit after %(attempts)s attempts,' 'stack_id: %(id)s, stack_status: %(status)s') % {'attempts': cfg.CONF.bay_heat.max_attempts, 'id': self.bay.stack_id, 'status': stack.stack_status}) raise loopingcall.LoopingCallDone() else: if self.attempts > cfg.CONF.bay_heat.max_attempts: LOG.error(_LE('Bay check exit after %(attempts)s attempts,' 'stack_id: %(id)s, stack_status: %(status)s') % {'attempts': cfg.CONF.bay_heat.max_attempts, 'id': self.bay.stack_id, 'status': stack.stack_status}) raise loopingcall.LoopingCallDone()