Example #1
0
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["nova.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,
                                       want_objects=True)
        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.InstanceNotRunning,
                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')
        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.HTTPBadRequest(explanation=msg)

        return webob.Response(status_int=202)
Example #2
0
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["nova.context"]
        authorize(context, 'migrate_live')

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

        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,
                                           want_objects=True)
            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.InstanceNotRunning,
                exception.MigrationPreCheckError) 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')
        return webob.Response(status_int=202)
Example #3
0
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["nova.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,
                                       want_objects=True)
        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.InstanceNotRunning,
                exception.ComputeHostNotFound,
                exception.MigrationPreCheckError) 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')
        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.HTTPBadRequest(explanation=msg)

        return webob.Response(status_int=202)
Example #4
0
    def _validate(self, bdm_dict):
        """Basic data format validations."""
        dict_fields = set(key for key, _ in bdm_dict.iteritems())

        # Check that there are no bogus fields
        if not (dict_fields <=
                (self._fields | self._db_only_fields)):
            raise exception.InvalidBDMFormat(
                details=_("Some fields are invalid."))

        if bdm_dict.get('no_device'):
            return

        # Check that all required fields are there
        if (self._required_fields and
                not ((dict_fields & self._required_fields) ==
                      self._required_fields)):
            raise exception.InvalidBDMFormat(
                details=_("Some required fields are missing"))

        if 'delete_on_termination' in bdm_dict:
            bdm_dict['delete_on_termination'] = strutils.bool_from_string(
                bdm_dict['delete_on_termination'])

        if bdm_dict.get('device_name') is not None:
            validate_device_name(bdm_dict['device_name'])

        validate_and_default_volume_size(bdm_dict)

        if bdm_dict.get('boot_index'):
            try:
                bdm_dict['boot_index'] = int(bdm_dict['boot_index'])
            except ValueError:
                raise exception.InvalidBDMFormat(
                    details=_("Boot index is invalid."))
Example #5
0
    def create(self, req, body):
        """Creates a new snapshot."""
        context = req.environ['nova.context']
        authorize(context)

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

        snapshot = body['snapshot']
        volume_id = snapshot['volume_id']

        LOG.audit(_("Create snapshot from volume %s"),
                  volume_id,
                  context=context)

        force = snapshot.get('force', False)
        try:
            force = strutils.bool_from_string(force, strict=True)
        except ValueError:
            msg = _("Invalid value '%s' for force.") % force
            raise exc.HTTPBadRequest(explanation=msg)

        if force:
            create_func = self.volume_api.create_snapshot_force
        else:
            create_func = self.volume_api.create_snapshot

        new_snapshot = create_func(context, volume_id,
                                   snapshot.get('display_name'),
                                   snapshot.get('display_description'))

        retval = _translate_snapshot_detail_view(context, new_snapshot)
        return {'snapshot': retval}
Example #6
0
 def sync_instances(self, req, body):
     """Tell all cells to sync instance info."""
     context = req.environ['nova.context']
     authorize(context)
     project_id = body.pop('project_id', None)
     deleted = body.pop('deleted', False)
     updated_since = body.pop('updated_since', None)
     if body:
         msg = _("Only 'updated_since', 'project_id' and 'deleted' are "
                 "understood.")
         raise exc.HTTPBadRequest(explanation=msg)
     if isinstance(deleted, six.string_types):
         try:
             deleted = strutils.bool_from_string(deleted, strict=True)
         except ValueError as err:
             raise exc.HTTPBadRequest(explanation=str(err))
     if updated_since:
         try:
             timeutils.parse_isotime(updated_since)
         except ValueError:
             msg = _('Invalid changes-since value')
             raise exc.HTTPBadRequest(explanation=msg)
     self.cells_rpcapi.sync_instances(context,
                                      project_id=project_id,
                                      updated_since=updated_since,
                                      deleted=deleted)
Example #7
0
    def server_create(self, server_dict, create_kwargs):
        # min_count and max_count are optional.  If they exist, they may come
        # in as strings.  Verify that they are valid integers and > 0.
        # Also, we want to default 'min_count' to 1, and default
        # 'max_count' to be 'min_count'.
        min_count = server_dict.get(MIN_ATTRIBUTE_NAME, 1)
        max_count = server_dict.get(MAX_ATTRIBUTE_NAME, min_count)
        return_id = server_dict.get(RRID_ATTRIBUTE_NAME, False)

        try:
            min_count = utils.validate_integer(min_count,
                                               "min_count", min_value=1)
            max_count = utils.validate_integer(max_count,
                                               "max_count", min_value=1)
            return_id = strutils.bool_from_string(return_id, strict=True)
        except exception.InvalidInput as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if min_count > max_count:
            msg = _('min_count must be <= max_count')
            raise exc.HTTPBadRequest(explanation=msg)

        create_kwargs['min_count'] = min_count
        create_kwargs['max_count'] = max_count
        create_kwargs['return_reservation_id'] = return_id
Example #8
0
    def server_create(self, server_dict, create_kwargs):
        # min_count and max_count are optional.  If they exist, they may come
        # in as strings.  Verify that they are valid integers and > 0.
        # Also, we want to default 'min_count' to 1, and default
        # 'max_count' to be 'min_count'.
        min_count = server_dict.get(MIN_ATTRIBUTE_NAME, 1)
        max_count = server_dict.get(MAX_ATTRIBUTE_NAME, min_count)
        return_id = server_dict.get(RRID_ATTRIBUTE_NAME, False)

        try:
            min_count = utils.validate_integer(min_count,
                                               "min_count",
                                               min_value=1)
            max_count = utils.validate_integer(max_count,
                                               "max_count",
                                               min_value=1)
            return_id = strutils.bool_from_string(return_id, strict=True)
        except exception.InvalidInput as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if min_count > max_count:
            msg = _('min_count must be <= max_count')
            raise exc.HTTPBadRequest(explanation=msg)

        create_kwargs['min_count'] = min_count
        create_kwargs['max_count'] = max_count
        create_kwargs['return_reservation_id'] = return_id
Example #9
0
 def _add_disk_config(self, context, images):
     for image in images:
         metadata = image['metadata']
         if INTERNAL_DISK_CONFIG in metadata:
             raw_value = metadata[INTERNAL_DISK_CONFIG]
             value = strutils.bool_from_string(raw_value)
             image[API_DISK_CONFIG] = disk_config_to_api(value)
Example #10
0
    def sync_instances(self, req, body):
        """Tell all cells to sync instance info."""
        context = req.environ['nova.context']

        authorize(context)
        authorize(context, action="sync_instances")

        project_id = body.pop('project_id', None)
        deleted = body.pop('deleted', False)
        updated_since = body.pop('updated_since', None)
        if body:
            msg = _("Only 'updated_since', 'project_id' and 'deleted' are "
                    "understood.")
            raise exc.HTTPBadRequest(explanation=msg)
        if isinstance(deleted, six.string_types):
            try:
                deleted = strutils.bool_from_string(deleted, strict=True)
            except ValueError as err:
                raise exc.HTTPBadRequest(explanation=str(err))
        if updated_since:
            try:
                timeutils.parse_isotime(updated_since)
            except ValueError:
                msg = _('Invalid changes-since value')
                raise exc.HTTPBadRequest(explanation=msg)
        self.cells_rpcapi.sync_instances(context, project_id=project_id,
                updated_since=updated_since, deleted=deleted)
Example #11
0
 def _add_disk_config(self, context, images):
     for image in images:
         metadata = image['metadata']
         if INTERNAL_DISK_CONFIG in metadata:
             raw_value = metadata[INTERNAL_DISK_CONFIG]
             value = strutils.bool_from_string(raw_value)
             image[API_DISK_CONFIG] = disk_config_to_api(value)
Example #12
0
    def create(self, req, body):
        """Creates a new snapshot."""
        context = req.environ["nova.context"]
        authorize(context)

        if not self.is_valid_body(body, "snapshot"):
            raise exc.HTTPUnprocessableEntity()

        snapshot = body["snapshot"]
        volume_id = snapshot["volume_id"]

        LOG.audit(_("Create snapshot from volume %s"), volume_id, context=context)

        force = snapshot.get("force", False)
        try:
            force = strutils.bool_from_string(force, strict=True)
        except ValueError:
            msg = _("Invalid value '%s' for force.") % force
            raise exception.InvalidParameterValue(err=msg)

        if force:
            create_func = self.volume_api.create_snapshot_force
        else:
            create_func = self.volume_api.create_snapshot

        new_snapshot = create_func(
            context, volume_id, snapshot.get("display_name"), snapshot.get("display_description")
        )

        retval = _translate_snapshot_detail_view(context, new_snapshot)
        return {"snapshot": retval}
Example #13
0
    def create(self, req, body):
        """Creates a new snapshot."""
        context = req.environ['nova.context']
        authorize(context)

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

        snapshot = body['snapshot']
        volume_id = snapshot['volume_id']

        LOG.audit(_("Create snapshot from volume %s"), volume_id,
                  context=context)

        force = snapshot.get('force', False)
        try:
            force = strutils.bool_from_string(force, strict=True)
        except ValueError:
            msg = _("Invalid value '%s' for force.") % force
            raise exc.HTTPBadRequest(explanation=msg)

        if force:
            create_func = self.volume_api.create_snapshot_force
        else:
            create_func = self.volume_api.create_snapshot

        new_snapshot = create_func(context, volume_id,
                                   snapshot.get('display_name'),
                                   snapshot.get('display_description'))

        retval = _translate_snapshot_detail_view(context, new_snapshot)
        return {'snapshot': retval}
    def _validate(self, bdm_dict):
        """Basic data format validations."""
        dict_fields = set(key for key, _ in bdm_dict.iteritems())

        # Check that there are no bogus fields
        if not (dict_fields <=
                (self._fields | self._db_only_fields)):
            raise exception.InvalidBDMFormat(
                details="Some fields are invalid.")

        if bdm_dict.get('no_device'):
            return

        # Check that all required fields are there
        if (self._required_fields and
                not ((dict_fields & self._required_fields) ==
                      self._required_fields)):
            raise exception.InvalidBDMFormat(
                details="Some required fields are missing")

        if 'delete_on_termination' in bdm_dict:
            bdm_dict['delete_on_termination'] = strutils.bool_from_string(
                bdm_dict['delete_on_termination'])

        if bdm_dict.get('device_name') is not None:
            validate_device_name(bdm_dict['device_name'])

        validate_and_default_volume_size(bdm_dict)

        if bdm_dict.get('boot_index'):
            try:
                bdm_dict['boot_index'] = int(bdm_dict['boot_index'])
            except ValueError:
                raise exception.InvalidBDMFormat(
                    details="Boot index is invalid.")
Example #15
0
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["nova.context"]
        authorize(context, 'migrate_live')

        try:
            block_migration = body["migrate_live"]["block_migration"]
            disk_over_commit = body["migrate_live"]["disk_over_commit"]
            host = body["migrate_live"]["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=str(err))

        try:
            instance = common.get_instance(self.compute_api, context, id,
                                           want_objects=True)
            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.InstanceNotRunning,
                exception.MigrationPreCheckError) as ex:
            raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'migrate_live')
        return webob.Response(status_int=202)
Example #16
0
    def _evacuate(self, req, id, body):
        """Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["nova.context"]
        authorize(context)

        if not self.is_valid_body(body, "evacuate"):
            raise exc.HTTPBadRequest(_("Malformed request body"))
        evacuate_body = body["evacuate"]

        try:
            host = evacuate_body["host"]
            on_shared_storage = strutils.bool_from_string(
                evacuate_body["onSharedStorage"])
        except (TypeError, KeyError):
            msg = _("host and onSharedStorage must be specified.")
            raise exc.HTTPBadRequest(explanation=msg)

        password = None
        if 'adminPass' in evacuate_body:
            # check that if requested to evacuate server on shared storage
            # password not specified
            if on_shared_storage:
                msg = _("admin password can't be changed on existing disk")
                raise exc.HTTPBadRequest(explanation=msg)

            password = evacuate_body['adminPass']
        elif not on_shared_storage:
            password = utils.generate_password()

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

        try:
            instance = self.compute_api.get(context, id, want_objects=True)
            if instance.host == host:
                msg = _("The target host can't be the same one.")
                raise exc.HTTPBadRequest(explanation=msg)
            self.compute_api.evacuate(context, instance, host,
                                      on_shared_storage, password)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'evacuate')
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.ComputeServiceInUse as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if password:
            return {'adminPass': password}
Example #17
0
    def _evacuate(self, req, id, body):
        """Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["nova.context"]
        authorize(context)

        if not self.is_valid_body(body, "evacuate"):
            raise exc.HTTPBadRequest(_("Malformed request body"))
        evacuate_body = body["evacuate"]

        try:
            host = evacuate_body["host"]
            on_shared_storage = strutils.bool_from_string(
                                            evacuate_body["onSharedStorage"])
        except (TypeError, KeyError):
            msg = _("host and onSharedStorage must be specified.")
            raise exc.HTTPBadRequest(explanation=msg)

        password = None
        if 'adminPass' in evacuate_body:
            # check that if requested to evacuate server on shared storage
            # password not specified
            if on_shared_storage:
                msg = _("admin password can't be changed on existing disk")
                raise exc.HTTPBadRequest(explanation=msg)

            password = evacuate_body['adminPass']
        elif not on_shared_storage:
            password = utils.generate_password()

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

        try:
            instance = self.compute_api.get(context, id)
            if instance['host'] == host:
                msg = _("The target host can't be the same one.")
                raise exc.HTTPBadRequest(explanation=msg)
            self.compute_api.evacuate(context, instance, host,
                                      on_shared_storage, password)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'evacuate')
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.ComputeServiceInUse as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if password:
            return {'adminPass': password}
Example #18
0
 def server_xml_extract_server_deserialize(self, server_node, server_dict):
     res_id = server_node.getAttribute(RRID_ATTRIBUTE_NAME)
     if res_id:
         server_dict[RRID_ATTRIBUTE_NAME] = strutils.bool_from_string(
             res_id)
     min_count = server_node.getAttribute(MIN_ATTRIBUTE_NAME)
     if min_count:
         server_dict[MIN_ATTRIBUTE_NAME] = min_count
     max_count = server_node.getAttribute(MAX_ATTRIBUTE_NAME)
     if max_count:
         server_dict[MAX_ATTRIBUTE_NAME] = max_count
Example #19
0
 def server_xml_extract_server_deserialize(self, server_node, server_dict):
     res_id = server_node.getAttribute(RRID_ATTRIBUTE_NAME)
     if res_id:
         server_dict[RRID_ATTRIBUTE_NAME] = strutils.bool_from_string(
             res_id)
     min_count = server_node.getAttribute(MIN_ATTRIBUTE_NAME)
     if min_count:
         server_dict[MIN_ATTRIBUTE_NAME] = min_count
     max_count = server_node.getAttribute(MAX_ATTRIBUTE_NAME)
     if max_count:
         server_dict[MAX_ATTRIBUTE_NAME] = max_count
Example #20
0
File: agent.py Project: markmc/nova
def should_use_agent(instance):
    sys_meta = utils.instance_sys_meta(instance)
    if USE_AGENT_SM_KEY not in sys_meta:
        return CONF.xenserver.use_agent_default
    else:
        use_agent_raw = sys_meta[USE_AGENT_SM_KEY]
        try:
            return strutils.bool_from_string(use_agent_raw, strict=True)
        except ValueError:
            LOG.warn(_("Invalid 'agent_present' value. " "Falling back to the default."), instance=instance)
            return CONF.xenserver.use_agent_default
Example #21
0
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["nova.context"]
        authorize(context, 'migrate_live')

        try:
            block_migration = body["migrate_live"]["block_migration"]
            disk_over_commit = body["migrate_live"]["disk_over_commit"]
            host = body["migrate_live"]["host"]
            pclm = body["migrate_live"]["pclm"]
        except (TypeError, KeyError):
            msg = _("host, block_migration, disk_over_commit and pclm 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=str(err))

        try:
            instance = common.get_instance(self.compute_api, context, id,
                                           want_objects=True)
            self.compute_api.live_migrate(context, instance, block_migration,
                                          disk_over_commit, host, pclm)
        except (exception.ComputeServiceUnavailable,
                exception.InvalidHypervisorType,
                exception.UnableToMigrateToSelf,
                exception.DestinationHypervisorTooOld,
                exception.NoValidHost,
                exception.InvalidLocalStorage,
                exception.InvalidSharedStorage,
                exception.MigrationPreCheckError) as ex:
            raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'migrate_live')
        return webob.Response(status_int=202)
Example #22
0
def required_by(instance):

    image_prop = utils.instance_sys_meta(instance).get(
        utils.SM_IMAGE_PROP_PREFIX + 'img_config_drive', 'optional')
    if image_prop not in ['optional', 'mandatory']:
        LOG.warn(_LW('Image config drive option %(image_prop)s is invalid '
                     'and will be ignored') % {'image_prop': image_prop},
                 instance=instance)

    return (instance.get('config_drive') or 'always' == CONF.force_config_drive
            or strutils.bool_from_string(CONF.force_config_drive)
            or image_prop == 'mandatory')
Example #23
0
def _untranslate_volume_summary_view(context, vol):
    """Maps keys for volumes summary view."""
    d = {}
    d["id"] = vol.id
    d["status"] = vol.status
    d["size"] = vol.size
    d["availability_zone"] = vol.availability_zone
    d["created_at"] = vol.created_at
    d["shareable"] = vol.shareable

    # TODO(jdg): The calling code expects attach_time and
    #            mountpoint to be set. When the calling
    #            code is more defensive this can be
    #            removed.
    d["attach_time"] = ""
    d["mountpoint"] = ""

    if vol.attachments:
        d["attachments"] = []
        for attach in vol.attachments:
            a = {
                "attach_status": "attached",
                "attachment_id": attach["attachment_id"],
                "instance_uuid": attach["server_id"],
                "mountpoint": attach["device"],
            }
            d["attachments"].append(a)
        d["attach_status"] = "attached"

    else:
        d["attach_status"] = "detached"
        d["attachments"] = []
    # NOTE(dzyu) volume(cinder) v2 API uses 'name' instead of 'display_name',
    # and use 'description' instead of 'display_description' for volume.
    if hasattr(vol, "display_name"):
        d["display_name"] = vol.display_name
        d["display_description"] = vol.display_description
    else:
        d["display_name"] = vol.name
        d["display_description"] = vol.description
    # TODO(jdg): Information may be lost in this translation
    d["volume_type_id"] = vol.volume_type
    d["snapshot_id"] = vol.snapshot_id
    d["bootable"] = strutils.bool_from_string(vol.bootable)
    d["volume_metadata"] = {}
    for key, value in vol.metadata.items():
        d["volume_metadata"][key] = value

    if hasattr(vol, "volume_image_metadata"):
        d["volume_image_metadata"] = copy.deepcopy(vol.volume_image_metadata)

    return d
Example #24
0
def should_use_agent(instance):
    sys_meta = utils.instance_sys_meta(instance)
    if USE_AGENT_SM_KEY not in sys_meta:
        return CONF.xenserver.use_agent_default
    else:
        use_agent_raw = sys_meta[USE_AGENT_SM_KEY]
        try:
            return strutils.bool_from_string(use_agent_raw, strict=True)
        except ValueError:
            LOG.warn(_("Invalid 'agent_present' value. "
                       "Falling back to the default."),
                       instance=instance)
            return CONF.xenserver.use_agent_default
Example #25
0
def _untranslate_volume_summary_view(context, vol):
    """Maps keys for volumes summary view."""
    d = {}
    d['id'] = vol.id
    d['status'] = vol.status
    d['size'] = vol.size
    d['availability_zone'] = vol.availability_zone
    d['created_at'] = vol.created_at
    d['shareable'] = vol.shareable
    
    # TODO(jdg): The calling code expects attach_time and
    #            mountpoint to be set. When the calling
    #            code is more defensive this can be
    #            removed.
    d['attach_time'] = ""
    d['mountpoint'] = ""

    if vol.attachments:
        d['attachments'] = []
        for attach in vol.attachments:
            a = {'attach_status': 'attached',
                 'attachment_id': attach['attachment_id'],
                 'instance_uuid': attach['server_id'],
                 'mountpoint': attach['device'],
                 }
            d['attachments'].append(a)
        d['attach_status'] = 'attached'

    else:
        d['attach_status'] = 'detached'
        d['attachments'] = []
    # NOTE(dzyu) volume(cinder) v2 API uses 'name' instead of 'display_name',
    # and use 'description' instead of 'display_description' for volume.
    if hasattr(vol, 'display_name'):
        d['display_name'] = vol.display_name
        d['display_description'] = vol.display_description
    else:
        d['display_name'] = vol.name
        d['display_description'] = vol.description
    # TODO(jdg): Information may be lost in this translation
    d['volume_type_id'] = vol.volume_type
    d['snapshot_id'] = vol.snapshot_id
    d['bootable'] = strutils.bool_from_string(vol.bootable)
    d['volume_metadata'] = {}
    for key, value in vol.metadata.items():
        d['volume_metadata'][key] = value

    if hasattr(vol, 'volume_image_metadata'):
        d['volume_image_metadata'] = copy.deepcopy(vol.volume_image_metadata)

    return d
Example #26
0
    def sync_instances(self, req, body):
        """Tell all cells to sync instance info."""
        context = req.environ['nova.context']

        authorize(context)
        authorize(context, action="sync_instances")

        project_id = body.pop('project_id', None)
        deleted = body.pop('deleted', False)
        updated_since = body.pop('updated_since', None)
        if isinstance(deleted, six.string_types):
            deleted = strutils.bool_from_string(deleted, strict=True)
        self.cells_rpcapi.sync_instances(context, project_id=project_id,
                updated_since=updated_since, deleted=deleted)
Example #27
0
    def _parse_is_public(self, is_public):
        """Parse is_public into something usable."""

        if is_public is None:
            # preserve default value of showing only public flavors
            return True
        elif utils.is_none_string(is_public):
            return None
        else:
            try:
                return strutils.bool_from_string(is_public, strict=True)
            except ValueError:
                msg = _('Invalid is_public filter [%s]') % is_public
                raise webob.exc.HTTPBadRequest(explanation=msg)
Example #28
0
    def _evacuate(self, req, id, body):
        """Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["nova.context"]
        authorize(context)

        evacuate_body = body["evacuate"]
        host = evacuate_body.get("host")
        on_shared_storage = strutils.bool_from_string(
                                        evacuate_body["onSharedStorage"])

        password = None
        if 'adminPass' in evacuate_body:
            # check that if requested to evacuate server on shared storage
            # password not specified
            if on_shared_storage:
                msg = _("admin password can't be changed on existing disk")
                raise exc.HTTPBadRequest(explanation=msg)

            password = evacuate_body['adminPass']
        elif not on_shared_storage:
            password = utils.generate_password()

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

        instance = common.get_instance(self.compute_api, context, id,
                                       want_objects=True)
        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.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 CONF.enable_instance_password:
            return {'adminPass': password}
        else:
            return {}
Example #29
0
    def update(self, req, id, body):
        context = req.environ['nova.context']
        authorize_update(context)
        project_id = id
        params = urlparse.parse_qs(req.environ.get('QUERY_STRING', ''))
        user_id = params.get('user_id', [None])[0]

        quota_set = body['quota_set']
        force_update = strutils.bool_from_string(
            quota_set.get('force', 'False'))

        try:
            settable_quotas = QUOTAS.get_settable_quotas(context,
                                                         project_id,
                                                         user_id=user_id)
        except exception.Forbidden:
            raise webob.exc.HTTPForbidden()

        LOG.debug("Force update quotas: %s", force_update)

        for key, value in body['quota_set'].iteritems():
            if key == 'force' or (not value and value != 0):
                continue
            # validate whether already used and reserved exceeds the new
            # quota, this check will be ignored if admin want to force
            # update
            value = int(value)
            if not force_update:
                minimum = settable_quotas[key]['minimum']
                maximum = settable_quotas[key]['maximum']
                self._validate_quota_limit(key, value, minimum, maximum)

            try:
                objects.Quotas.create_limit(context,
                                            project_id,
                                            key,
                                            value,
                                            user_id=user_id)
            except exception.QuotaExists:
                objects.Quotas.update_limit(context,
                                            project_id,
                                            key,
                                            value,
                                            user_id=user_id)
            except exception.AdminRequired:
                raise webob.exc.HTTPForbidden()
        return self._format_quota_set(
            id, self._get_quotas(context, id, user_id=user_id))
Example #30
0
def required_by(instance):

    image_prop = utils.instance_sys_meta(instance).get(utils.SM_IMAGE_PROP_PREFIX + "img_config_drive", "optional")
    if image_prop not in ["optional", "mandatory"]:
        LOG.warn(
            _LW("Image config drive option %(image_prop)s is invalid " "and will be ignored")
            % {"image_prop": image_prop},
            instance=instance,
        )

    return (
        instance.get("config_drive")
        or "always" == CONF.force_config_drive
        or strutils.bool_from_string(CONF.force_config_drive)
        or image_prop == "mandatory"
    )
Example #31
0
File: cells.py Project: tdp100/nova
    def sync_instances(self, req, body):
        """Tell all cells to sync instance info."""
        context = req.environ['nova.context']

        authorize(context)
        authorize(context, action="sync_instances")

        project_id = body.pop('project_id', None)
        deleted = body.pop('deleted', False)
        updated_since = body.pop('updated_since', None)
        if isinstance(deleted, six.string_types):
            deleted = strutils.bool_from_string(deleted, strict=True)
        self.cells_rpcapi.sync_instances(context,
                                         project_id=project_id,
                                         updated_since=updated_since,
                                         deleted=deleted)
Example #32
0
    def _evacuate(self, req, id, body):
        """
        Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["nova.context"]
        authorize(context)

        try:
            if len(body) != 1:
                raise exc.HTTPBadRequest(_("Malformed request body"))

            evacuate_body = body["evacuate"]
            host = evacuate_body["host"]
            on_shared_storage = strutils.bool_from_string(
                evacuate_body["onSharedStorage"])

            password = None
            if 'adminPass' in evacuate_body:
                # check that if requested to evacuate server on shared storage
                # password not specified
                if on_shared_storage:
                    msg = _("admin password can't be changed on existing disk")
                    raise exc.HTTPBadRequest(explanation=msg)

                password = evacuate_body['adminPass']
            elif not on_shared_storage:
                password = utils.generate_password()

        except (TypeError, KeyError):
            msg = _("host and onSharedStorage must be specified.")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            instance = self.compute_api.get(context, id)
            self.compute_api.evacuate(context, instance, host,
                                      on_shared_storage, password)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'evacuate')
        except Exception as e:
            msg = _("Error in evacuate, %s") % e
            LOG.exception(msg, instance=instance)
            raise exc.HTTPBadRequest(explanation=msg)

        if password:
            return {'adminPass': password}
Example #33
0
    def _evacuate(self, req, id, body):
        """
        Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["nova.context"]
        authorize(context)

        try:
            if len(body) != 1:
                raise exc.HTTPBadRequest(_("Malformed request body"))

            evacuate_body = body["evacuate"]
            host = evacuate_body["host"]
            on_shared_storage = strutils.bool_from_string(
                                            evacuate_body["onSharedStorage"])

            password = None
            if 'adminPass' in evacuate_body:
                # check that if requested to evacuate server on shared storage
                # password not specified
                if on_shared_storage:
                    msg = _("admin password can't be changed on existing disk")
                    raise exc.HTTPBadRequest(explanation=msg)

                password = evacuate_body['adminPass']
            elif not on_shared_storage:
                password = utils.generate_password()

        except (TypeError, KeyError):
            msg = _("host and onSharedStorage must be specified.")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            instance = self.compute_api.get(context, id)
            self.compute_api.evacuate(context, instance, host,
                                      on_shared_storage, password)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'evacuate')
        except Exception as e:
            msg = _("Error in evacuate, %s") % e
            LOG.exception(msg, instance=instance)
            raise exc.HTTPBadRequest(explanation=msg)

        if password:
            return {'adminPass': password}
Example #34
0
    def _evacuate(self, req, id, body):
        """Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["nova.context"]
        authorize(context)

        evacuate_body = body["evacuate"]
        host = evacuate_body["host"]
        on_shared_storage = strutils.bool_from_string(
            evacuate_body["on_shared_storage"])

        password = None
        if 'admin_password' in evacuate_body:
            # check that if requested to evacuate server on shared storage
            # password not specified
            if on_shared_storage:
                msg = _("admin password can't be changed on existing disk")
                raise exc.HTTPBadRequest(explanation=msg)

            password = evacuate_body['admin_password']
        elif not on_shared_storage:
            password = utils.generate_password()

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

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

        if CONF.enable_instance_password:
            return {'admin_password': password}
        else:
            return {}
Example #35
0
    def from_image(cls, image_id, image_meta=None):
        """Returns VMwareImage, the subset of properties the driver uses.

        :param image_id - image id of image
        :param image_meta - image metadata we are working with
        :return: vmware image object
        :rtype: nova.virt.vmwareapi.vmware_images.VmwareImage
        """
        if image_meta is None:
            image_meta = {}

        properties = image_meta.get("properties", {})

        # calculate linked_clone flag, allow image properties to override the
        # global property set in the configurations.
        image_linked_clone = properties.get(LINKED_CLONE_PROPERTY,
                                            CONF.vmware.use_linked_clone)

        # catch any string values that need to be interpreted as boolean values
        linked_clone = strutils.bool_from_string(image_linked_clone)

        props = {
            'image_id': image_id,
            'linked_clone': linked_clone
        }

        if 'size' in image_meta:
            props['file_size'] = image_meta['size']
        if 'disk_format' in image_meta:
            props['file_type'] = image_meta['disk_format']

        props_map = {
            'vmware_ostype': 'os_type',
            'vmware_adaptertype': 'adapter_type',
            'vmware_disktype': 'disk_type',
            'hw_vif_model': 'vif_model'
        }

        for k, v in props_map.iteritems():
            if k in properties:
                props[v] = properties[k]

        return cls(**props)
Example #36
0
    def index(self, req):
        """Return a list of floating ips."""
        context = req.environ['nova.context']
        authorize(context)
        all_tenants = False
        if 'all_tenants' in req.GET:
            try:
                if strutils.bool_from_string(req.GET['all_tenants'], True):
                    authorize_all_tenants(context)
                    all_tenants = True
            except ValueError as err:
                raise webob.exc.HTTPBadRequest(explanation=str(err))

        floating_ips = self.network_api.get_floating_ips(context, all_tenants)

        for floating_ip in floating_ips:
            self._normalize_ip(floating_ip)

        return _translate_floating_ips_view(floating_ips)
Example #37
0
    def index(self, req):
        """Return a list of floating ips."""
        context = req.environ['nova.context']
        authorize(context)
        all_tenants = False
        if 'all_tenants' in req.GET:
            try:
                if strutils.bool_from_string(req.GET['all_tenants'], True):
                    authorize_all_tenants(context)
                    all_tenants = True
            except ValueError as err:
                raise webob.exc.HTTPBadRequest(explanation=str(err))

        floating_ips = self.network_api.get_floating_ips(context, all_tenants)

        for floating_ip in floating_ips:
            self._normalize_ip(floating_ip)

        return _translate_floating_ips_view(floating_ips)
Example #38
0
    def from_image(cls, image_id, image_meta=None):
        """Returns VMwareImage, the subset of properties the driver uses.

        :param image_id - image id of image
        :param image_meta - image metadata we are working with
        :return: vmware image object
        :rtype: nova.virt.vmwareapi.vmware_images.VmwareImage
        """
        if image_meta is None:
            image_meta = {}

        properties = image_meta.get("properties", {})

        # calculate linked_clone flag, allow image properties to override the
        # global property set in the configurations.
        image_linked_clone = properties.get(LINKED_CLONE_PROPERTY,
                                            CONF.vmware.use_linked_clone)

        # catch any string values that need to be interpreted as boolean values
        linked_clone = strutils.bool_from_string(image_linked_clone)

        props = {'image_id': image_id, 'linked_clone': linked_clone}

        if 'size' in image_meta:
            props['file_size'] = image_meta['size']
        if 'disk_format' in image_meta:
            props['file_type'] = image_meta['disk_format']

        props_map = {
            'vmware_ostype': 'os_type',
            'vmware_adaptertype': 'adapter_type',
            'vmware_disktype': 'disk_type',
            'hw_vif_model': 'vif_model'
        }

        for k, v in props_map.iteritems():
            if k in properties:
                props[v] = properties[k]

        return cls(**props)
Example #39
0
def _untranslate_volume_summary_view(context, vol):
    """Maps keys for volumes summary view."""
    d = {}
    d['id'] = vol.id
    d['status'] = vol.status
    d['size'] = vol.size
    d['availability_zone'] = vol.availability_zone
    d['created_at'] = vol.created_at

    # TODO(jdg): The calling code expects attach_time and
    #            mountpoint to be set. When the calling
    #            code is more defensive this can be
    #            removed.
    d['attach_time'] = ""
    d['mountpoint'] = ""

    if vol.attachments:
        att = vol.attachments[0]
        d['attach_status'] = 'attached'
        d['instance_uuid'] = att['server_id']
        d['mountpoint'] = att['device']
    else:
        d['attach_status'] = 'detached'

    d['display_name'] = vol.display_name
    d['display_description'] = vol.display_description

    # TODO(jdg): Information may be lost in this translation
    d['volume_type_id'] = vol.volume_type
    d['snapshot_id'] = vol.snapshot_id
    d['bootable'] = strutils.bool_from_string(vol.bootable)
    d['volume_metadata'] = {}
    for key, value in vol.metadata.items():
        d['volume_metadata'][key] = value

    if hasattr(vol, 'volume_image_metadata'):
        d['volume_image_metadata'] = copy.deepcopy(vol.volume_image_metadata)

    return d
Example #40
0
def _untranslate_volume_summary_view(context, vol):
    """Maps keys for volumes summary view."""
    d = {}
    d['id'] = vol.id
    d['status'] = vol.status
    d['size'] = vol.size
    d['availability_zone'] = vol.availability_zone
    d['created_at'] = vol.created_at

    # TODO(jdg): The calling code expects attach_time and
    #            mountpoint to be set. When the calling
    #            code is more defensive this can be
    #            removed.
    d['attach_time'] = ""
    d['mountpoint'] = ""

    if vol.attachments:
        att = vol.attachments[0]
        d['attach_status'] = 'attached'
        d['instance_uuid'] = att['server_id']
        d['mountpoint'] = att['device']
    else:
        d['attach_status'] = 'detached'

    d['display_name'] = vol.display_name
    d['display_description'] = vol.display_description

    # TODO(jdg): Information may be lost in this translation
    d['volume_type_id'] = vol.volume_type
    d['snapshot_id'] = vol.snapshot_id
    d['bootable'] = strutils.bool_from_string(vol.bootable)
    d['volume_metadata'] = {}
    for key, value in vol.metadata.items():
        d['volume_metadata'][key] = value

    if hasattr(vol, 'volume_image_metadata'):
        d['volume_image_metadata'] = copy.deepcopy(vol.volume_image_metadata)

    return d
Example #41
0
    def server_create(self, server_dict, create_kwargs, body_deprecated_param):
        block_device_mapping = server_dict.get(ATTRIBUTE_NAME, [])
        block_device_mapping_v2 = server_dict.get(ATTRIBUTE_NAME_V2, [])

        if block_device_mapping and block_device_mapping_v2:
            expl = _('Using different block_device_mapping syntaxes '
                     'is not allowed in the same request.')
            raise exc.HTTPBadRequest(explanation=expl)

        for bdm in block_device_mapping:
            try:
                block_device.validate_device_name(bdm.get("device_name"))
                block_device.validate_and_default_volume_size(bdm)
            except exception.InvalidBDMFormat as e:
                raise exc.HTTPBadRequest(explanation=e.format_message())

            if 'delete_on_termination' in bdm:
                bdm['delete_on_termination'] = strutils.bool_from_string(
                    bdm['delete_on_termination'])

        if block_device_mapping:
            create_kwargs['block_device_mapping'] = block_device_mapping
            # Sets the legacy_bdm flag if we got a legacy block device mapping.
            create_kwargs['legacy_bdm'] = True
    def server_create(self, server_dict, create_kwargs, body_deprecated_param):
        block_device_mapping = server_dict.get(ATTRIBUTE_NAME, [])
        block_device_mapping_v2 = server_dict.get(ATTRIBUTE_NAME_V2, [])

        if block_device_mapping and block_device_mapping_v2:
            expl = _('Using different block_device_mapping syntaxes '
                     'is not allowed in the same request.')
            raise exc.HTTPBadRequest(explanation=expl)

        for bdm in block_device_mapping:
            try:
                block_device.validate_device_name(bdm.get("device_name"))
                block_device.validate_and_default_volume_size(bdm)
            except exception.InvalidBDMFormat as e:
                raise exc.HTTPBadRequest(explanation=e.format_message())

            if 'delete_on_termination' in bdm:
                bdm['delete_on_termination'] = strutils.bool_from_string(
                    bdm['delete_on_termination'])

        if block_device_mapping:
            create_kwargs['block_device_mapping'] = block_device_mapping
            # Sets the legacy_bdm flag if we got a legacy block device mapping.
            create_kwargs['legacy_bdm'] = True
Example #43
0
    def update(self, req, id, body):
        context = req.environ['nova.context']
        authorize_update(context)
        project_id = id
        params = urlparse.parse_qs(req.environ.get('QUERY_STRING', ''))
        user_id = params.get('user_id', [None])[0]

        bad_keys = []
        force_update = False

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

        for key, value in quota_set.items():
            if key not in QUOTAS and key != 'force':
                bad_keys.append(key)
                continue
            if key == 'force':
                force_update = strutils.bool_from_string(value)
            elif key != 'force' and value:
                try:
                    value = int(value)
                except (ValueError, TypeError):
                    msg = _("Quota value for key '%(key)s' should be an "
                            "integer.  It is actually type '%(vtype)s'.")
                    msg = msg % {'key': key, 'vtype': type(value)}
                    LOG.warn(msg)
                    raise webob.exc.HTTPBadRequest(explanation=msg)

        if len(bad_keys) > 0:
            msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            settable_quotas = QUOTAS.get_settable_quotas(context,
                                                         project_id,
                                                         user_id=user_id)
        except exception.NotAuthorized:
            raise webob.exc.HTTPForbidden()

        try:
            quotas = self._get_quotas(context,
                                      id,
                                      user_id=user_id,
                                      usages=True)
        except exception.NotAuthorized:
            raise webob.exc.HTTPForbidden()

        LOG.debug(_("Force update quotas: %s"), force_update)

        for key, value in body['quota_set'].iteritems():
            if key == 'force' or (not value and value != 0):
                continue
            # validate whether already used and reserved exceeds the new
            # quota, this check will be ignored if admin want to force
            # update
            value = int(value)
            if force_update is not True and value >= 0:
                quota_value = quotas.get(key)
                if quota_value and quota_value['limit'] >= 0:
                    quota_used = (quota_value['in_use'] +
                                  quota_value['reserved'])
                    LOG.debug(
                        _("Quota %(key)s used: %(quota_used)s, "
                          "value: %(value)s."), {
                              'key': key,
                              'quota_used': quota_used,
                              'value': value
                          })
                    if quota_used > value:
                        msg = (_("Quota value %(value)s for %(key)s are "
                                 "less than already used and reserved "
                                 "%(quota_used)s") % {
                                     'value': value,
                                     'key': key,
                                     'quota_used': quota_used
                                 })
                        raise webob.exc.HTTPBadRequest(explanation=msg)

            minimum = settable_quotas[key]['minimum']
            maximum = settable_quotas[key]['maximum']
            self._validate_quota_limit(value, minimum, maximum)
            try:
                db.quota_create(context,
                                project_id,
                                key,
                                value,
                                user_id=user_id)
            except exception.QuotaExists:
                db.quota_update(context,
                                project_id,
                                key,
                                value,
                                user_id=user_id)
            except exception.AdminRequired:
                raise webob.exc.HTTPForbidden()
        return self._format_quota_set(
            id, self._get_quotas(context, id, user_id=user_id))
Example #44
0
    def update(self, req, id, body):
        context = req.environ['nova.context']
        authorize_update(context)
        project_id = id

        bad_keys = []

        # By default, we can force update the quota if the extended
        # is not loaded
        force_update = True
        extended_loaded = False
        if self.ext_mgr.is_loaded('os-extended-quotas'):
            # force optional has been enabled, the default value of
            # force_update need to be changed to False
            extended_loaded = True
            force_update = False

        for key, value in body['quota_set'].items():
            if (key not in QUOTAS and key not in NON_QUOTA_KEYS):
                bad_keys.append(key)
                continue
            if key == 'force' and extended_loaded:
                # only check the force optional when the extended has
                # been loaded
                force_update = strutils.bool_from_string(value)
            elif key not in NON_QUOTA_KEYS and value:
                try:
                    value = int(value)
                except (ValueError, TypeError):
                    msg = _("Quota '%(value)s' for %(key)s should be "
                            "integer.") % locals()
                    LOG.warn(msg)
                    raise webob.exc.HTTPBadRequest(explanation=msg)
                self._validate_quota_limit(value)

        LOG.debug(_("force update quotas: %s") % force_update)

        if len(bad_keys) > 0:
            msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            project_quota = self._get_quotas(context, id, True)
        except exception.NotAuthorized:
            raise webob.exc.HTTPForbidden()

        for key, value in body['quota_set'].items():
            if key in NON_QUOTA_KEYS or not value:
                continue
            # validate whether already used and reserved exceeds the new
            # quota, this check will be ignored if admin want to force
            # update
            value = int(value)
            if force_update is not True and value >= 0:
                quota_value = project_quota.get(key)
                if quota_value and quota_value['limit'] >= 0:
                    quota_used = (quota_value['in_use'] +
                                  quota_value['reserved'])
                    LOG.debug(
                        _("Quota %(key)s used: %(quota_used)s, "
                          "value: %(value)s."), {
                              'key': key,
                              'quota_used': quota_used,
                              'value': value
                          })
                    if quota_used > value:
                        msg = (_("Quota value %(value)s for %(key)s are "
                                 "greater than already used and reserved "
                                 "%(quota_used)s") % {
                                     'value': value,
                                     'key': key,
                                     'quota_used': quota_used
                                 })
                        raise webob.exc.HTTPBadRequest(explanation=msg)

            try:
                db.quota_update(context, project_id, key, value)
            except exception.ProjectQuotaNotFound:
                db.quota_create(context, project_id, key, value)
            except exception.AdminRequired:
                raise webob.exc.HTTPForbidden()
        return {'quota_set': self._get_quotas(context, id)}
Example #45
0
def create(name,
           memory,
           vcpus,
           root_gb,
           ephemeral_gb=0,
           flavorid=None,
           swap=0,
           rxtx_factor=1.0,
           is_public=True):
    """Creates flavors."""
    if not flavorid:
        flavorid = uuid.uuid4()

    kwargs = {
        'memory_mb': memory,
        'vcpus': vcpus,
        'root_gb': root_gb,
        'ephemeral_gb': ephemeral_gb,
        'swap': swap,
        'rxtx_factor': rxtx_factor,
    }

    if isinstance(name, six.string_types):
        name = name.strip()
    # ensure name do not exceed 255 characters
    utils.check_string_length(name, 'name', min_length=1, max_length=255)

    # ensure name does not contain any special characters
    valid_name = VALID_NAME_REGEX.search(name)
    if not valid_name:
        msg = _("Flavor names can only contain alphanumeric characters, "
                "periods, dashes, underscores and spaces.")
        raise exception.InvalidInput(reason=msg)

    # NOTE(vish): Internally, flavorid is stored as a string but it comes
    #             in through json as an integer, so we convert it here.
    flavorid = unicode(flavorid)

    # ensure leading/trailing whitespaces not present.
    if flavorid.strip() != flavorid:
        msg = _("id cannot contain leading and/or trailing whitespace(s)")
        raise exception.InvalidInput(reason=msg)

    # ensure flavor id does not exceed 255 characters
    utils.check_string_length(flavorid, 'id', min_length=1, max_length=255)

    # ensure flavor id does not contain any special characters
    valid_flavor_id = VALID_ID_REGEX.search(flavorid)
    if not valid_flavor_id:
        msg = _("Flavor id can only contain letters from A-Z (both cases), "
                "periods, dashes, underscores and spaces.")
        raise exception.InvalidInput(reason=msg)

    # NOTE(wangbo): validate attributes of the creating flavor.
    # ram and vcpus should be positive ( > 0) integers.
    # disk, ephemeral and swap should be non-negative ( >= 0) integers.
    flavor_attributes = {
        'memory_mb': ('ram', 1),
        'vcpus': ('vcpus', 1),
        'root_gb': ('disk', 0),
        'ephemeral_gb': ('ephemeral', 0),
        'swap': ('swap', 0)
    }

    for key, value in flavor_attributes.items():
        kwargs[key] = utils.validate_integer(kwargs[key], value[0], value[1],
                                             db.MAX_INT)

    # rxtx_factor should be a positive float
    try:
        kwargs['rxtx_factor'] = float(kwargs['rxtx_factor'])
        if (kwargs['rxtx_factor'] <= 0
                or kwargs['rxtx_factor'] > SQL_SP_FLOAT_MAX):
            raise ValueError()
    except ValueError:
        msg = (_("'rxtx_factor' argument must be a float between 0 and %g") %
               SQL_SP_FLOAT_MAX)
        raise exception.InvalidInput(reason=msg)

    kwargs['name'] = name
    kwargs['flavorid'] = flavorid
    # ensure is_public attribute is boolean
    try:
        kwargs['is_public'] = strutils.bool_from_string(is_public, strict=True)
    except ValueError:
        raise exception.InvalidInput(reason=_("is_public must be a boolean"))

    try:
        return db.flavor_create(context.get_admin_context(), kwargs)
    except db_exc.DBError as e:
        LOG.exception(_LE('DB error: %s'), e)
        raise exception.FlavorCreateFailed()
Example #46
0
 def _get_sys_meta_key(self, key):
     sys_meta = utils.instance_sys_meta(self.instance)
     raw_value = sys_meta.get(key, 'False')
     return strutils.bool_from_string(raw_value, strict=False)
Example #47
0
    def _action_rebuild(self, req, id, body):
        """Rebuild an instance with the given attributes."""
        try:
            rebuild_dict = body['rebuild']
        except (KeyError, TypeError):
            msg = _('Invalid request body')
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            image_href = rebuild_dict["image_ref"]
        except (KeyError, TypeError):
            msg = _("Could not parse image_ref from request.")
            raise exc.HTTPBadRequest(explanation=msg)

        image_href = self._image_uuid_from_href(image_href)

        password = self._get_server_admin_password(rebuild_dict)

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

        attr_map = {
            'name': 'display_name',
            'metadata': 'metadata',
        }

        rebuild_kwargs = {}

        if 'name' in rebuild_dict:
            self._validate_server_name(rebuild_dict['name'])

        if 'preserve_ephemeral' in rebuild_dict:
            rebuild_kwargs['preserve_ephemeral'] = strutils.bool_from_string(
                rebuild_dict['preserve_ephemeral'], strict=True)

        if list(self.rebuild_extension_manager):
            self.rebuild_extension_manager.map(self._rebuild_extension_point,
                                               rebuild_dict, rebuild_kwargs)

        for request_attribute, instance_attribute in attr_map.items():
            try:
                rebuild_kwargs[instance_attribute] = rebuild_dict[
                    request_attribute]
            except (KeyError, TypeError):
                pass

        try:
            self.compute_api.rebuild(context,
                                     instance,
                                     image_href,
                                     password,
                                     **rebuild_kwargs)
        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,
                    'rebuild')
        except exception.InstanceNotFound:
            msg = _("Instance could not be found")
            raise exc.HTTPNotFound(explanation=msg)
        except exception.InvalidMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message())
        except exception.ImageNotFound:
            msg = _("Cannot find image for rebuild")
            raise exc.HTTPBadRequest(explanation=msg)
        except (exception.ImageNotActive,
                exception.FlavorDiskTooSmall,
                exception.FlavorMemoryTooSmall,
                exception.InvalidMetadata) as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

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

        view = self._view_builder.show(req, instance)

        # Add on the admin_password attribute since the view doesn't do it
        # unless instance passwords are disabled
        if CONF.enable_instance_password:
            view['server']['admin_password'] = password

        robj = wsgi.ResponseObject(view)
        return self._add_location(robj)
Example #48
0
    def update(self, req, id, body):
        context = req.environ["nova.context"]
        authorize_update(context)
        project_id = id

        bad_keys = []

        # By default, we can force update the quota if the extended
        # is not loaded
        force_update = True
        extended_loaded = False
        if self.ext_mgr.is_loaded("os-extended-quotas"):
            # force optional has been enabled, the default value of
            # force_update need to be changed to False
            extended_loaded = True
            force_update = False

        user_id = None
        if self.ext_mgr.is_loaded("os-user-quotas"):
            # Update user quotas only if the extended is loaded
            params = urlparse.parse_qs(req.environ.get("QUERY_STRING", ""))
            user_id = params.get("user_id", [None])[0]

        try:
            settable_quotas = QUOTAS.get_settable_quotas(context, project_id, user_id=user_id)
        except exception.NotAuthorized:
            raise webob.exc.HTTPForbidden()

        if not self.is_valid_body(body, "quota_set"):
            msg = _("quota_set not specified")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        quota_set = body["quota_set"]
        for key, value in quota_set.items():
            if key not in QUOTAS and key not in NON_QUOTA_KEYS:
                bad_keys.append(key)
                continue
            if key == "force" and extended_loaded:
                # only check the force optional when the extended has
                # been loaded
                force_update = strutils.bool_from_string(value)
            elif key not in NON_QUOTA_KEYS and value:
                try:
                    value = utils.validate_integer(value, key)
                except exception.InvalidInput as e:
                    LOG.warn(e.format_message())
                    raise webob.exc.HTTPBadRequest(explanation=e.format_message())

        LOG.debug(_("force update quotas: %s") % force_update)

        if len(bad_keys) > 0:
            msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            quotas = self._get_quotas(context, id, user_id=user_id, usages=True)
        except exception.NotAuthorized:
            raise webob.exc.HTTPForbidden()

        for key, value in quota_set.items():
            if key in NON_QUOTA_KEYS or (not value and value != 0):
                continue
            # validate whether already used and reserved exceeds the new
            # quota, this check will be ignored if admin want to force
            # update
            value = int(value)
            if force_update is not True and value >= 0:
                quota_value = quotas.get(key)
                if quota_value and quota_value["limit"] >= 0:
                    quota_used = quota_value["in_use"] + quota_value["reserved"]
                    LOG.debug(
                        _("Quota %(key)s used: %(quota_used)s, " "value: %(value)s."),
                        {"key": key, "quota_used": quota_used, "value": value},
                    )
                    if quota_used > value:
                        msg = _(
                            "Quota value %(value)s for %(key)s are "
                            "less than already used and reserved "
                            "%(quota_used)s"
                        ) % {"value": value, "key": key, "quota_used": quota_used}
                        raise webob.exc.HTTPBadRequest(explanation=msg)

            minimum = settable_quotas[key]["minimum"]
            maximum = settable_quotas[key]["maximum"]
            self._validate_quota_limit(value, minimum, maximum)
            try:
                db.quota_create(context, project_id, key, value, user_id=user_id)
            except exception.QuotaExists:
                db.quota_update(context, project_id, key, value, user_id=user_id)
            except exception.AdminRequired:
                raise webob.exc.HTTPForbidden()
        return {"quota_set": self._get_quotas(context, id, user_id=user_id)}
Example #49
0
def create(name, memory, vcpus, root_gb, ephemeral_gb=0, flavorid=None, swap=0, rxtx_factor=1.0, is_public=True):
    """Creates flavors."""
    if not flavorid:
        flavorid = uuid.uuid4()

    kwargs = {
        "memory_mb": memory,
        "vcpus": vcpus,
        "root_gb": root_gb,
        "ephemeral_gb": ephemeral_gb,
        "swap": swap,
        "rxtx_factor": rxtx_factor,
    }

    # ensure name do not exceed 255 characters
    utils.check_string_length(name, "name", min_length=1, max_length=255)

    # ensure name does not contain any special characters
    invalid_name = INVALID_NAME_REGEX.search(name)
    if invalid_name:
        msg = _("names can only contain [a-zA-Z0-9_.- ]")
        raise exception.InvalidInput(reason=msg)

    # Some attributes are positive ( > 0) integers
    for option in ["memory_mb", "vcpus"]:
        try:
            assert int(str(kwargs[option])) > 0
            kwargs[option] = int(kwargs[option])
        except (ValueError, AssertionError, TypeError):
            msg = _("'%s' argument must be a positive integer") % option
            raise exception.InvalidInput(reason=msg)

    # Some attributes are non-negative ( >= 0) integers
    for option in ["root_gb", "ephemeral_gb", "swap"]:
        try:
            assert int(str(kwargs[option])) >= 0
            kwargs[option] = int(kwargs[option])
        except (ValueError, AssertionError, TypeError):
            msg = _("'%s' argument must be an integer greater than or" " equal to 0") % option
            raise exception.InvalidInput(reason=msg)

    # rxtx_factor should be a positive float
    try:
        kwargs["rxtx_factor"] = float(kwargs["rxtx_factor"])
        assert kwargs["rxtx_factor"] > 0
    except (ValueError, AssertionError):
        msg = _("'rxtx_factor' argument must be a positive float")
        raise exception.InvalidInput(reason=msg)

    kwargs["name"] = name
    # NOTE(vish): Internally, flavorid is stored as a string but it comes
    #             in through json as an integer, so we convert it here.
    kwargs["flavorid"] = unicode(flavorid)

    # ensure is_public attribute is boolean
    try:
        kwargs["is_public"] = strutils.bool_from_string(is_public, strict=True)
    except ValueError:
        raise exception.InvalidInput(reason=_("is_public must be a boolean"))

    try:
        return db.instance_type_create(context.get_admin_context(), kwargs)
    except db_exc.DBError as e:
        LOG.exception(_("DB error: %s") % e)
        raise exception.InstanceTypeCreateFailed()
Example #50
0
    def update(self, req, id, body):
        context = req.environ['nova.context']
        authorize_update(context)
        project_id = id
        params = urlparse.parse_qs(req.environ.get('QUERY_STRING', ''))
        user_id = params.get('user_id', [None])[0]

        bad_keys = []
        force_update = False

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

        for key, value in quota_set.items():
            if ((key not in QUOTAS or key in FILTERED_QUOTAS)
                 and key != 'force'):
                bad_keys.append(key)
                continue
            if key == 'force':
                force_update = strutils.bool_from_string(value)
            elif key != 'force' and value:
                try:
                    value = utils.validate_integer(
                        value, key)
                except exception.InvalidInput as e:
                    LOG.warn(e.format_message())
                    raise webob.exc.HTTPBadRequest(
                        explanation=e.format_message())

        if len(bad_keys) > 0:
            msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            settable_quotas = QUOTAS.get_settable_quotas(context, project_id,
                                                         user_id=user_id)
        except exception.Forbidden:
            raise webob.exc.HTTPForbidden()

        try:
            quotas = self._get_quotas(context, id, user_id=user_id,
                                      usages=True)
        except exception.Forbidden:
            raise webob.exc.HTTPForbidden()

        LOG.debug("Force update quotas: %s", force_update)

        for key, value in body['quota_set'].iteritems():
            if key == 'force' or (not value and value != 0):
                continue
            # validate whether already used and reserved exceeds the new
            # quota, this check will be ignored if admin want to force
            # update
            value = int(value)
            if force_update is not True and value >= 0:
                quota_value = quotas.get(key)
                if quota_value and quota_value['limit'] >= 0:
                    quota_used = (quota_value['in_use'] +
                                  quota_value['reserved'])
                    LOG.debug("Quota %(key)s used: %(quota_used)s, "
                              "value: %(value)s.",
                              {'key': key, 'quota_used': quota_used,
                               'value': value})
                    if quota_used > value:
                        msg = (_("Quota value %(value)s for %(key)s are "
                                "less than already used and reserved "
                                "%(quota_used)s") %
                                {'value': value, 'key': key,
                                 'quota_used': quota_used})
                        raise webob.exc.HTTPBadRequest(explanation=msg)

            minimum = settable_quotas[key]['minimum']
            maximum = settable_quotas[key]['maximum']
            self._validate_quota_limit(value, minimum, maximum)
            try:
                db.quota_create(context, project_id, key, value,
                                user_id=user_id)
            except exception.QuotaExists:
                db.quota_update(context, project_id, key, value,
                                user_id=user_id)
            except exception.AdminRequired:
                raise webob.exc.HTTPForbidden()
        return self._format_quota_set(id, self._get_quotas(context, id,
                                                           user_id=user_id))
Example #51
0
File: agent.py Project: hoomri/nova
 def _get_sys_meta_key(self, key):
     sys_meta = utils.instance_sys_meta(self.instance)
     raw_value = sys_meta.get(key, 'False')
     return strutils.bool_from_string(raw_value, strict=False)
Example #52
0
    def update(self, req, id, body):
        context = req.environ['nova.context']
        authorize_update(context)
        project_id = id

        bad_keys = []

        # By default, we can force update the quota if the extended
        # is not loaded
        force_update = True
        extended_loaded = False
        if self.ext_mgr.is_loaded('os-extended-quotas'):
            # force optional has been enabled, the default value of
            # force_update need to be changed to False
            extended_loaded = True
            force_update = False

        user_id = None
        if self.ext_mgr.is_loaded('os-user-quotas'):
            # Update user quotas only if the extended is loaded
            params = urlparse.parse_qs(req.environ.get('QUERY_STRING', ''))
            user_id = params.get('user_id', [None])[0]

        try:
            settable_quotas = QUOTAS.get_settable_quotas(context,
                                                         project_id,
                                                         user_id=user_id)
        except exception.Forbidden:
            raise webob.exc.HTTPForbidden()

        if not self.is_valid_body(body, 'quota_set'):
            msg = _("quota_set not specified")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        quota_set = body['quota_set']
        for key, value in quota_set.items():
            if (key not in QUOTAS and key not in NON_QUOTA_KEYS):
                bad_keys.append(key)
                continue
            if key == 'force' and extended_loaded:
                # only check the force optional when the extended has
                # been loaded
                force_update = strutils.bool_from_string(value)
            elif key not in NON_QUOTA_KEYS and value:
                try:
                    value = utils.validate_integer(value, key)
                except exception.InvalidInput as e:
                    raise webob.exc.HTTPBadRequest(
                        explanation=e.format_message())

        LOG.debug("force update quotas: %s", force_update)

        if len(bad_keys) > 0:
            msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            quotas = self._get_quotas(context,
                                      id,
                                      user_id=user_id,
                                      usages=True)
        except exception.Forbidden:
            raise webob.exc.HTTPForbidden()

        for key, value in quota_set.items():
            if key in NON_QUOTA_KEYS or (not value and value != 0):
                continue
            # validate whether already used and reserved exceeds the new
            # quota, this check will be ignored if admin want to force
            # update
            value = int(value)
            if force_update is not True and value >= 0:
                quota_value = quotas.get(key)
                if quota_value and quota_value['limit'] >= 0:
                    quota_used = (quota_value['in_use'] +
                                  quota_value['reserved'])
                    LOG.debug(
                        "Quota %(key)s used: %(quota_used)s, "
                        "value: %(value)s.", {
                            'key': key,
                            'quota_used': quota_used,
                            'value': value
                        })
                    if quota_used > value:
                        msg = (_("Quota value %(value)s for %(key)s are "
                                 "less than already used and reserved "
                                 "%(quota_used)s") % {
                                     'value': value,
                                     'key': key,
                                     'quota_used': quota_used
                                 })
                        raise webob.exc.HTTPBadRequest(explanation=msg)

            minimum = settable_quotas[key]['minimum']
            maximum = settable_quotas[key]['maximum']
            self._validate_quota_limit(value, minimum, maximum)
            try:
                db.quota_create(context,
                                project_id,
                                key,
                                value,
                                user_id=user_id)
            except exception.QuotaExists:
                db.quota_update(context,
                                project_id,
                                key,
                                value,
                                user_id=user_id)
            except exception.AdminRequired:
                raise webob.exc.HTTPForbidden()
        return {'quota_set': self._get_quotas(context, id, user_id=user_id)}
Example #53
0
def required_by(instance):
    return (instance.get('config_drive') or
            'always' == CONF.force_config_drive or
            strutils.bool_from_string(CONF.force_config_drive))
Example #54
0
    def _get_servers(self, req, is_detail):
        """Returns a list of servers, based on any search options specified."""

        search_opts = {}
        search_opts.update(req.GET)

        context = req.environ['nova.context']
        remove_invalid_options(context, search_opts,
                               self._get_server_search_options())

        # Verify search by 'status' contains a valid status.
        # Convert it to filter by vm_state or task_state for compute_api.
        status = search_opts.pop('status', None)
        if status is not None:
            vm_state, task_state = common.task_and_vm_state_from_status(status)
            if not vm_state and not task_state:
                return {'servers': []}
            search_opts['vm_state'] = vm_state
            # When we search by vm state, task state will return 'default'.
            # So we don't need task_state search_opt.
            if 'default' not in task_state:
                search_opts['task_state'] = task_state

        if 'changes_since' in search_opts:
            try:
                parsed = timeutils.parse_isotime(search_opts['changes_since'])
            except ValueError:
                msg = _('Invalid changes_since value')
                raise exc.HTTPBadRequest(explanation=msg)
            search_opts['changes_since'] = parsed

        # By default, compute's get_all() will return deleted instances.
        # If an admin hasn't specified a 'deleted' search option, we need
        # to filter out deleted instances by setting the filter ourselves.
        # ... Unless 'changes_since' is specified, because 'changes_since'
        # should return recently deleted images according to the API spec.

        if 'deleted' not in search_opts:
            if 'changes_since' not in search_opts:
                # No 'changes_since', so we only want non-deleted servers
                search_opts['deleted'] = False

        if 'changes_since' in search_opts:
            search_opts['changes-since'] = search_opts.pop('changes_since')

        if search_opts.get("vm_state") == ['deleted']:
            if context.is_admin:
                search_opts['deleted'] = True
            else:
                msg = _("Only administrators may list deleted instances")
                raise exc.HTTPBadRequest(explanation=msg)

        # If tenant_id is passed as a search parameter this should
        # imply that all_tenants is also enabled unless explicitly
        # disabled. Note that the tenant_id parameter is filtered out
        # by remove_invalid_options above unless the requestor is an
        # admin.
        if 'tenant_id' in search_opts and not 'all_tenants' in search_opts:
            # We do not need to add the all_tenants flag if the tenant
            # id associated with the token is the tenant id
            # specified. This is done so a request that does not need
            # the all_tenants flag does not fail because of lack of
            # policy permission for compute:get_all_tenants when it
            # doesn't actually need it.
            if context.project_id != search_opts.get('tenant_id'):
                search_opts['all_tenants'] = 1

        # If all tenants is passed with 0 or false as the value
        # then remove it from the search options. Nothing passed as
        # the value for all_tenants is considered to enable the feature
        all_tenants = search_opts.get('all_tenants')
        if all_tenants:
            try:
                if not strutils.bool_from_string(all_tenants, True):
                    del search_opts['all_tenants']
            except ValueError as err:
                raise exception.InvalidInput(str(err))

        if 'all_tenants' in search_opts:
            policy.enforce(context, 'compute:get_all_tenants', {
                'project_id': context.project_id,
                'user_id': context.user_id
            })
            del search_opts['all_tenants']
        else:
            if context.project_id:
                search_opts['project_id'] = context.project_id
            else:
                search_opts['user_id'] = context.user_id

        limit, marker = common.get_limit_and_marker(req)
        try:
            instance_list = self.compute_api.get_all(
                context,
                search_opts=search_opts,
                limit=limit,
                marker=marker,
                want_objects=True,
                expected_attrs=['pci_devices'])
        except exception.MarkerNotFound:
            msg = _('marker [%s] not found') % marker
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.FlavorNotFound:
            log_msg = _("Flavor '%s' could not be found ")
            LOG.debug(log_msg, search_opts['flavor'])
            instance_list = []

        if is_detail:
            instance_list.fill_faults()
            response = self._view_builder.detail(req, instance_list)
        else:
            response = self._view_builder.index(req, instance_list)
        req.cache_db_instances(instance_list)
        return response
Example #55
0
    def _get_servers(self, req, is_detail):
        """Returns a list of servers, based on any search options specified."""

        search_opts = {}
        search_opts.update(req.GET)

        context = req.environ['nova.context']
        remove_invalid_options(context, search_opts,
                self._get_server_search_options())

        # Verify search by 'status' contains a valid status.
        # Convert it to filter by vm_state or task_state for compute_api.
        status = search_opts.pop('status', None)
        if status is not None:
            vm_state, task_state = common.task_and_vm_state_from_status(status)
            if not vm_state and not task_state:
                return {'servers': []}
            search_opts['vm_state'] = vm_state
            # When we search by vm state, task state will return 'default'.
            # So we don't need task_state search_opt.
            if 'default' not in task_state:
                search_opts['task_state'] = task_state

        if 'changes_since' in search_opts:
            try:
                parsed = timeutils.parse_isotime(search_opts['changes_since'])
            except ValueError:
                msg = _('Invalid changes_since value')
                raise exc.HTTPBadRequest(explanation=msg)
            search_opts['changes_since'] = parsed

        # By default, compute's get_all() will return deleted instances.
        # If an admin hasn't specified a 'deleted' search option, we need
        # to filter out deleted instances by setting the filter ourselves.
        # ... Unless 'changes_since' is specified, because 'changes_since'
        # should return recently deleted images according to the API spec.

        if 'deleted' not in search_opts:
            if 'changes_since' not in search_opts:
                # No 'changes_since', so we only want non-deleted servers
                search_opts['deleted'] = False

        if 'changes_since' in search_opts:
            search_opts['changes-since'] = search_opts.pop('changes_since')

        if search_opts.get("vm_state") == ['deleted']:
            if context.is_admin:
                search_opts['deleted'] = True
            else:
                msg = _("Only administrators may list deleted instances")
                raise exc.HTTPBadRequest(explanation=msg)

        # If tenant_id is passed as a search parameter this should
        # imply that all_tenants is also enabled unless explicitly
        # disabled. Note that the tenant_id parameter is filtered out
        # by remove_invalid_options above unless the requestor is an
        # admin.
        if 'tenant_id' in search_opts and not 'all_tenants' in search_opts:
            # We do not need to add the all_tenants flag if the tenant
            # id associated with the token is the tenant id
            # specified. This is done so a request that does not need
            # the all_tenants flag does not fail because of lack of
            # policy permission for compute:get_all_tenants when it
            # doesn't actually need it.
            if context.project_id != search_opts.get('tenant_id'):
                search_opts['all_tenants'] = 1

        # If all tenants is passed with 0 or false as the value
        # then remove it from the search options. Nothing passed as
        # the value for all_tenants is considered to enable the feature
        all_tenants = search_opts.get('all_tenants')
        if all_tenants:
            try:
                if not strutils.bool_from_string(all_tenants, True):
                    del search_opts['all_tenants']
            except ValueError as err:
                raise exception.InvalidInput(str(err))

        if 'all_tenants' in search_opts:
            policy.enforce(context, 'compute:get_all_tenants',
                           {'project_id': context.project_id,
                            'user_id': context.user_id})
            del search_opts['all_tenants']
        else:
            if context.project_id:
                search_opts['project_id'] = context.project_id
            else:
                search_opts['user_id'] = context.user_id

        limit, marker = common.get_limit_and_marker(req)
        try:
            instance_list = self.compute_api.get_all(context,
                    search_opts=search_opts, limit=limit, marker=marker,
                    want_objects=True, expected_attrs=['pci_devices'])
        except exception.MarkerNotFound:
            msg = _('marker [%s] not found') % marker
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.FlavorNotFound:
            log_msg = _("Flavor '%s' could not be found ")
            LOG.debug(log_msg, search_opts['flavor'])
            instance_list = []

        if is_detail:
            instance_list.fill_faults()
            response = self._view_builder.detail(req, instance_list)
        else:
            response = self._view_builder.index(req, instance_list)
        req.cache_db_instances(instance_list)
        return response
Example #56
0
    def _action_rebuild(self, req, id, body):
        """Rebuild an instance with the given attributes."""
        try:
            rebuild_dict = body['rebuild']
        except (KeyError, TypeError):
            msg = _('Invalid request body')
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            image_href = rebuild_dict["image_ref"]
        except (KeyError, TypeError):
            msg = _("Could not parse image_ref from request.")
            raise exc.HTTPBadRequest(explanation=msg)

        image_href = self._image_uuid_from_href(image_href)

        password = self._get_server_admin_password(rebuild_dict)

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

        attr_map = {
            'name': 'display_name',
            'metadata': 'metadata',
        }

        rebuild_kwargs = {}

        if 'name' in rebuild_dict:
            self._validate_server_name(rebuild_dict['name'])

        if 'preserve_ephemeral' in rebuild_dict:
            rebuild_kwargs['preserve_ephemeral'] = strutils.bool_from_string(
                rebuild_dict['preserve_ephemeral'], strict=True)

        if list(self.rebuild_extension_manager):
            self.rebuild_extension_manager.map(self._rebuild_extension_point,
                                               rebuild_dict, rebuild_kwargs)

        for request_attribute, instance_attribute in attr_map.items():
            try:
                rebuild_kwargs[instance_attribute] = rebuild_dict[
                    request_attribute]
            except (KeyError, TypeError):
                pass

        try:
            self.compute_api.rebuild(context, instance, image_href, password,
                                     **rebuild_kwargs)
        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, 'rebuild')
        except exception.InstanceNotFound:
            msg = _("Instance could not be found")
            raise exc.HTTPNotFound(explanation=msg)
        except exception.InvalidMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message())
        except exception.ImageNotFound:
            msg = _("Cannot find image for rebuild")
            raise exc.HTTPBadRequest(explanation=msg)
        except (exception.ImageNotActive, exception.FlavorDiskTooSmall,
                exception.FlavorMemoryTooSmall,
                exception.InvalidMetadata) as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

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

        view = self._view_builder.show(req, instance)

        # Add on the admin_password attribute since the view doesn't do it
        # unless instance passwords are disabled
        if CONF.enable_instance_password:
            view['server']['admin_password'] = password

        robj = wsgi.ResponseObject(view)
        return self._add_location(robj)
Example #57
0
def create(name, memory, vcpus, root_gb, ephemeral_gb=0, flavorid=None,
           swap=0, rxtx_factor=1.0, is_public=True):
    """Creates flavors."""
    if not flavorid:
        flavorid = uuid.uuid4()

    kwargs = {
        'memory_mb': memory,
        'vcpus': vcpus,
        'root_gb': root_gb,
        'ephemeral_gb': ephemeral_gb,
        'swap': swap,
        'rxtx_factor': rxtx_factor,
    }

    # ensure name do not exceed 255 characters
    utils.check_string_length(name, 'name', min_length=1, max_length=255)

    # ensure name does not contain any special characters
    valid_name = VALID_NAME_OR_ID_REGEX.search(name)
    if not valid_name:
        msg = _("names can only contain [a-zA-Z0-9_.- ]")
        raise exception.InvalidInput(reason=msg)

    # NOTE(vish): Internally, flavorid is stored as a string but it comes
    #             in through json as an integer, so we convert it here.
    flavorid = unicode(flavorid)

    # ensure leading/trailing whitespaces not present.
    if flavorid.strip() != flavorid:
        msg = _("id cannot contain leading and/or trailing whitespace(s)")
        raise exception.InvalidInput(reason=msg)

    # ensure flavor id does not exceed 255 characters
    utils.check_string_length(flavorid, 'id', min_length=1,
                              max_length=255)

    # ensure flavor id does not contain any special characters
    valid_flavor_id = VALID_NAME_OR_ID_REGEX.search(flavorid)
    if not valid_flavor_id:
        msg = _("id can only contain [a-zA-Z0-9_.- ]")
        raise exception.InvalidInput(reason=msg)

    # Some attributes are positive ( > 0) integers
    for option in ['memory_mb', 'vcpus']:
        kwargs[option] = utils.validate_integer(kwargs[option], option, 1,
                                                sys.maxint)

    # Some attributes are non-negative ( >= 0) integers
    for option in ['root_gb', 'ephemeral_gb', 'swap']:
        kwargs[option] = utils.validate_integer(kwargs[option], option, 0,
                                                sys.maxint)

    # rxtx_factor should be a positive float
    try:
        kwargs['rxtx_factor'] = float(kwargs['rxtx_factor'])
        if kwargs['rxtx_factor'] <= 0:
            raise ValueError()
    except ValueError:
        msg = _("'rxtx_factor' argument must be a positive float")
        raise exception.InvalidInput(reason=msg)

    kwargs['name'] = name
    kwargs['flavorid'] = flavorid
    # ensure is_public attribute is boolean
    try:
        kwargs['is_public'] = strutils.bool_from_string(
            is_public, strict=True)
    except ValueError:
        raise exception.InvalidInput(reason=_("is_public must be a boolean"))

    try:
        return db.flavor_create(context.get_admin_context(), kwargs)
    except db_exc.DBError as e:
        LOG.exception(_('DB error: %s') % e)
        raise exception.InstanceTypeCreateFailed()
Example #58
0
def create(name, memory, vcpus, root_gb, ephemeral_gb=0, flavorid=None,
           swap=0, rxtx_factor=1.0, is_public=True):
    """Creates flavors."""
    if not flavorid:
        flavorid = uuid.uuid4()

    kwargs = {
        'memory_mb': memory,
        'vcpus': vcpus,
        'root_gb': root_gb,
        'ephemeral_gb': ephemeral_gb,
        'swap': swap,
        'rxtx_factor': rxtx_factor,
    }

    if isinstance(name, six.string_types):
        name = name.strip()
    # ensure name do not exceed 255 characters
    utils.check_string_length(name, 'name', min_length=1, max_length=255)

    # ensure name does not contain any special characters
    valid_name = VALID_NAME_OR_ID_REGEX.search(name)
    if not valid_name:
        msg = _("names can only contain [a-zA-Z0-9_.- ]")
        raise exception.InvalidInput(reason=msg)

    # NOTE(vish): Internally, flavorid is stored as a string but it comes
    #             in through json as an integer, so we convert it here.
    flavorid = unicode(flavorid)

    # ensure leading/trailing whitespaces not present.
    if flavorid.strip() != flavorid:
        msg = _("id cannot contain leading and/or trailing whitespace(s)")
        raise exception.InvalidInput(reason=msg)

    # ensure flavor id does not exceed 255 characters
    utils.check_string_length(flavorid, 'id', min_length=1,
                              max_length=255)

    # ensure flavor id does not contain any special characters
    valid_flavor_id = VALID_NAME_OR_ID_REGEX.search(flavorid)
    if not valid_flavor_id:
        msg = _("id can only contain [a-zA-Z0-9_.- ]")
        raise exception.InvalidInput(reason=msg)

    # Some attributes are positive ( > 0) integers
    for option in ['memory_mb', 'vcpus']:
        kwargs[option] = utils.validate_integer(kwargs[option], option, 1,
                                                sys.maxint)

    # Some attributes are non-negative ( >= 0) integers
    for option in ['root_gb', 'ephemeral_gb', 'swap']:
        kwargs[option] = utils.validate_integer(kwargs[option], option, 0,
                                                sys.maxint)

    # rxtx_factor should be a positive float
    try:
        kwargs['rxtx_factor'] = float(kwargs['rxtx_factor'])
        if kwargs['rxtx_factor'] <= 0:
            raise ValueError()
    except ValueError:
        msg = _("'rxtx_factor' argument must be a positive float")
        raise exception.InvalidInput(reason=msg)

    kwargs['name'] = name
    kwargs['flavorid'] = flavorid
    # ensure is_public attribute is boolean
    try:
        kwargs['is_public'] = strutils.bool_from_string(
            is_public, strict=True)
    except ValueError:
        raise exception.InvalidInput(reason=_("is_public must be a boolean"))

    try:
        return db.flavor_create(context.get_admin_context(), kwargs)
    except db_exc.DBError as e:
        LOG.exception(_('DB error: %s') % e)
        raise exception.InstanceTypeCreateFailed()