Exemplo n.º 1
0
    def _rescue(self, req, id, body):
        """Rescue an instance."""
        context = req.environ["compute.context"]
        authorize(context)

        if body['rescue'] and 'adminPass' in body['rescue']:
            password = body['rescue']['adminPass']
        else:
            password = utils.generate_password()

        instance = common.get_instance(self.compute_api, context, id)
        try:
            rescue_image_ref = None
            if self.ext_mgr.is_loaded("os-extended-rescue-with-image"):
                if body['rescue'] and 'rescue_image_ref' in body['rescue']:
                    rescue_image_ref = self._rescue_image_validation(
                        body['rescue']['rescue_image_ref'])
            self.compute_api.rescue(context,
                                    instance,
                                    rescue_password=password,
                                    rescue_image_ref=rescue_image_ref)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'rescue', id)
        except exception.InvalidVolume as volume_error:
            raise exc.HTTPConflict(explanation=volume_error.format_message())
        except exception.InstanceNotRescuable as non_rescuable:
            raise exc.HTTPBadRequest(
                explanation=non_rescuable.format_message())

        return {'adminPass': password}
Exemplo n.º 2
0
    def create(self, req, server_id, body):
        """Attach an interface to an instance."""
        context = req.environ['compute.context']
        authorize(context)

        network_id = None
        port_id = None
        req_ip = None
        if body:
            attachment = body['interfaceAttachment']
            network_id = attachment.get('net_id', None)
            port_id = attachment.get('port_id', None)
            try:
                req_ip = attachment['fixed_ips'][0]['ip_address']
            except Exception:
                pass

        if network_id and port_id:
            msg = _("Must not input both network_id and port_id")
            raise exc.HTTPBadRequest(explanation=msg)
        if req_ip and not network_id:
            msg = _("Must input network_id when request IP address")
            raise exc.HTTPBadRequest(explanation=msg)

        if req_ip:
            try:
                netaddr.IPAddress(req_ip)
            except netaddr.AddrFormatError as e:
                raise exc.HTTPBadRequest(explanation=six.text_type(e))

        try:
            instance = common.get_instance(self.compute_api,
                                           context, server_id)
            LOG.info(_LI("Attach interface"), instance=instance)
            vif = self.compute_api.attach_interface(context,
                instance, network_id, port_id, req_ip)
        except (exception.PortNotFound,
                exception.NetworkNotFound) as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.FixedIpAlreadyInUse,
                exception.InterfaceAttachFailedNoNetwork,
                exception.NoMoreFixedIps,
                exception.PortInUse,
                exception.NetworkDuplicated,
                exception.NetworkAmbiguous,
                exception.PortNotUsable) as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except NotImplementedError:
            msg = _("Network driver does not support this function.")
            raise webob.exc.HTTPNotImplemented(explanation=msg)
        except exception.InterfaceAttachFailed:
            msg = _("Failed to attach interface")
            raise webob.exc.HTTPInternalServerError(explanation=msg)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'attach_interface', server_id)

        return self.show(req, server_id, vif['id'])
Exemplo n.º 3
0
    def _update_instance_metadata(self,
                                  context,
                                  server_id,
                                  metadata,
                                  delete=False):
        try:
            server = common.get_instance(self.compute_api, context, server_id)
            return self.compute_api.update_instance_metadata(
                context, server, metadata, delete)

        except exception.InstanceNotFound:
            msg = _('Server does not exist')
            raise exc.HTTPNotFound(explanation=msg)

        except (ValueError, AttributeError):
            msg = _("Malformed request body")
            raise exc.HTTPBadRequest(explanation=msg)

        except exception.InvalidMetadata as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

        except exception.InvalidMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message())

        except exception.QuotaError as error:
            raise exc.HTTPForbidden(explanation=error.format_message())

        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())

        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'update metadata', server_id)
Exemplo n.º 4
0
    def _rescue(self, req, id, body):
        """Rescue an instance."""
        context = req.environ["compute.context"]
        authorize(context)

        if body['rescue'] and 'adminPass' in body['rescue']:
            password = body['rescue']['adminPass']
        else:
            password = utils.generate_password()

        instance = common.get_instance(self.compute_api, context, id)
        try:
            rescue_image_ref = None
            if self.ext_mgr.is_loaded("os-extended-rescue-with-image"):
                if body['rescue'] and 'rescue_image_ref' in body['rescue']:
                    rescue_image_ref = self._rescue_image_validation(
                       body['rescue']['rescue_image_ref'])
            self.compute_api.rescue(context, instance,
                rescue_password=password, rescue_image_ref=rescue_image_ref)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                                                                  'rescue', id)
        except exception.InvalidVolume as volume_error:
            raise exc.HTTPConflict(explanation=volume_error.format_message())
        except exception.InstanceNotRescuable as non_rescuable:
            raise exc.HTTPBadRequest(
                explanation=non_rescuable.format_message())

        return {'adminPass': password}
Exemplo n.º 5
0
    def _action_create_image(self, req, id, body):
        """Snapshot a server instance."""
        context = req.environ['compute.context']
        entity = body.get("createImage", {})

        image_name = entity.get("name")

        if not image_name:
            msg = _("createImage entity requires name attribute")
            raise exc.HTTPBadRequest(explanation=msg)

        props = {}
        metadata = entity.get('metadata', {})
        common.check_img_metadata_properties_quota(context, metadata)
        try:
            props.update(metadata)
        except ValueError:
            msg = _("Invalid metadata")
            raise exc.HTTPBadRequest(explanation=msg)

        instance = self._get_server(context, req, id)

        bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
                    context, instance.uuid)

        try:
            if self.compute_api.is_volume_backed_instance(context, instance,
                                                          bdms):
                policy.enforce(context,
                        'cloud:snapshot_volume_backed',
                        {'project_id': context.project_id,
                        'user_id': context.user_id})
                image = self.compute_api.snapshot_volume_backed(
                                                       context,
                                                       instance,
                                                       image_name,
                                                       extra_properties=props)
            else:
                image = self.compute_api.snapshot(context,
                                                  instance,
                                                  image_name,
                                                  extra_properties=props)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                        'createImage', id)
        except exception.Invalid as err:
            raise exc.HTTPBadRequest(explanation=err.format_message())

        # build location of newly-created image entity
        image_id = str(image['id'])
        url_prefix = self._view_builder._update_glance_link_prefix(
                req.application_url)
        image_ref = common.url_join(url_prefix,
                                    context.project_id,
                                    'images',
                                    image_id)

        resp = webob.Response(status_int=202)
        resp.headers['Location'] = image_ref
        return resp
Exemplo n.º 6
0
    def _action_reboot(self, req, id, body):
        if 'reboot' in body and 'type' in body['reboot']:
            if not isinstance(body['reboot']['type'], six.string_types):
                msg = _("Argument 'type' for reboot must be a string")
                LOG.error(msg)
                raise exc.HTTPBadRequest(explanation=msg)
            valid_reboot_types = ['HARD', 'SOFT']
            reboot_type = body['reboot']['type'].upper()
            if not valid_reboot_types.count(reboot_type):
                msg = _("Argument 'type' for reboot is not HARD or SOFT")
                LOG.error(msg)
                raise exc.HTTPBadRequest(explanation=msg)
        else:
            msg = _("Missing argument 'type' for reboot")
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)

        context = req.environ['compute.context']
        instance = self._get_server(context, req, id)

        try:
            self.compute_api.reboot(context, instance, reboot_type)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'reboot', id)
        return webob.Response(status_int=202)
Exemplo n.º 7
0
    def _update_instance_metadata(self, context, server_id, metadata,
                                  delete=False):
        try:
            server = common.get_instance(self.compute_api, context, server_id)
            return self.compute_api.update_instance_metadata(context,
                                                             server,
                                                             metadata,
                                                             delete)

        except exception.InstanceNotFound:
            msg = _('Server does not exist')
            raise exc.HTTPNotFound(explanation=msg)

        except (ValueError, AttributeError):
            msg = _("Malformed request body")
            raise exc.HTTPBadRequest(explanation=msg)

        except exception.InvalidMetadata as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

        except exception.InvalidMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message())

        except exception.QuotaError as error:
            raise exc.HTTPForbidden(explanation=error.format_message())

        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())

        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'update metadata', server_id)
Exemplo n.º 8
0
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["compute.context"]
        authorize(context, 'migrateLive')

        try:
            block_migration = body["os-migrateLive"]["block_migration"]
            disk_over_commit = body["os-migrateLive"]["disk_over_commit"]
            host = body["os-migrateLive"]["host"]
        except (TypeError, KeyError):
            msg = _("host, block_migration and disk_over_commit must "
                    "be specified for live migration.")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            block_migration = strutils.bool_from_string(block_migration,
                                                        strict=True)
            disk_over_commit = strutils.bool_from_string(disk_over_commit,
                                                         strict=True)
        except ValueError as err:
            raise exc.HTTPBadRequest(explanation=six.text_type(err))

        instance = common.get_instance(self.compute_api, context, id)
        try:
            self.compute_api.live_migrate(context, instance, block_migration,
                                          disk_over_commit, host)
        except (exception.NoValidHost, exception.ComputeServiceUnavailable,
                exception.InvalidHypervisorType, exception.InvalidCPUInfo,
                exception.UnableToMigrateToSelf,
                exception.DestinationHypervisorTooOld,
                exception.InvalidLocalStorage, exception.InvalidSharedStorage,
                exception.HypervisorUnavailable,
                exception.MigrationPreCheckError,
                exception.LiveMigrationWithOldNovaNotSafe) as ex:
            raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'os-migrateLive', id)
        except Exception:
            if host is None:
                msg = _("Live migration of instance %s to another host "
                        "failed") % id
            else:
                msg = _("Live migration of instance %(id)s to host %(host)s "
                        "failed") % {
                            'id': id,
                            'host': host
                        }
            LOG.exception(msg)
            # Return messages from scheduler
            raise exc.HTTPInternalServerError(explanation=msg)

        return webob.Response(status_int=202)
Exemplo n.º 9
0
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["compute.context"]
        authorize(context, 'migrateLive')

        try:
            block_migration = body["os-migrateLive"]["block_migration"]
            disk_over_commit = body["os-migrateLive"]["disk_over_commit"]
            host = body["os-migrateLive"]["host"]
        except (TypeError, KeyError):
            msg = _("host, block_migration and disk_over_commit must "
                    "be specified for live migration.")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            block_migration = strutils.bool_from_string(block_migration,
                                                        strict=True)
            disk_over_commit = strutils.bool_from_string(disk_over_commit,
                                                         strict=True)
        except ValueError as err:
            raise exc.HTTPBadRequest(explanation=six.text_type(err))

        instance = common.get_instance(self.compute_api, context, id)
        try:
            self.compute_api.live_migrate(context, instance, block_migration,
                                          disk_over_commit, host)
        except (exception.NoValidHost,
                exception.ComputeServiceUnavailable,
                exception.InvalidHypervisorType,
                exception.InvalidCPUInfo,
                exception.UnableToMigrateToSelf,
                exception.DestinationHypervisorTooOld,
                exception.InvalidLocalStorage,
                exception.InvalidSharedStorage,
                exception.HypervisorUnavailable,
                exception.MigrationPreCheckError,
                exception.LiveMigrationWithOldNovaNotSafe) as ex:
            raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'os-migrateLive', id)
        except Exception:
            if host is None:
                msg = _("Live migration of instance %s to another host "
                        "failed") % id
            else:
                msg = _("Live migration of instance %(id)s to host %(host)s "
                        "failed") % {'id': id, 'host': host}
            LOG.exception(msg)
            # Return messages from scheduler
            raise exc.HTTPInternalServerError(explanation=msg)

        return webob.Response(status_int=202)
Exemplo n.º 10
0
    def delete(self, req, server_id, id):
        """Detach a volume from an instance."""
        context = req.environ['compute.context']
        authorize(context)
        authorize_attach(context, action='delete')

        volume_id = id

        instance = common.get_instance(self.compute_api, context, server_id)
        if instance.vm_state in (vm_states.SHELVED,
                                 vm_states.SHELVED_OFFLOADED):
            _check_request_version(req, '2.20', 'detach_volume',
                                   server_id, instance.vm_state)
        try:
            volume = self.volume_api.get(context, volume_id)
        except exception.VolumeNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())

        bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
                context, instance.uuid)
        if not bdms:
            msg = _("Instance %s is not attached.") % server_id
            raise exc.HTTPNotFound(explanation=msg)

        found = False
        try:
            for bdm in bdms:
                if bdm.volume_id != volume_id:
                    continue
                if bdm.is_root:
                    msg = _("Can't detach root device volume")
                    raise exc.HTTPForbidden(explanation=msg)
                try:
                    self.compute_api.detach_volume(context, instance, volume)
                    found = True
                    break
                except exception.VolumeUnattached:
                    # The volume is not attached.  Treat it as NotFound
                    # by falling through.
                    pass
                except exception.InvalidVolume as e:
                    raise exc.HTTPBadRequest(explanation=e.format_message())
                except exception.InstanceUnknownCell as e:
                    raise exc.HTTPNotFound(explanation=e.format_message())
                except exception.InvalidInput as e:
                    raise exc.HTTPBadRequest(explanation=e.format_message())

        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'detach_volume', server_id)

        if not found:
            msg = _("volume_id not found: %s") % volume_id
            raise exc.HTTPNotFound(explanation=msg)
Exemplo n.º 11
0
def _check_request_version(req, min_version, method, server_id, server_state):
    if not api_version_request.is_supported(req, min_version=min_version):
        exc_inv = exception.InstanceInvalidState(
                attr='vm_state',
                instance_uuid=server_id,
                state=server_state,
                method=method)
        common.raise_http_conflict_for_instance_invalid_state(
                exc_inv,
                method,
                server_id)
Exemplo n.º 12
0
    def create(self, req, server_id, body):
        """Attach a volume to an instance."""
        context = req.environ['compute.context']
        authorize(context)
        authorize_attach(context, action='create')

        if not self.is_valid_body(body, 'volumeAttachment'):
            msg = _("volumeAttachment not specified")
            raise exc.HTTPBadRequest(explanation=msg)
        try:
            volume_id = body['volumeAttachment']['volumeId']
        except KeyError:
            msg = _("volumeId must be specified.")
            raise exc.HTTPBadRequest(explanation=msg)
        device = body['volumeAttachment'].get('device')

        self._validate_volume_id(volume_id)

        LOG.info(_LI("Attach volume %(volume_id)s to instance %(server_id)s "
                    "at %(device)s"),
                  {'volume_id': volume_id,
                   'device': device,
                   'server_id': server_id},
                  context=context)

        instance = common.get_instance(self.compute_api, context, server_id)
        try:
            device = self.compute_api.attach_volume(context, instance,
                                                    volume_id, device)
        except exception.NotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'attach_volume', server_id)

        # The attach is async
        attachment = {}
        attachment['id'] = volume_id
        attachment['serverId'] = server_id
        attachment['volumeId'] = volume_id
        attachment['device'] = device

        # NOTE(justinsb): And now, we have a problem...
        # The attach is async, so there's a window in which we don't see
        # the attachment (until the attachment completes).  We could also
        # get problems with concurrent requests.  I think we need an
        # attachment state, and to write to the DB here, but that's a bigger
        # change.
        # For now, we'll probably have to rely on libraries being smart

        # TODO(justinsb): How do I return "accepted" here?
        return {'volumeAttachment': attachment}
Exemplo n.º 13
0
 def delete(self, req, id):
     """Destroys a server."""
     try:
         self._delete(req.environ['compute.context'], req, id)
     except exception.NotFound:
         msg = _("Instance could not be found")
         raise exc.HTTPNotFound(explanation=msg)
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(state_error,
                 'delete', id)
Exemplo n.º 14
0
    def update(self, req, server_id, id, body):
        if (not self.ext_mgr or
                not self.ext_mgr.is_loaded('os-volume-attachment-update')):
            raise exc.HTTPBadRequest()
        context = req.environ['compute.context']
        authorize(context)
        authorize_attach(context, action='update')

        if not self.is_valid_body(body, 'volumeAttachment'):
            msg = _("volumeAttachment not specified")
            raise exc.HTTPBadRequest(explanation=msg)

        old_volume_id = id
        old_volume = self.volume_api.get(context, old_volume_id)

        try:
            new_volume_id = body['volumeAttachment']['volumeId']
        except KeyError:
            msg = _("volumeId must be specified.")
            raise exc.HTTPBadRequest(explanation=msg)
        self._validate_volume_id(new_volume_id)
        new_volume = self.volume_api.get(context, new_volume_id)

        instance = common.get_instance(self.compute_api, context, server_id)

        bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
                context, instance.uuid)
        found = False
        try:
            for bdm in bdms:
                if bdm.volume_id != old_volume_id:
                    continue
                try:
                    self.compute_api.swap_volume(context, instance, old_volume,
                                                 new_volume)
                    found = True
                    break
                except exception.VolumeUnattached:
                    # The volume is not attached.  Treat it as NotFound
                    # by falling through.
                    pass
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'swap_volume', server_id)

        if not found:
            msg = _("volume_id not found: %s") % old_volume_id
            raise exc.HTTPNotFound(explanation=msg)
        else:
            return webob.Response(status_int=202)
Exemplo n.º 15
0
 def _action_confirm_resize(self, req, id, body):
     context = req.environ['compute.context']
     instance = self._get_server(context, req, id)
     try:
         self.compute_api.confirm_resize(context, instance)
     except exception.MigrationNotFound:
         msg = _("Instance has not been resized.")
         raise exc.HTTPBadRequest(explanation=msg)
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(state_error,
                 'confirmResize', id)
Exemplo n.º 16
0
 def _unshelve(self, req, id, body):
     """Restore an instance from shelved mode."""
     context = req.environ["compute.context"]
     auth_unshelve(context)
     instance = common.get_instance(self.compute_api, context, id)
     try:
         self.compute_api.unshelve(context, instance)
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(
             state_error, 'unshelve', id)
     return webob.Response(status_int=202)
Exemplo n.º 17
0
 def test_raise_http_conflict_for_instance_invalid_state(self):
     exc = exception.InstanceInvalidState(attr='fake_attr',
             state='fake_state', method='fake_method',
             instance_uuid='fake')
     try:
         common.raise_http_conflict_for_instance_invalid_state(exc,
                 'meow', 'fake_server_id')
     except webob.exc.HTTPConflict as e:
         self.assertEqual(six.text_type(e),
             "Cannot 'meow' instance fake_server_id while it is in "
             "fake_attr fake_state")
     else:
         self.fail("webob.exc.HTTPConflict was not raised")
Exemplo n.º 18
0
    def _stop_server(self, req, id, body):
        """Stop an instance."""
        context = req.environ['compute.context']
        instance = self._get_instance(context, id)
        extensions.check_compute_policy(context, 'stop', instance)

        try:
            self.compute_api.stop(context, instance)
        except (exception.InstanceNotReady, exception.InstanceIsLocked) as e:
            raise webob.exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                'stop', id)
        return webob.Response(status_int=202)
Exemplo n.º 19
0
    def index(self, req, server_id):
        context = req.environ["compute.context"]
        authorize(context)

        instance = common.get_instance(self.compute_api, context, server_id)

        try:
            return self.compute_api.get_diagnostics(context, instance)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'get_diagnostics', server_id)
        except NotImplementedError:
            msg = _("Unable to get diagnostics, functionality not implemented")
            raise webob.exc.HTTPNotImplemented(explanation=msg)
Exemplo n.º 20
0
 def _unshelve(self, req, id, body):
     """Restore an instance from shelved mode."""
     context = req.environ["compute.context"]
     auth_unshelve(context)
     instance = common.get_instance(self.compute_api, context, id)
     try:
         self.compute_api.unshelve(context, instance)
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(state_error,
                                                               'unshelve',
                                                               id)
     return webob.Response(status_int=202)
Exemplo n.º 21
0
 def _unrescue(self, req, id, body):
     """Unrescue an instance."""
     context = req.environ["compute.context"]
     authorize(context)
     instance = common.get_instance(self.compute_api, context, id)
     try:
         self.compute_api.unrescue(context, instance)
     except exception.InstanceUnknownCell as e:
         raise exc.HTTPNotFound(explanation=e.format_message())
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(
             state_error, 'unrescue', id)
Exemplo n.º 22
0
    def _stop_server(self, req, id, body):
        """Stop an instance."""
        context = req.environ['compute.context']
        instance = self._get_instance(context, id)
        extensions.check_compute_policy(context, 'stop', instance)

        try:
            self.compute_api.stop(context, instance)
        except (exception.InstanceNotReady, exception.InstanceIsLocked) as e:
            raise webob.exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'stop', id)
        return webob.Response(status_int=202)
Exemplo n.º 23
0
 def _resume(self, req, id, body):
     """Permit admins to resume the server from suspend."""
     context = req.environ['compute.context']
     authorize(context, action='resume')
     try:
         server = common.get_instance(self.compute_api, context, id)
         self.compute_api.resume(context, server)
     except exception.InstanceUnknownCell as e:
         raise exc.HTTPNotFound(explanation=e.format_message())
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(
             state_error, 'resume', id)
Exemplo n.º 24
0
 def _restore(self, req, id, body):
     """Restore a previously deleted instance."""
     context = req.environ["compute.context"]
     authorize(context)
     instance = common.get_instance(self.compute_api, context, id)
     try:
         self.compute_api.restore(context, instance)
     except exception.InstanceUnknownCell as error:
         raise webob.exc.HTTPNotFound(explanation=error.format_message())
     except exception.QuotaError as error:
         raise webob.exc.HTTPForbidden(explanation=error.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(state_error,
                 'restore', id)
Exemplo n.º 25
0
 def _resume(self, req, id, body):
     """Permit admins to resume the server from suspend."""
     context = req.environ['compute.context']
     authorize(context, action='resume')
     try:
         server = common.get_instance(self.compute_api, context, id)
         self.compute_api.resume(context, server)
     except exception.InstanceUnknownCell as e:
         raise exc.HTTPNotFound(explanation=e.format_message())
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(state_error,
                 'resume', id)
Exemplo n.º 26
0
    def create(self, req, server_id, body):
        """Attach a volume to an instance."""
        context = req.environ['compute.context']
        authorize(context)
        authorize_attach(context, action='create')

        volume_id = body['volumeAttachment']['volumeId']
        device = body['volumeAttachment'].get('device')

        instance = common.get_instance(self.compute_api, context, server_id)

        if instance.vm_state in (vm_states.SHELVED,
                                 vm_states.SHELVED_OFFLOADED):
            _check_request_version(req, '2.20', 'attach_volume',
                                   server_id, instance.vm_state)

        try:
            device = self.compute_api.attach_volume(context, instance,
                                                    volume_id, device)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.VolumeNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'attach_volume', server_id)
        except (exception.InvalidVolume,
                exception.InvalidDevicePath) as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        # The attach is async
        attachment = {}
        attachment['id'] = volume_id
        attachment['serverId'] = server_id
        attachment['volumeId'] = volume_id
        attachment['device'] = device

        # NOTE(justinsb): And now, we have a problem...
        # The attach is async, so there's a window in which we don't see
        # the attachment (until the attachment completes).  We could also
        # get problems with concurrent requests.  I think we need an
        # attachment state, and to write to the DB here, but that's a bigger
        # change.
        # For now, we'll probably have to rely on libraries being smart

        # TODO(justinsb): How do I return "accepted" here?
        return {'volumeAttachment': attachment}
Exemplo n.º 27
0
 def _unrescue(self, req, id, body):
     """Unrescue an instance."""
     context = req.environ["compute.context"]
     authorize(context)
     instance = common.get_instance(self.compute_api, context, id)
     try:
         self.compute_api.unrescue(context, instance)
     except exception.InstanceUnknownCell as e:
         raise exc.HTTPNotFound(explanation=e.format_message())
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(state_error,
                                                               'unrescue',
                                                               id)
Exemplo n.º 28
0
    def delete(self, req, server_id, id):
        """Abort an in progress migration of an instance."""
        context = req.environ['compute.context']
        authorize(context, action="delete")

        instance = common.get_instance(self.compute_api, context, server_id)
        try:
            self.compute_api.live_migrate_abort(context, instance, id)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, "abort live migration", server_id)
        except exception.MigrationNotFoundForInstance as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InvalidMigrationState as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
Exemplo n.º 29
0
    def _shelve_offload(self, req, id, body):
        """Force removal of a shelved instance from the cloud node."""
        context = req.environ["compute.context"]
        auth_shelve_offload(context)

        instance = common.get_instance(self.compute_api, context, id)
        try:
            self.compute_api.shelve_offload(context, instance)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'shelveOffload', id)

        return webob.Response(status_int=202)
Exemplo n.º 30
0
    def delete(self, req, server_id, id):
        """Abort an in progress migration of an instance."""
        context = req.environ['compute.context']
        authorize(context, action="delete")

        instance = common.get_instance(self.compute_api, context, server_id)
        try:
            self.compute_api.live_migrate_abort(context, instance, id)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                    state_error, "abort live migration", server_id)
        except exception.MigrationNotFoundForInstance as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InvalidMigrationState as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
Exemplo n.º 31
0
    def _shelve_offload(self, req, id, body):
        """Force removal of a shelved instance from the cloud node."""
        context = req.environ["compute.context"]
        authorize(context, action='shelve_offload')

        instance = common.get_instance(self.compute_api, context, id)
        try:
            self.compute_api.shelve_offload(context, instance)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'shelveOffload', id)
Exemplo n.º 32
0
    def _shelve_offload(self, req, id, body):
        """Force removal of a shelved instance from the cloud node."""
        context = req.environ["compute.context"]
        auth_shelve_offload(context)

        instance = common.get_instance(self.compute_api, context, id)
        try:
            self.compute_api.shelve_offload(context, instance)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                                                              'shelveOffload',
                                                              id)

        return webob.Response(status_int=202)
Exemplo n.º 33
0
    def _create_backup(self, req, id, body):
        """Backup a server instance.

        Images now have an `image_type` associated with them, which can be
        'snapshot' or the backup type, like 'daily' or 'weekly'.

        If the image_type is backup-like, then the rotation factor can be
        included and that will cause the oldest backups that exceed the
        rotation factor to be deleted.

        """
        context = req.environ["compute.context"]
        authorize(context)
        entity = body["createBackup"]

        image_name = common.normalize_name(entity["name"])
        backup_type = entity["backup_type"]
        rotation = int(entity["rotation"])

        props = {}
        metadata = entity.get('metadata', {})
        common.check_img_metadata_properties_quota(context, metadata)
        props.update(metadata)

        instance = common.get_instance(self.compute_api, context, id)

        try:
            image = self.compute_api.backup(context, instance, image_name,
                    backup_type, rotation, extra_properties=props)
        except exception.InstanceUnknownCell as e:
            raise webob.exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'createBackup', id)
        except exception.InvalidRequest as e:
            raise webob.exc.HTTPBadRequest(explanation=e.format_message())

        resp = webob.Response(status_int=202)

        # build location of newly-created image entity if rotation is not zero
        if rotation > 0:
            image_id = str(image['id'])
            image_ref = common.url_join(req.application_url, 'images',
                                        image_id)
            resp.headers['Location'] = image_ref

        return resp
Exemplo n.º 34
0
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["compute.context"]
        authorize(context, action='migrate_live')

        host = body["os-migrateLive"]["host"]
        block_migration = body["os-migrateLive"]["block_migration"]

        if api_version_request.is_supported(req, min_version='2.25'):
            if block_migration == 'auto':
                block_migration = None
            else:
                block_migration = strutils.bool_from_string(block_migration,
                                                            strict=True)
            disk_over_commit = None
        else:
            disk_over_commit = body["os-migrateLive"]["disk_over_commit"]

            block_migration = strutils.bool_from_string(block_migration,
                                                        strict=True)
            disk_over_commit = strutils.bool_from_string(disk_over_commit,
                                                         strict=True)

        try:
            instance = common.get_instance(self.compute_api, context, id)
            self.compute_api.live_migrate(context, instance, block_migration,
                                          disk_over_commit, host)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.NoValidHost,
                exception.ComputeServiceUnavailable,
                exception.InvalidHypervisorType,
                exception.InvalidCPUInfo,
                exception.UnableToMigrateToSelf,
                exception.DestinationHypervisorTooOld,
                exception.InvalidLocalStorage,
                exception.InvalidSharedStorage,
                exception.HypervisorUnavailable,
                exception.MigrationPreCheckError,
                exception.LiveMigrationWithOldNovaNotSafe,
                exception.LiveMigrationWithOldNovaNotSupported) as ex:
            raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'os-migrateLive', id)
Exemplo n.º 35
0
 def _action_revert_resize(self, req, id, body):
     context = req.environ['compute.context']
     instance = self._get_server(context, req, id)
     try:
         self.compute_api.revert_resize(context, instance)
     except exception.MigrationNotFound:
         msg = _("Instance has not been resized.")
         raise exc.HTTPBadRequest(explanation=msg)
     except exception.FlavorNotFound:
         msg = _("Flavor used by the instance could not be found.")
         raise exc.HTTPBadRequest(explanation=msg)
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(state_error,
                 'revertResize', id)
     return webob.Response(status_int=202)
Exemplo n.º 36
0
 def _unpause(self, req, id, body):
     """Permit Admins to unpause the server."""
     ctxt = req.environ['compute.context']
     authorize(ctxt, action='unpause')
     server = common.get_instance(self.compute_api, ctxt, id)
     try:
         self.compute_api.unpause(ctxt, server)
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(state_error,
                 'unpause', id)
     except (exception.InstanceUnknownCell,
                  exception.InstanceNotFound) as e:
         raise exc.HTTPNotFound(explanation=e.format_message())
     except NotImplementedError:
         common.raise_feature_not_supported()
Exemplo n.º 37
0
    def _evacuate(self, req, id, body):
        """Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["compute.context"]
        authorize(context)

        evacuate_body = body["evacuate"]
        host = evacuate_body.get("host")

        on_shared_storage = self._get_on_shared_storage(req, evacuate_body)

        if api_version_request.is_supported(req, min_version='2.14'):
            password = self._get_password_v214(req, evacuate_body)
        else:
            password = self._get_password(req, evacuate_body,
                                          on_shared_storage)

        if host is not None:
            try:
                self.host_api.service_get_by_compute_host(context, host)
            except exception.ComputeHostNotFound:
                msg = _("Compute host %s not found.") % host
                raise exc.HTTPNotFound(explanation=msg)

        instance = common.get_instance(self.compute_api, context, id)
        if instance.host == host:
            msg = _("The target host can't be the same one.")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.evacuate(context, instance, host,
                                      on_shared_storage, password)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'evacuate', id)
        except exception.ComputeServiceInUse as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if (not api_version_request.is_supported(req, min_version='2.14')
                and CONF.enable_instance_password):
            return {'adminPass': password}
        else:
            return None
Exemplo n.º 38
0
    def _evacuate(self, req, id, body):
        """Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["compute.context"]
        authorize(context)

        evacuate_body = body["evacuate"]
        host = evacuate_body.get("host")

        on_shared_storage = self._get_on_shared_storage(req, evacuate_body)

        if api_version_request.is_supported(req, min_version='2.14'):
            password = self._get_password_v214(req, evacuate_body)
        else:
            password = self._get_password(req, evacuate_body,
                                          on_shared_storage)

        if host is not None:
            try:
                self.host_api.service_get_by_compute_host(context, host)
            except exception.ComputeHostNotFound:
                msg = _("Compute host %s not found.") % host
                raise exc.HTTPNotFound(explanation=msg)

        instance = common.get_instance(self.compute_api, context, id)
        if instance.host == host:
            msg = _("The target host can't be the same one.")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.evacuate(context, instance, host,
                                      on_shared_storage, password)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'evacuate', id)
        except exception.ComputeServiceInUse as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if (not api_version_request.is_supported(req, min_version='2.14') and
                CONF.enable_instance_password):
            return {'adminPass': password}
        else:
            return None
Exemplo n.º 39
0
 def _unpause(self, req, id, body):
     """Permit Admins to unpause the server."""
     ctxt = req.environ['compute.context']
     authorize(ctxt, action='unpause')
     server = common.get_instance(self.compute_api, ctxt, id)
     try:
         self.compute_api.unpause(ctxt, server)
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(
             state_error, 'unpause', id)
     except (exception.InstanceUnknownCell,
             exception.InstanceNotFound) as e:
         raise exc.HTTPNotFound(explanation=e.format_message())
     except NotImplementedError:
         common.raise_feature_not_supported()
Exemplo n.º 40
0
    def delete(self, req, server_id, id):
        """Detach a volume from an instance."""
        context = req.environ['compute.context']
        authorize(context)
        authorize_attach(context, action='delete')

        volume_id = id
        LOG.info(_LI("Detach volume %s"), volume_id, context=context)

        instance = common.get_instance(self.compute_api, context, server_id)

        volume = self.volume_api.get(context, volume_id)

        bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
                context, instance.uuid)
        if not bdms:
            msg = _("Instance %s is not attached.") % server_id
            raise exc.HTTPNotFound(explanation=msg)

        found = False
        try:
            for bdm in bdms:
                if bdm.volume_id != volume_id:
                    continue
                if bdm.is_root:
                    msg = _("Can't detach root device volume")
                    raise exc.HTTPForbidden(explanation=msg)
                try:
                    self.compute_api.detach_volume(context, instance, volume)
                    found = True
                    break
                except exception.VolumeUnattached:
                    # The volume is not attached.  Treat it as NotFound
                    # by falling through.
                    pass
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'detach_volume', server_id)

        if not found:
            msg = _("volume_id not found: %s") % volume_id
            raise exc.HTTPNotFound(explanation=msg)
        else:
            return webob.Response(status_int=202)
Exemplo n.º 41
0
    def index(self, req, server_id):
        context = req.environ["compute.context"]
        authorize(context)

        instance = common.get_instance(self.compute_api, context, server_id)

        try:
            # NOTE(gmann): To make V21 same as V2 API, this method will call
            # 'get_diagnostics' instead of 'get_instance_diagnostics'.
            # In future, 'get_instance_diagnostics' needs to be called to
            # provide VM diagnostics in a defined format for all driver.
            # BP - https://blueprints.launchpad.net/cloud/+spec/v3-diagnostics.
            return self.compute_api.get_diagnostics(context, instance)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'get_diagnostics', server_id)
        except NotImplementedError:
            common.raise_feature_not_supported()
Exemplo n.º 42
0
    def _force_complete(self, req, id, server_id, body):
        context = req.environ['compute.context']
        authorize(context, action='force_complete')

        instance = common.get_instance(self.compute_api, context, server_id)
        try:
            self.compute_api.live_migrate_force_complete(context, instance, id)
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.MigrationNotFoundByStatus,
                exception.InvalidMigrationState,
                exception.MigrationNotFoundForInstance) as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'force_complete', server_id)
Exemplo n.º 43
0
    def index(self, req, server_id):
        context = req.environ["compute.context"]
        authorize(context)

        instance = common.get_instance(self.compute_api, context, server_id)

        try:
            # NOTE(gmann): To make V21 same as V2 API, this method will call
            # 'get_diagnostics' instead of 'get_instance_diagnostics'.
            # In future, 'get_instance_diagnostics' needs to be called to
            # provide VM diagnostics in a defined format for all driver.
            # BP - https://blueprints.launchpad.net/cloud/+spec/v3-diagnostics.
            return self.compute_api.get_diagnostics(context, instance)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'get_diagnostics', server_id)
        except NotImplementedError:
            common.raise_feature_not_supported()
Exemplo n.º 44
0
    def _force_complete(self, req, id, server_id, body):
        context = req.environ['compute.context']
        authorize(context, action='force_complete')

        instance = common.get_instance(self.compute_api, context, server_id)
        try:
            self.compute_api.live_migrate_force_complete(context, instance, id)
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.MigrationNotFoundByStatus,
                exception.InvalidMigrationState,
                exception.MigrationNotFoundForInstance) as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'force_complete', server_id)
Exemplo n.º 45
0
    def update(self, req, server_id, id, body):
        context = req.environ['compute.context']
        authorize(context)
        authorize_attach(context, action='update')

        old_volume_id = id
        try:
            old_volume = self.volume_api.get(context, old_volume_id)

            new_volume_id = body['volumeAttachment']['volumeId']
            new_volume = self.volume_api.get(context, new_volume_id)
        except exception.VolumeNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())

        instance = common.get_instance(self.compute_api, context, server_id)

        bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
                context, instance.uuid)
        found = False
        try:
            for bdm in bdms:
                if bdm.volume_id != old_volume_id:
                    continue
                try:
                    self.compute_api.swap_volume(context, instance, old_volume,
                                                 new_volume)
                    found = True
                    break
                except exception.VolumeUnattached:
                    # The volume is not attached.  Treat it as NotFound
                    # by falling through.
                    pass
                except exception.InvalidVolume as e:
                    raise exc.HTTPBadRequest(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'swap_volume', server_id)

        if not found:
            msg = _("The volume was either invalid or not attached to the "
                    "instance.")
            raise exc.HTTPNotFound(explanation=msg)
Exemplo n.º 46
0
 def _suspend(self, req, id, body):
     """Permit admins to suspend the server."""
     context = req.environ['compute.context']
     authorize(context, 'suspend')
     server = common.get_instance(self.compute_api, context, id)
     try:
         self.compute_api.suspend(context, server)
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(
             state_error, 'suspend', id)
     except exception.InstanceNotFound:
         msg = _("Server not found")
         raise exc.HTTPNotFound(explanation=msg)
     except Exception:
         readable = traceback.format_exc()
         LOG.exception(_LE("cloud.api::suspend %s"), readable)
         raise exc.HTTPUnprocessableEntity()
     return webob.Response(status_int=202)
Exemplo n.º 47
0
    def _update_instance_metadata(self,
                                  context,
                                  server_id,
                                  metadata,
                                  delete=False):
        try:
            server = common.get_instance(self.compute_api, context, server_id)
            return self.compute_api.update_instance_metadata(
                context, server, metadata, delete)

        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())

        except exception.QuotaError as error:
            raise exc.HTTPForbidden(explanation=error.format_message())

        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())

        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'update metadata', server_id)
Exemplo n.º 48
0
 def _migrate(self, req, id, body):
     """Permit admins to migrate a server to a new host."""
     context = req.environ['compute.context']
     authorize(context, 'migrate')
     instance = common.get_instance(self.compute_api, context, id)
     try:
         self.compute_api.resize(req.environ['compute.context'], instance)
     except exception.QuotaError as error:
         raise exc.HTTPForbidden(explanation=error.format_message())
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(
             state_error, 'migrate', id)
     except exception.InstanceNotFound as e:
         raise exc.HTTPNotFound(explanation=e.format_message())
     except exception.NoValidHost as e:
         raise exc.HTTPBadRequest(explanation=e.format_message())
     except Exception:
         LOG.exception(_LE("Error in migrate"))
         raise exc.HTTPBadRequest()
     return webob.Response(status_int=202)
Exemplo n.º 49
0
    def delete(self, req, server_id, id):
        """Deletes an existing metadata."""
        context = req.environ['compute.context']
        authorize(context, action='delete')
        metadata = self._get_metadata(context, server_id)

        if id not in metadata:
            msg = _("Metadata item was not found")
            raise exc.HTTPNotFound(explanation=msg)

        server = common.get_instance(self.compute_api, context, server_id)
        try:
            self.compute_api.delete_instance_metadata(context, server, id)

        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())

        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())

        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'delete metadata', server_id)
Exemplo n.º 50
0
    def delete(self, req, server_id, id):
        """Detach an interface from an instance."""
        context = req.environ['compute.context']
        authorize(context)
        port_id = id
        instance = common.get_instance(self.compute_api,
                                       context, server_id)
        LOG.info(_LI("Detach interface %s"), port_id, instance=instance)
        try:
            self.compute_api.detach_interface(context,
                instance, port_id=port_id)
        except exception.PortNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except NotImplementedError:
            msg = _("Network driver does not support this function.")
            raise webob.exc.HTTPNotImplemented(explanation=msg)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'detach_interface', server_id)

        return webob.Response(status_int=202)
Exemplo n.º 51
0
    def change_password(self, req, id, body):
        context = req.environ['compute.context']
        authorize(context)

        password = body['changePassword']['adminPass']
        instance = common.get_instance(self.compute_api, context, id)
        try:
            self.compute_api.set_admin_password(context, instance, password)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstancePasswordSetFailed as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as e:
            raise common.raise_http_conflict_for_instance_invalid_state(
                e, 'changePassword', id)
        except NotImplementedError:
            msg = _("Unable to set password on instance")
            common.raise_feature_not_supported(msg=msg)