Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
    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
Пример #4
0
    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
Пример #5
0
    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
Пример #6
0
    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
Пример #7
0
    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()
Пример #8
0
    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()