Esempio n. 1
0
    def _volume_upload_image(self, req, id, body):
        """Uploads the specified volume to image service."""
        context = req.environ['cinder.context']
        params = body['os-volume_upload_image']
        req_version = req.api_version_request

        force = params.get('force', 'False')
        force = strutils.bool_from_string(force, strict=True)

        # Not found exception will be handled at the wsgi level
        volume = self.volume_api.get(context, id)

        context.authorize(policy.UPLOAD_IMAGE_POLICY)
        # check for valid disk-format
        disk_format = params.get("disk_format", "raw")

        image_metadata = {"container_format": params.get(
            "container_format", "bare"),
            "disk_format": disk_format,
            "name": params["image_name"]}

        if volume.encryption_key_id:
            # Clone volume encryption key: the current key cannot
            # be reused because it will be deleted when the volume is
            # deleted.
            # TODO(eharney): Currently, there is no mechanism to remove
            # these keys, because Glance will not delete the key from
            # Barbican when the image is deleted.
            encryption_key_id = self._key_manager.store(
                context,
                self._key_manager.get(context, volume.encryption_key_id))

            image_metadata['cinder_encryption_key_id'] = encryption_key_id

        if req_version >= mv.get_api_version(
                mv.UPLOAD_IMAGE_PARAMS):

            image_metadata['visibility'] = params.get('visibility', 'private')
            image_metadata['protected'] = strutils.bool_from_string(
                params.get('protected', 'False'), strict=True)

            if image_metadata['visibility'] == 'public':
                context.authorize(policy.UPLOAD_PUBLIC_POLICY)

        try:
            response = self.volume_api.copy_volume_to_image(context,
                                                            volume,
                                                            image_metadata,
                                                            force)
        except exception.InvalidVolume as error:
            raise webob.exc.HTTPBadRequest(explanation=error.msg)
        except ValueError as error:
            raise webob.exc.HTTPBadRequest(explanation=six.text_type(error))
        except messaging.RemoteError as error:
            msg = "%(err_type)s: %(err_msg)s" % {'err_type': error.exc_type,
                                                 'err_msg': error.value}
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except Exception as error:
            raise webob.exc.HTTPBadRequest(explanation=six.text_type(error))
        return {'os-volume_upload_image': response}
Esempio n. 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, action='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)
            self.compute_api.live_migrate(context, instance, block_migration,
                                          disk_over_commit, host)
        except (exception.NoValidHost,
                exception.ComputeServiceUnavailable,
                exception.InvalidHypervisorType,
                exception.InvalidCPUInfo,
                exception.UnableToMigrateToSelf,
                exception.DestinationHypervisorTooOld,
                exception.InvalidLocalStorage,
                exception.InvalidSharedStorage,
                exception.HypervisorUnavailable,
                exception.MigrationPreCheckError,
                exception.LiveMigrationWithOldNovaNotSafe) as ex:
            raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'os-migrateLive', id)
Esempio n. 3
0
    def update_host(self, context, segment_uuid, id, host_data):
        """Update the host"""
        segment = objects.FailoverSegment.get_by_uuid(context, segment_uuid)

        host = objects.Host.get_by_uuid(context, id)

        if is_failover_segment_under_recovery(segment):
            msg = _("Host %s can't be updated as "
                    "it is in-use to process notifications.") % host.uuid
            LOG.error(msg)
            raise exception.HostInUse(msg)

        if 'name' in host_data:
            self._is_valid_host_name(context, host_data.get('name'))

        if 'on_maintenance' in host_data:
            host_data['on_maintenance'] = strutils.bool_from_string(
                host_data['on_maintenance'], strict=True)
        if 'reserved' in host_data:
            host_data['reserved'] = strutils.bool_from_string(
                host_data['reserved'], strict=True)

        try:
            host.update(host_data)
            host.save()
        except Exception as e:
            with excutils.save_and_reraise_exception():
                tb = traceback.format_exc()
                api_utils.notify_about_host_api(context, host,
                    action=fields.EventNotificationAction.HOST_UPDATE,
                    phase=fields.EventNotificationPhase.ERROR, exception=e,
                    tb=tb)
        return host
Esempio n. 4
0
    def create_host(self, context, segment_uuid, host_data):
        """Create host"""
        segment = objects.FailoverSegment.get_by_uuid(context, segment_uuid)
        host = objects.Host(context=context)

        # Populate host object for create
        host.name = host_data.get('name')
        host.failover_segment_id = segment.uuid
        host.type = host_data.get('type')
        host.control_attributes = host_data.get('control_attributes')
        host.on_maintenance = strutils.bool_from_string(
            host_data.get('on_maintenance', False), strict=True)
        host.reserved = strutils.bool_from_string(
            host_data.get('reserved', False), strict=True)

        self._is_valid_host_name(context, host.name)

        try:
            host.create()
        except Exception as e:
            with excutils.save_and_reraise_exception():
                tb = traceback.format_exc()
                api_utils.notify_about_host_api(context, host,
                    action=fields.EventNotificationAction.HOST_CREATE,
                    phase=fields.EventNotificationPhase.ERROR, exception=e,
                    tb=tb)

        return host
Esempio n. 5
0
def get_headers(req):
    kwargs = {}

    # TODO(vkmc) We should add a control here to make sure
    # that the headers/request combination is possible
    # e.g. we cannot have messages_post with grace

    if req._body.get('marker') is not None:
        kwargs['marker'] = req._body.get('marker')

    if req._body.get('limit') is not None:
        kwargs['limit'] = int(req._body.get('limit'))

    if req._body.get('detailed') is not None:
        kwargs['detailed'] = strutils.bool_from_string(
            req._body.get('detailed'))

    if req._body.get('echo') is not None:
        kwargs['echo'] = strutils.bool_from_string(req._body.get('echo'))

    if req._body.get('include_claimed') is not None:
        kwargs['include_claimed'] = strutils.bool_from_string(
            req._body.get('include_claimed'))

    if req._body.get('ttl') is not None:
        kwargs['ttl'] = int(req._body.get('ttl'))

    if req._body.get('grace') is not None:
        kwargs['grace'] = int(req._body.get('grace'))

    return kwargs
Esempio n. 6
0
 def _validate_type(self, attrib, value):
     if attrib.schema.type == attrib.schema.STRING:
         if not isinstance(value, six.string_types):
             LOG.warning(_LW("Attribute %(name)s is not of type "
                             "%(att_type)s"),
                         {'name': attrib.name,
                          'att_type': attrib.schema.STRING})
     elif attrib.schema.type == attrib.schema.LIST:
         if (not isinstance(value, collections.Sequence)
                 or isinstance(value, six.string_types)):
             LOG.warning(_LW("Attribute %(name)s is not of type "
                             "%(att_type)s"),
                         {'name': attrib.name,
                          'att_type': attrib.schema.LIST})
     elif attrib.schema.type == attrib.schema.MAP:
         if not isinstance(value, collections.Mapping):
             LOG.warning(_LW("Attribute %(name)s is not of type "
                             "%(att_type)s"),
                         {'name': attrib.name,
                          'att_type': attrib.schema.MAP})
     elif attrib.schema.type == attrib.schema.INTEGER:
         if not isinstance(value, int):
             LOG.warning(_LW("Attribute %(name)s is not of type "
                             "%(att_type)s"),
                         {'name': attrib.name,
                          'att_type': attrib.schema.INTEGER})
     elif attrib.schema.type == attrib.schema.BOOLEAN:
         try:
             strutils.bool_from_string(value, strict=True)
         except ValueError:
             LOG.warning(_LW("Attribute %(name)s is not of type "
                             "%(att_type)s"),
                         {'name': attrib.name,
                          'att_type': attrib.schema.BOOLEAN})
Esempio n. 7
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', id)
        except Exception:
            if host is None:
                msg = _("Live migration of instance %s to another host "
                        "failed") % id
            else:
                msg = _("Live migration of instance %(id)s to host %(host)s "
                        "failed") % {'id': id, 'host': host}
            LOG.exception(msg)
            # Return messages from scheduler
            raise exc.HTTPInternalServerError(explanation=msg)

        return webob.Response(status_int=202)
Esempio n. 8
0
 def __init__(self, runtime):
     self._runtime = weakref.proxy(runtime)
     self._storage = runtime.storage
     self._undefined_resolver = RevertAll(self._runtime)
     self._defer_reverts = strutils.bool_from_string(
         self._runtime.options.get('defer_reverts', False))
     self._resolve = not strutils.bool_from_string(
         self._runtime.options.get('never_resolve', False))
Esempio n. 9
0
        def evaluate_pool(pool):
            try:
                pool_attributes = pool.attributes.to_dict()
            except exceptions.RelationNotLoaded:
                pool_attributes = {}

            # Remove the "pool_id" attribute, that is used in
            # PoolIDAttributeFilter. If the item is not in the dict, it is
            # fine, we should just continue.
            pool_attributes.pop('pool_id', None)

            if pool_attributes == {}:
                # If we did not send any attribute to filter on, we should
                # not filter the pools based on an empty set, as this will
                # return no pools.
                return True

            # Check if the keys requested exist in this pool
            if not {key for key in six.iterkeys(pool_attributes)}.issuperset(
                    zone_attributes):
                msg = "%(pool)s did not match list of requested attribute "\
                      "keys - removing from list. Requested: %(r_key)s. Pool:"\
                      "%(p_key)s"

                LOG.debug(
                    msg,
                    {
                        'pool': pool,
                        'r_key': zone_attributes,
                        'p_key': pool_attributes
                    }
                )
                # Missing required keys - remove from the list
                return False

            for key in six.iterkeys(zone_attributes):
                LOG.debug("Checking value of %s for %s", key, pool)

                pool_attr = bool_from_string(pool_attributes[key],
                                             default=pool_attributes[key])
                zone_attr = bool_from_string(zone_attributes[key],
                                             default=zone_attributes[key])

                if not pool_attr == zone_attr:
                    LOG.debug(
                        "%(pool)s did not match requested value of %(key)s. "
                        "Requested: %(r_val)s. Pool: %(p_val)s",
                        {
                            'pool': pool,
                            'key': key,
                            'r_val': zone_attr,
                            'p_val': pool_attr
                        })
                    # Value didn't match - remove from the list
                    return False

            # Pool matches list of attributes - keep
            return True
Esempio n. 10
0
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["nova.context"]
        context.can(ms_policies.POLICY_ROOT % 'migrate_live')

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

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

        instance = common.get_instance(self.compute_api, context, id)
        try:
            self.compute_api.live_migrate(context, instance, block_migration,
                                          disk_over_commit, host, force,
                                          async_)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.NoValidHost,
                exception.ComputeServiceUnavailable,
                exception.InvalidHypervisorType,
                exception.InvalidCPUInfo,
                exception.UnableToMigrateToSelf,
                exception.DestinationHypervisorTooOld,
                exception.InvalidLocalStorage,
                exception.InvalidSharedStorage,
                exception.HypervisorUnavailable,
                exception.MigrationPreCheckError) as ex:
            if async_:
                with excutils.save_and_reraise_exception():
                    LOG.error("Unexpected exception received from "
                              "conductor during pre-live-migration checks "
                              "'%(ex)s'", {'ex': ex})
            else:
                raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.ComputeHostNotFound as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'os-migrateLive', id)
Esempio n. 11
0
 def _extract_edit_managed_records(self, ctxt, request):
     ctxt.edit_managed_records = False
     if 'edit_managed_records' in request.GET:
         value = request.GET.pop('edit_managed_records')
         ctxt.edit_managed_records = strutils.bool_from_string(value)
     elif request.headers.get('X-Designate-Edit-Managed-Records'):
         ctxt.edit_managed_records = \
             strutils.bool_from_string(
                 request.headers.get('X-Designate-Edit-Managed-Records'))
Esempio n. 12
0
    def _extract_all_projects(self, ctxt, request):
        ctxt.all_tenants = False
        if request.headers.get('X-Auth-All-Projects'):
            value = request.headers.get('X-Auth-All-Projects')
            ctxt.all_tenants = strutils.bool_from_string(value)

        for i in ('all_projects', 'all_tenants', ):
            if i in request.GET:
                value = request.GET.pop(i)
                ctxt.all_tenants = strutils.bool_from_string(value)
Esempio n. 13
0
    def index(self, req, segment_id):
        """Returns a list a hosts."""
        context = req.environ['masakari.context']
        authorize(context)

        try:
            filters = {}
            limit, marker = common.get_limit_and_marker(req)
            sort_keys, sort_dirs = common.get_sort_params(req.params)

            segment = objects.FailoverSegment.get_by_uuid(context,
                                                          segment_id)

            filters['failover_segment_id'] = segment.uuid
            if 'name' in req.params:
                filters['name'] = req.params['name']

            if 'type' in req.params:
                filters['type'] = req.params['type']

            if 'control_attributes' in req.params:
                filters['control_attributes'] = req.params[
                    'control_attributes']

            if 'on_maintenance' in req.params:
                try:
                    filters['on_maintenance'] = strutils.bool_from_string(
                        req.params['on_maintenance'], strict=True)
                except ValueError as ex:
                    msg = _("Invalid value for on_maintenance: "
                            "%s") % encodeutils.exception_to_unicode(ex)
                    raise exc.HTTPBadRequest(explanation=msg)

            if 'reserved' in req.params:
                try:
                    filters['reserved'] = strutils.bool_from_string(
                        req.params['reserved'], strict=True)
                except ValueError as ex:
                    msg = _("Invalid value for reserved: "
                            "%s") % encodeutils.exception_to_unicode(ex)
                    raise exc.HTTPBadRequest(explanation=msg)

            hosts = self.api.get_all(context, filters=filters,
                                     sort_keys=sort_keys, sort_dirs=sort_dirs,
                                     limit=limit, marker=marker)
        except exception.MarkerNotFound as ex:
            raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.Invalid as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        except exception.FailoverSegmentNotFound as ex:
            raise exc.HTTPNotFound(explanation=ex.format_message())

        return {'hosts': hosts}
Esempio n. 14
0
    def setUp(self):
        super(BaseTestCase, self).setUp()
        self.useFixture(fixtures.FakeLogger())

        # If enabled, stdout and/or stderr is captured and will appear in
        # test results if that test fails.
        if strutils.bool_from_string(os.environ.get('OS_STDOUT_CAPTURE')):
            stdout = self.useFixture(fixtures.StringStream('stdout')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
        if strutils.bool_from_string(os.environ.get('OS_STDERR_CAPTURE')):
            stderr = self.useFixture(fixtures.StringStream('stderr')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
Esempio n. 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, action='migrate_live')

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

        if api_version_request.is_supported(req, min_version='2.30'):
            force = body["os-migrateLive"].get("force", False)
            force = strutils.bool_from_string(force, strict=True)
            if force is True and not host:
                message = _("Can't force to a non-provided destination")
                raise exc.HTTPBadRequest(explanation=message)
        if api_version_request.is_supported(req, min_version='2.25'):
            if block_migration == 'auto':
                block_migration = None
            else:
                block_migration = strutils.bool_from_string(block_migration,
                                                            strict=True)
            disk_over_commit = None
        else:
            disk_over_commit = body["os-migrateLive"]["disk_over_commit"]

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

        try:
            instance = common.get_instance(self.compute_api, context, id)
            self.compute_api.live_migrate(context, instance, block_migration,
                                          disk_over_commit, host, force)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.NoValidHost,
                exception.ComputeServiceUnavailable,
                exception.InvalidHypervisorType,
                exception.InvalidCPUInfo,
                exception.UnableToMigrateToSelf,
                exception.DestinationHypervisorTooOld,
                exception.InvalidLocalStorage,
                exception.InvalidSharedStorage,
                exception.HypervisorUnavailable,
                exception.MigrationPreCheckError,
                exception.LiveMigrationWithOldNovaNotSupported) as ex:
            raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'os-migrateLive', id)
Esempio n. 16
0
    def get_replication_config(rep_device_list):
        """Gather necessary replication configuration info.

        :param rep_device_list: the replication device list from cinder.conf
        :returns: rep_config, replication configuration dict
        """
        rep_config = {}
        if not rep_device_list:
            return None
        else:
            target = rep_device_list[0]
            try:
                rep_config['array'] = target['target_device_id']
                rep_config['srp'] = target['remote_pool']
                rep_config['rdf_group_label'] = target['rdf_group_label']
                rep_config['portgroup'] = target['remote_port_group']

            except KeyError as ke:
                error_message = (_("Failed to retrieve all necessary SRDF "
                                   "information. Error received: %(ke)s.") %
                                 {'ke': six.text_type(ke)})
                LOG.exception(error_message)
                raise exception.VolumeBackendAPIException(
                    message=error_message)

            allow_extend = target.get('allow_extend', 'false')
            if strutils.bool_from_string(allow_extend):
                rep_config['allow_extend'] = True
            else:
                rep_config['allow_extend'] = False

            rep_mode = target.get('mode', '')
            if rep_mode.lower() in ['async', 'asynchronous']:
                rep_config['mode'] = REP_ASYNC
            elif rep_mode.lower() == 'metro':
                rep_config['mode'] = REP_METRO
                metro_bias = target.get('metro_use_bias', 'false')
                if strutils.bool_from_string(metro_bias):
                    rep_config[METROBIAS] = True
                else:
                    rep_config[METROBIAS] = False
                allow_delete_metro = target.get('allow_delete_metro', 'false')
                if strutils.bool_from_string(allow_delete_metro):
                    rep_config['allow_delete_metro'] = True
                else:
                    rep_config['allow_delete_metro'] = False
            else:
                rep_config['mode'] = REP_SYNC

        return rep_config
Esempio n. 17
0
    def create(self, req, body):
        """Create a new backup."""
        LOG.debug('Creating new backup %s', body)

        context = req.environ['cinder.context']
        req_version = req.api_version_request

        backup = body['backup']
        container = backup.get('container', None)
        volume_id = backup['volume_id']

        self.validate_name_and_description(backup, check_length=False)
        name = backup.get('name', None)
        description = backup.get('description', None)
        incremental = strutils.bool_from_string(backup.get(
            'incremental', False), strict=True)
        force = strutils.bool_from_string(backup.get(
            'force', False), strict=True)
        snapshot_id = backup.get('snapshot_id', None)
        metadata = backup.get('metadata', None) if req_version.matches(
            mv.BACKUP_METADATA) else None

        if req_version.matches(mv.BACKUP_AZ):
            availability_zone = backup.get('availability_zone', None)
        else:
            availability_zone = None
        az_text = ' in az %s' % availability_zone if availability_zone else ''

        LOG.info("Creating backup of volume %(volume_id)s in container"
                 " %(container)s%(az)s",
                 {'volume_id': volume_id, 'container': container,
                  'az': az_text},
                 context=context)

        try:
            new_backup = self.backup_api.create(context, name, description,
                                                volume_id, container,
                                                incremental, availability_zone,
                                                force, snapshot_id, metadata)
        except (exception.InvalidVolume,
                exception.InvalidSnapshot,
                exception.InvalidVolumeMetadata,
                exception.InvalidVolumeMetadataSize) as error:
            raise exc.HTTPBadRequest(explanation=error.msg)
        # Other not found exceptions will be handled at the wsgi level
        except exception.ServiceNotFound as error:
            raise exc.HTTPServiceUnavailable(explanation=error.msg)

        retval = self._view_builder.summary(req, dict(new_backup))
        return retval
Esempio n. 18
0
    def _validate(self, bdm_dict):
        """Basic data format validations."""
        dict_fields = set(key for key, _ in six.iteritems(bdm_dict))

        # 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."))
Esempio n. 19
0
def validate_public_share_policy(context, api_params, api='create'):
    """Validates if policy allows is_public parameter to be set to True.

    :arg api_params - A dictionary of values that may contain 'is_public'
    :returns api_params with 'is_public' item sanitized if present
    :raises exception.InvalidParameterValue if is_public is set but is Invalid
            exception.NotAuthorized if is_public is True but policy prevents it
    """
    if 'is_public' not in api_params:
        return api_params

    policies = {
        'create': 'create_public_share',
        'update': 'set_public_share',
    }
    policy_to_check = policies[api]
    try:
        api_params['is_public'] = strutils.bool_from_string(
            api_params['is_public'], strict=True)
    except ValueError as e:
        raise exception.InvalidParameterValue(six.text_type(e))

    public_shares_allowed = policy.check_policy(
        context, 'share', policy_to_check, do_raise=False)
    if api_params['is_public'] and not public_shares_allowed:
        message = _("User is not authorized to set 'is_public' to True in the "
                    "request.")
        raise exception.NotAuthorized(message=message)

    return api_params
Esempio n. 20
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)
Esempio n. 21
0
    def bmc_reset(self, task, http_method, warm=True):
        """Reset BMC with IPMI command 'bmc reset (warm|cold)'.

        :param task: a TaskManager instance.
        :param http_method: the HTTP method used on the request.
        :param warm: boolean parameter to decide on warm or cold reset.
        :raises: IPMIFailure on an error from ipmitool.
        :raises: MissingParameterValue if a required parameter is missing.
        :raises: InvalidParameterValue when an invalid value is specified

        """
        node_uuid = task.node.uuid

        warm = strutils.bool_from_string(warm)
        if warm:
            warm_param = 'warm'
        else:
            warm_param = 'cold'

        LOG.debug('Doing %(warm)s BMC reset on node %(node)s',
                  {'warm': warm_param, 'node': node_uuid})
        driver_info = _parse_driver_info(task.node)
        cmd = 'bmc reset %s' % warm_param

        try:
            out, err = _exec_ipmitool(driver_info, cmd)
            LOG.debug('bmc reset returned stdout: %(stdout)s, stderr:'
                      ' %(stderr)s', {'stdout': out, 'stderr': err})
        except (exception.PasswordFileFailedToCreate,
                processutils.ProcessExecutionError) as e:
            LOG.exception(_LE('IPMI "bmc reset" failed for node %(node_id)s '
                          'with error: %(error)s.'),
                          {'node_id': node_uuid, 'error': e})
            raise exception.IPMIFailure(cmd=cmd)
Esempio n. 22
0
    def delete(self, req, id, body):
        """Delete a consistency group."""
        LOG.debug('delete called for member %s', id)
        context = req.environ['cinder.context']
        force = False
        if body:
            if not self.is_valid_body(body, 'consistencygroup'):
                msg = _("Missing required element 'consistencygroup' in "
                        "request body.")
                raise exc.HTTPBadRequest(explanation=msg)

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

        LOG.info(_LI('Delete consistency group with id: %s'), id)

        try:
            group = self.consistencygroup_api.get(context, id)
            self.consistencygroup_api.delete(context, group, force)
        # Not found exception will be handled at the wsgi level
        except exception.InvalidConsistencyGroup as error:
            raise exc.HTTPBadRequest(explanation=error.msg)

        return webob.Response(status_int=202)
Esempio n. 23
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=six.text_type(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)
Esempio n. 24
0
    def _set_bootable(self, req, id, body):
        """Update bootable status of a volume."""
        context = req.environ['storage.context']
        try:
            volume = self.volume_api.get(context, id)
        except exception.VolumeNotFound as error:
            raise webob.exc.HTTPNotFound(explanation=error.msg)

        try:
            bootable = body['os-set_bootable']['bootable']
        except KeyError:
            msg = _("Must specify bootable in request.")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            bootable = strutils.bool_from_string(bootable,
                                                 strict=True)
        except ValueError as error:
            err_msg = encodeutils.exception_to_unicode(error)
            msg = _("Invalid value for 'bootable': '%s'") % err_msg
            raise webob.exc.HTTPBadRequest(explanation=msg)

        update_dict = {'bootable': bootable}

        self.volume_api.update(context, volume, update_dict)
        return webob.Response(status_int=200)
Esempio n. 25
0
    def confirmation_prompt(self):
        print(self._objects_map.get_count_table())
        raw_val = input(
            _("There are %(count)d objects set for deletion. "
              "Continue? [y/N]") % dict(count=len(self._objects_map)))

        return strutils.bool_from_string(raw_val)
 def password(self):
     if self._validate_string(self.args.os_password):
         return self.args.os_password
     verify_pass = (
         strutils.bool_from_string(cliutils.env("OS_VERIFY_PASSWORD"))
     )
     return self._prompt_password(verify_pass)
Esempio n. 27
0
    def setUp(self):
        """Run before each test method to initialize test environment."""
        super(TestCase, self).setUp()

        test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0)
        try:
            test_timeout = int(test_timeout)
        except ValueError:
            # If timeout value is invalid do not set a timeout.
            test_timeout = 0
        if test_timeout > 0:
            self.useFixture(fixtures.Timeout(test_timeout, gentle=True))
        self.useFixture(fixtures.NestedTempfile())
        self.useFixture(fixtures.TempHomeDir())

        environ_enabled = (lambda var_name:
                           strutils.bool_from_string(os.environ.get(var_name)))
        if environ_enabled('OS_STDOUT_CAPTURE'):
            stdout = self.useFixture(fixtures.StringStream('stdout')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
        if environ_enabled('OS_STDERR_CAPTURE'):
            stderr = self.useFixture(fixtures.StringStream('stderr')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))

        self.start = timeutils.utcnow()
Esempio n. 28
0
    def setUp(self):
        """Run before each test method to initialize test environment."""
        super(TestCase, self).setUp()

        test_timeout = os.environ.get("OS_TEST_TIMEOUT", 0)
        try:
            test_timeout = int(test_timeout)
        except ValueError:
            # If timeout value is invalid do not set a timeout.
            test_timeout = 0
        if test_timeout > 0:
            self.useFixture(fixtures.Timeout(test_timeout, gentle=True))
        self.useFixture(fixtures.NestedTempfile())
        self.useFixture(fixtures.TempHomeDir())

        environ_enabled = lambda var_name: strutils.bool_from_string(os.environ.get(var_name))
        if environ_enabled("OS_STDOUT_CAPTURE"):
            stdout = self.useFixture(fixtures.StringStream("stdout")).stream
            self.useFixture(fixtures.MonkeyPatch("sys.stdout", stdout))
        if environ_enabled("OS_STDERR_CAPTURE"):
            stderr = self.useFixture(fixtures.StringStream("stderr")).stream
            self.useFixture(fixtures.MonkeyPatch("sys.stderr", stderr))
        if environ_enabled("OS_LOG_CAPTURE"):
            log_format = "%(levelname)s [%(name)s] %(message)s"
            if environ_enabled("OS_DEBUG"):
                level = logging.DEBUG
            else:
                level = logging.INFO
            self.useFixture(fixtures.LoggerFixture(nuke_handlers=False, format=log_format, level=level))
Esempio n. 29
0
def _cloud_create(cs, args, cloud_type=None):
    try:
        params = _extract_dict(args.params)
    except Exception:
        raise exceptions.CommandError("Unable to convert params to dict: %s" %
                                      params)
    enabled = strutils.bool_from_string(args.enabled)
    capabilities = _extract_list(args.capabilities)

    if not params:
        raise exceptions.CommandError("Connection parameters can't be empty.")

    kwargs = {'name': args.name,
              'driver': args.driver,
              'type': cloud_type,
              'capabilities': capabilities,
              'enabled': enabled,
              'params': params}

    cloud = cs.clouds.create(**kwargs)
    info = dict()
    info.update(cloud._info)
    info['params'] = _dict_to_string(info['params'])
    info['capabilities'] = _list_to_string(info['capabilities'])
    if info['type'] == 'destination':
        info['properties'] = _extract_props(info['properties'])

    utils.print_dict(info)
Esempio n. 30
0
 def _migrate_volume(self, req, id, body):
     """Migrate a volume to the specified host."""
     context = req.environ['cinder.context']
     self.authorize(context, 'migrate_volume')
     try:
         volume = self._get(context, id)
     except exception.NotFound:
         raise exc.HTTPNotFound()
     params = body['os-migrate_volume']
     try:
         host = params['host']
     except KeyError:
         raise exc.HTTPBadRequest(explanation=_("Must specify 'host'"))
     force_host_copy = params.get('force_host_copy', False)
     if isinstance(force_host_copy, basestring):
         try:
             force_host_copy = strutils.bool_from_string(force_host_copy,
                                                         strict=True)
         except ValueError:
             raise exc.HTTPBadRequest(
                 explanation=_("Bad value for 'force_host_copy'"))
     elif not isinstance(force_host_copy, bool):
         raise exc.HTTPBadRequest(
             explanation=_("'force_host_copy' not string or bool"))
     self.volume_api.migrate_volume(context, volume, host, force_host_copy)
     return webob.Response(status_int=202)
Esempio n. 31
0
    def get_all(self,
                context,
                search_opts=None,
                sort_key='created_at',
                sort_dir='desc'):
        policy.check_policy(context, 'share', 'get_all')

        if search_opts is None:
            search_opts = {}

        LOG.debug("Searching for shares by: %s", six.text_type(search_opts))

        # Prepare filters
        filters = {}
        if 'metadata' in search_opts:
            filters['metadata'] = search_opts.pop('metadata')
            if not isinstance(filters['metadata'], dict):
                msg = _("Wrong metadata filter provided: "
                        "%s.") % six.text_type(filters['metadata'])
                raise exception.InvalidInput(reason=msg)
        if 'extra_specs' in search_opts:
            # Verify policy for extra-specs access
            extensions.extension_authorizer('share',
                                            'types_extra_specs')(context)
            filters['extra_specs'] = search_opts.pop('extra_specs')
            if not isinstance(filters['extra_specs'], dict):
                msg = _("Wrong extra specs filter provided: "
                        "%s.") % six.text_type(filters['extra_specs'])
                raise exception.InvalidInput(reason=msg)
        if not (isinstance(sort_key, six.string_types) and sort_key):
            msg = _("Wrong sort_key filter provided: "
                    "'%s'.") % six.text_type(sort_key)
            raise exception.InvalidInput(reason=msg)
        if not (isinstance(sort_dir, six.string_types) and sort_dir):
            msg = _("Wrong sort_dir filter provided: "
                    "'%s'.") % six.text_type(sort_dir)
            raise exception.InvalidInput(reason=msg)

        is_public = search_opts.pop('is_public', False)
        is_public = strutils.bool_from_string(is_public, strict=True)

        # Get filtered list of shares
        if 'share_server_id' in search_opts:
            # NOTE(vponomaryov): this is project_id independent
            policy.check_policy(context, 'share', 'list_by_share_server_id')
            shares = self.db.share_get_all_by_share_server(
                context,
                search_opts.pop('share_server_id'),
                filters=filters,
                sort_key=sort_key,
                sort_dir=sort_dir)
        elif (context.is_admin and 'all_tenants' in search_opts):
            shares = self.db.share_get_all(context,
                                           filters=filters,
                                           sort_key=sort_key,
                                           sort_dir=sort_dir)
        else:
            shares = self.db.share_get_all_by_project(
                context,
                project_id=context.project_id,
                filters=filters,
                is_public=is_public,
                sort_key=sort_key,
                sort_dir=sort_dir)

        # NOTE(vponomaryov): we do not need 'all_tenants' opt anymore
        search_opts.pop('all_tenants', None)

        if search_opts:
            results = []
            for s in shares:
                # values in search_opts can be only strings
                if all(s.get(k, None) == v for k, v in search_opts.items()):
                    results.append(s)
            shares = results
        return shares
Esempio n. 32
0
    def create(self,
               context,
               share_proto,
               size,
               name,
               description,
               snapshot=None,
               availability_zone=None,
               metadata=None,
               share_network_id=None,
               share_type=None,
               is_public=False):
        """Create new share."""
        policy.check_policy(context, 'share', 'create')

        self._check_metadata_properties(context, metadata)

        if snapshot is not None:
            if snapshot['status'] != 'available':
                msg = _("status must be 'available'")
                raise exception.InvalidShareSnapshot(reason=msg)
            if not size:
                size = snapshot['size']

            snapshot_id = snapshot['id']
        else:
            snapshot_id = None

        def as_int(s):
            try:
                return int(s)
            except (ValueError, TypeError):
                return s

        # tolerate size as stringified int
        size = as_int(size)

        if not isinstance(size, int) or size <= 0:
            msg = (_("Share size '%s' must be an integer and greater than 0") %
                   size)
            raise exception.InvalidInput(reason=msg)

        if snapshot and size < snapshot['size']:
            msg = (_("Share size '%s' must be equal or greater "
                     "than snapshot size") % size)
            raise exception.InvalidInput(reason=msg)

        if snapshot is None:
            share_type_id = share_type['id'] if share_type else None
        else:
            source_share = self.db.share_get(context, snapshot['share_id'])
            if share_type is None:
                share_type_id = source_share['share_type_id']
                if share_type_id is not None:
                    share_type = share_types.get_share_type(
                        context, share_type_id)
            else:
                share_type_id = share_type['id']
                if share_type_id != source_share['share_type_id']:
                    msg = _("Invalid share type specified: the requested "
                            "share type must match the type of the source "
                            "share. If a share type is not specified when "
                            "requesting a new share from a snapshot, the "
                            "share type of the source share will be applied "
                            "to the new share.")
                    raise exception.InvalidInput(reason=msg)

        supported_share_protocols = (proto.upper()
                                     for proto in CONF.enabled_share_protocols)
        if not (share_proto
                and share_proto.upper() in supported_share_protocols):
            msg = (_("Invalid share protocol provided: %(provided)s. "
                     "It is either disabled or unsupported. Available "
                     "protocols: %(supported)s") %
                   dict(provided=share_proto,
                        supported=CONF.enabled_share_protocols))
            raise exception.InvalidInput(reason=msg)

        try:
            reservations = QUOTAS.reserve(context, shares=1, gigabytes=size)
        except exception.OverQuota as e:
            overs = e.kwargs['overs']
            usages = e.kwargs['usages']
            quotas = e.kwargs['quotas']

            def _consumed(name):
                return (usages[name]['reserved'] + usages[name]['in_use'])

            if 'gigabytes' in overs:
                LOG.warn(
                    _LW("Quota exceeded for %(s_pid)s, tried to create "
                        "%(s_size)sG share (%(d_consumed)dG of "
                        "%(d_quota)dG already consumed)"), {
                            's_pid': context.project_id,
                            's_size': size,
                            'd_consumed': _consumed('gigabytes'),
                            'd_quota': quotas['gigabytes']
                        })
                raise exception.ShareSizeExceedsAvailableQuota()
            elif 'shares' in overs:
                LOG.warn(
                    _LW("Quota exceeded for %(s_pid)s, tried to create "
                        "share (%(d_consumed)d shares "
                        "already consumed)"), {
                            's_pid': context.project_id,
                            'd_consumed': _consumed('shares')
                        })
                raise exception.ShareLimitExceeded(allowed=quotas['shares'])

        if availability_zone is None:
            availability_zone = CONF.storage_availability_zone

        try:
            is_public = strutils.bool_from_string(is_public, strict=True)
        except ValueError as e:
            raise exception.InvalidParameterValue(e.message)

        options = {
            'size': size,
            'user_id': context.user_id,
            'project_id': context.project_id,
            'snapshot_id': snapshot_id,
            'share_network_id': share_network_id,
            'availability_zone': availability_zone,
            'metadata': metadata,
            'status': "creating",
            'scheduled_at': timeutils.utcnow(),
            'display_name': name,
            'display_description': description,
            'share_proto': share_proto,
            'share_type_id': share_type_id,
            'is_public': is_public,
        }

        try:
            share = self.db.share_create(context, options)
            QUOTAS.commit(context, reservations)
        except Exception:
            with excutils.save_and_reraise_exception():
                try:
                    self.db.share_delete(context, share['id'])
                finally:
                    QUOTAS.rollback(context, reservations)

        request_spec = {
            'share_properties': options,
            'share_proto': share_proto,
            'share_id': share['id'],
            'snapshot_id': snapshot_id,
            'share_type': share_type,
        }
        filter_properties = {}

        if (snapshot and not CONF.use_scheduler_creating_share_from_snapshot):
            # Shares from snapshots with restriction - source host only.
            # It is common situation for different types of backends.
            host = snapshot['share']['host']
            share = self.db.share_update(context, share['id'], {'host': host})
            self.share_rpcapi.create_share(
                context,
                share,
                host,
                request_spec=request_spec,
                filter_properties=filter_properties,
                snapshot_id=snapshot_id,
            )
        else:
            # Shares from scratch and from snapshots when source host is not
            # the only allowed, it is possible, for example, in multibackend
            # installation with Generic drivers only.
            self.scheduler_rpcapi.create_share(
                context,
                CONF.share_topic,
                share['id'],
                snapshot_id,
                request_spec=request_spec,
                filter_properties=filter_properties,
            )

        return share
Esempio n. 33
0
    def update(self, req, id, body):
        """Update Quota for a particular tenant

        This works for hierarchical and non-hierarchical projects. For
        hierarchical projects only immediate parent admin or the
        CLOUD admin are able to perform an update.

        :param req: request
        :param id: target project id that needs to be updated
        :param body: key, value pair that that will be
                     applied to the resources if the update
                     succeeds
        """
        context = req.environ['cinder.context']
        authorize_update(context)
        self.validate_string_length(id,
                                    'quota_set_name',
                                    min_length=1,
                                    max_length=255)

        self.assert_valid_body(body, 'quota_set')

        # Get the optional argument 'skip_validation' from body,
        # if skip_validation is False, then validate existing resource.
        skip_flag = body.get('skip_validation', True)
        if not utils.is_valid_boolstr(skip_flag):
            msg = _("Invalid value '%s' for skip_validation.") % skip_flag
            raise exception.InvalidParameterValue(err=msg)
        skip_flag = strutils.bool_from_string(skip_flag)

        target_project_id = id
        bad_keys = []

        # NOTE(ankit): Pass #1 - In this loop for body['quota_set'].items(),
        # we figure out if we have any bad keys.
        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 len(bad_keys) > 0:
            msg = _("Bad key(s) in quota set: %s") % ",".join(bad_keys)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        # Saving off this value since we need to use it multiple times
        use_nested_quotas = QUOTAS.using_nested_quotas()
        if use_nested_quotas:
            # Get the parent_id of the target project to verify whether we are
            # dealing with hierarchical namespace or non-hierarchical namespace
            target_project = quota_utils.get_project_hierarchy(
                context, target_project_id, parents_as_ids=True)
            parent_id = target_project.parent_id

            if parent_id:
                # Get the children of the project which the token is scoped to
                # in order to know if the target_project is in its hierarchy.
                context_project = quota_utils.get_project_hierarchy(
                    context, context.project_id, subtree_as_ids=True)
                self._authorize_update_or_delete(context_project,
                                                 target_project.id, parent_id)

        # NOTE(ankit): Pass #2 - In this loop for body['quota_set'].keys(),
        # we validate the quota limits to ensure that we can bail out if
        # any of the items in the set is bad. Meanwhile we validate value
        # to ensure that the value can't be lower than number of existing
        # resources.
        quota_values = QUOTAS.get_project_quotas(context,
                                                 target_project_id,
                                                 defaults=False)
        valid_quotas = {}
        reservations = []
        for key in body['quota_set'].keys():
            if key in NON_QUOTA_KEYS:
                continue

            value = self.validate_integer(body['quota_set'][key],
                                          key,
                                          min_value=-1,
                                          max_value=db.MAX_INT)

            # Can't skip the validation of nested quotas since it could mess up
            # hierarchy if parent limit is less than childrens' current usage
            if not skip_flag or use_nested_quotas:
                self._validate_existing_resource(key, value, quota_values)

            if use_nested_quotas:
                try:
                    reservations += self._update_nested_quota_allocated(
                        context, target_project, quota_values, key, value)
                except exception.OverQuota as e:
                    if reservations:
                        db.reservation_rollback(context, reservations)
                    raise webob.exc.HTTPBadRequest(explanation=e.message)

            valid_quotas[key] = value

        # NOTE(ankit): Pass #3 - At this point we know that all the keys and
        # values are valid and we can iterate and update them all in one shot
        # without having to worry about rolling back etc as we have done
        # the validation up front in the 2 loops above.
        for key, value in valid_quotas.items():
            try:
                db.quota_update(context, target_project_id, key, value)
            except exception.ProjectQuotaNotFound:
                db.quota_create(context, target_project_id, key, value)
            except exception.AdminRequired:
                raise webob.exc.HTTPForbidden()

        if reservations:
            db.reservation_commit(context, reservations)
        return {'quota_set': self._get_quotas(context, target_project_id)}
Esempio n. 34
0
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of Ironic ramdisk using PXE.

        This method prepares the boot of the deploy or rescue kernel/ramdisk
        after reading relevant information from the node's driver_info and
        instance_info.

        :param task: a task from TaskManager.
        :param ramdisk_params: the parameters to be passed to the ramdisk.
            pxe driver passes these parameters as kernel command-line
            arguments.
        :param mode: Label indicating a deploy or rescue operation
            being carried out on the node. Supported values are
            'deploy' and 'rescue'. Defaults to 'deploy', indicating
            deploy operation is being carried out.
        :returns: None
        :raises: MissingParameterValue, if some information is missing in
            node's driver_info or instance_info.
        :raises: InvalidParameterValue, if some information provided is
            invalid.
        :raises: IronicException, if some power or set boot boot device
            operation failed on the node.
        """
        node = task.node
        mode = deploy_utils.rescue_or_deploy_mode(node)
        ipxe_enabled = CONF.pxe.ipxe_enabled
        if ipxe_enabled:
            # NOTE(mjturek): At this point, the ipxe boot script should
            # already exist as it is created at startup time. However, we
            # call the boot script create method here to assert its
            # existence and handle the unlikely case that it wasn't created
            # or was deleted.
            pxe_utils.create_ipxe_boot_script()

        dhcp_opts = pxe_utils.dhcp_options_for_instance(
            task, ipxe_enabled=ipxe_enabled)
        provider = dhcp_factory.DHCPFactory()
        provider.update_dhcp(task, dhcp_opts)

        pxe_info = pxe_utils.get_image_info(node, mode=mode)

        # NODE: Try to validate and fetch instance images only
        # if we are in DEPLOYING state.
        if node.provision_state == states.DEPLOYING:
            pxe_info.update(pxe_utils.get_instance_image_info(task))
            boot_mode_utils.sync_boot_mode(task)

        pxe_options = pxe_utils.build_pxe_config_options(
            task, pxe_info, ipxe_enabled=ipxe_enabled)
        pxe_options.update(ramdisk_params)

        pxe_config_template = deploy_utils.get_pxe_config_template(node)

        pxe_utils.create_pxe_config(task, pxe_options,
                                    pxe_config_template,
                                    ipxe_enabled=CONF.pxe.ipxe_enabled)

        persistent = False
        value = node.driver_info.get('force_persistent_boot_device',
                                     'Default')
        if value in {'Always', 'Default', 'Never'}:
            if value == 'Always':
                persistent = True
        else:
            persistent = strutils.bool_from_string(value, False)
        manager_utils.node_set_boot_device(task, boot_devices.PXE,
                                           persistent=persistent)

        if CONF.pxe.ipxe_enabled and CONF.pxe.ipxe_use_swift:
            kernel_label = '%s_kernel' % mode
            ramdisk_label = '%s_ramdisk' % mode
            pxe_info.pop(kernel_label, None)
            pxe_info.pop(ramdisk_label, None)

        if pxe_info:
            pxe_utils.cache_ramdisk_kernel(task, pxe_info,
                                           ipxe_enabled=CONF.pxe.ipxe_enabled)
Esempio n. 35
0
    def setUp(self):
        """Run before each test method to initialize test environment."""
        super(TestCase, self).setUp()

        # Create default notifier
        self.notifier = fake_notifier.get_fake_notifier()

        # Mock rpc get notifier with fake notifier method that joins all
        # notifications with the default notifier
        p = mock.patch('miper.rpc.get_notifier',
                       side_effect=self._get_joined_notifier)
        p.start()

        # Import miper objects for test cases
        objects.register_all()

        # Unit tests do not need to use lazy gettext
        i18n.enable_lazy(False)

        test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0)
        try:
            test_timeout = int(test_timeout)
        except ValueError:
            # If timeout value is invalid do not set a timeout.
            test_timeout = 0
        if test_timeout > 0:
            self.useFixture(fixtures.Timeout(test_timeout, gentle=True))
        self.useFixture(fixtures.NestedTempfile())
        self.useFixture(fixtures.TempHomeDir())

        environ_enabled = (lambda var_name: strutils.bool_from_string(
            os.environ.get(var_name)))
        if environ_enabled('OS_STDOUT_CAPTURE'):
            stdout = self.useFixture(fixtures.StringStream('stdout')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
        if environ_enabled('OS_STDERR_CAPTURE'):
            stderr = self.useFixture(fixtures.StringStream('stderr')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))

        self.useFixture(log_fixture.get_logging_handle_error_fixture())
        self.useFixture(miper_fixtures.StandardLogging())

        rpc.add_extra_exmods("miper.tests.unit")
        self.addCleanup(rpc.clear_extra_exmods)
        self.addCleanup(rpc.cleanup)

        self.messaging_conf = messaging_conffixture.ConfFixture(CONF)
        self.messaging_conf.transport_driver = 'fake'
        self.messaging_conf.response_timeout = 15
        self.useFixture(self.messaging_conf)
        rpc.init(CONF)

        conf_fixture.set_defaults(CONF)
        CONF([], default_config_files=[])

        # NOTE(vish): We need a better method for creating fixtures for tests
        #             now that we have some required db setup for the system
        #             to work properly.
        self.start = timeutils.utcnow()

        CONF.set_default('connection', 'sqlite://', 'database')
        CONF.set_default('sqlite_synchronous', False, 'database')

        global _DB_CACHE
        if not _DB_CACHE:
            _DB_CACHE = Database(sqla_api,
                                 migration,
                                 sql_connection=CONF.database.connection,
                                 sqlite_db=CONF.database.sqlite_db,
                                 sqlite_clean_db=CONF.sqlite_clean_db)
        self.useFixture(_DB_CACHE)

        # emulate some of the mox stuff, we can't use the metaclass
        # because it screws with our generators
        mox_fixture = self.useFixture(moxstubout.MoxStubout())
        self.mox = mox_fixture.mox
        self.stubs = mox_fixture.stubs
        self.addCleanup(CONF.reset)
        self.addCleanup(self._common_cleanup)
        self.injected = []
        self._services = []

        fake_notifier.stub_notifier(self.stubs)

        self.override_config('fatal_exception_format_errors', True)
        # This will be cleaned up by the NestedTempfile fixture
        lock_path = self.useFixture(fixtures.TempDir()).path
        self.fixture = self.useFixture(config_fixture.Config(lockutils.CONF))
        self.fixture.config(lock_path=lock_path, group='oslo_concurrency')
        lockutils.set_defaults(lock_path)
        self.override_config('policy_file',
                             os.path.join(
                                 os.path.abspath(
                                     os.path.join(
                                         os.path.dirname(__file__),
                                         '..',
                                     )), 'miper/tests/unit/policy.json'),
                             group='oslo_policy')

        self._disable_osprofiler()
Esempio n. 36
0
 def _is_magnum_auto_healer_running(self):
     auto_healing = self.cluster.labels.get("auto_healing_enabled")
     auto_healing_enabled = strutils.bool_from_string(auto_healing)
     controller = self.cluster.labels.get("auto_healing_controller")
     return (auto_healing_enabled and controller == "magnum-auto-healer")
Esempio n. 37
0
def create(name,
           memory,
           vcpus,
           root_gb,
           ephemeral_gb=0,
           flavorid=None,
           swap=0,
           rxtx_factor=1.0,
           is_public=True,
           description=None):
    """Creates flavors."""
    if not flavorid:
        flavorid = uuidutils.generate_uuid()

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

    if isinstance(name, str):
        name = name.strip()

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

    # 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_const.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'] > db_const.SQL_SP_FLOAT_MAX):
            raise ValueError()
    except ValueError:
        msg = _("'rxtx_factor' argument must be a float between 0 and %g")
        raise exception.InvalidInput(reason=msg % db_const.SQL_SP_FLOAT_MAX)

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

    flavor = objects.Flavor(context=context.get_admin_context(), **kwargs)
    flavor.create()
    return flavor
Esempio n. 38
0
 def test_bool_bool_from_string(self):
     self.assertTrue(strutils.bool_from_string(True))
     self.assertFalse(strutils.bool_from_string(False))
Esempio n. 39
0
 def test_bool_bool_from_string_no_text(self, mock_text):
     self.assertTrue(strutils.bool_from_string(True))
     self.assertFalse(strutils.bool_from_string(False))
     self.assertEqual(0, mock_text.call_count)
Esempio n. 40
0
 def test_bool_bool_from_string_default(self):
     self.assertTrue(strutils.bool_from_string('', default=True))
     self.assertFalse(strutils.bool_from_string('wibble', default=False))
Esempio n. 41
0
    def _test_bool_from_string(self, c):
        self.assertTrue(strutils.bool_from_string(c('true')))
        self.assertTrue(strutils.bool_from_string(c('TRUE')))
        self.assertTrue(strutils.bool_from_string(c('on')))
        self.assertTrue(strutils.bool_from_string(c('On')))
        self.assertTrue(strutils.bool_from_string(c('yes')))
        self.assertTrue(strutils.bool_from_string(c('YES')))
        self.assertTrue(strutils.bool_from_string(c('yEs')))
        self.assertTrue(strutils.bool_from_string(c('1')))
        self.assertTrue(strutils.bool_from_string(c('T')))
        self.assertTrue(strutils.bool_from_string(c('t')))
        self.assertTrue(strutils.bool_from_string(c('Y')))
        self.assertTrue(strutils.bool_from_string(c('y')))

        self.assertFalse(strutils.bool_from_string(c('false')))
        self.assertFalse(strutils.bool_from_string(c('FALSE')))
        self.assertFalse(strutils.bool_from_string(c('off')))
        self.assertFalse(strutils.bool_from_string(c('OFF')))
        self.assertFalse(strutils.bool_from_string(c('no')))
        self.assertFalse(strutils.bool_from_string(c('0')))
        self.assertFalse(strutils.bool_from_string(c('42')))
        self.assertFalse(strutils.bool_from_string(c(
                         'This should not be True')))
        self.assertFalse(strutils.bool_from_string(c('F')))
        self.assertFalse(strutils.bool_from_string(c('f')))
        self.assertFalse(strutils.bool_from_string(c('N')))
        self.assertFalse(strutils.bool_from_string(c('n')))

        # Whitespace should be stripped
        self.assertTrue(strutils.bool_from_string(c(' 1 ')))
        self.assertTrue(strutils.bool_from_string(c(' true ')))
        self.assertFalse(strutils.bool_from_string(c(' 0 ')))
        self.assertFalse(strutils.bool_from_string(c(' false ')))
Esempio n. 42
0
    def setUp(self):
        """Run before each test method to initialize test environment."""
        super(TestCase, self).setUp()

        # Create default notifier
        self.notifier = fake_notifier.get_fake_notifier()

        # Mock rpc get notifier with fake notifier method that joins all
        # notifications with the default notifier
        p = mock.patch('cinder.rpc.get_notifier',
                       side_effect=self._get_joined_notifier)
        p.start()

        # Unit tests do not need to use lazy gettext
        i18n.enable_lazy(False)

        test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0)
        try:
            test_timeout = int(test_timeout)
        except ValueError:
            # If timeout value is invalid do not set a timeout.
            test_timeout = 0
        if test_timeout > 0:
            self.useFixture(fixtures.Timeout(test_timeout, gentle=True))
        self.useFixture(fixtures.NestedTempfile())
        self.useFixture(fixtures.TempHomeDir())

        environ_enabled = (lambda var_name: strutils.bool_from_string(
            os.environ.get(var_name)))
        if environ_enabled('OS_STDOUT_CAPTURE'):
            stdout = self.useFixture(fixtures.StringStream('stdout')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
        if environ_enabled('OS_STDERR_CAPTURE'):
            stderr = self.useFixture(fixtures.StringStream('stderr')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
        if environ_enabled('OS_LOG_CAPTURE'):
            log_format = '%(levelname)s [%(name)s] %(message)s'
            if environ_enabled('OS_DEBUG'):
                level = logging.DEBUG
            else:
                level = logging.INFO
            self.useFixture(
                fixtures.LoggerFixture(nuke_handlers=False,
                                       format=log_format,
                                       level=level))

        rpc.add_extra_exmods("cinder.tests.unit")
        self.addCleanup(rpc.clear_extra_exmods)
        self.addCleanup(rpc.cleanup)

        self.messaging_conf = messaging_conffixture.ConfFixture(CONF)
        self.messaging_conf.transport_driver = 'fake'
        self.messaging_conf.response_timeout = 15
        self.useFixture(self.messaging_conf)
        rpc.init(CONF)

        conf_fixture.set_defaults(CONF)
        CONF([], default_config_files=[])

        # NOTE(vish): We need a better method for creating fixtures for tests
        #             now that we have some required db setup for the system
        #             to work properly.
        self.start = timeutils.utcnow()

        CONF.set_default('connection', 'sqlite://', 'database')
        CONF.set_default('sqlite_synchronous', False, 'database')

        global _DB_CACHE
        if not _DB_CACHE:
            _DB_CACHE = Database(sqla_api,
                                 migration,
                                 sql_connection=CONF.database.connection,
                                 sqlite_db=CONF.database.sqlite_db,
                                 sqlite_clean_db=CONF.sqlite_clean_db)
        self.useFixture(_DB_CACHE)

        # NOTE(danms): Make sure to reset us back to non-remote objects
        # for each test to avoid interactions. Also, backup the object
        # registry.
        objects_base.CinderObject.indirection_api = None
        self._base_test_obj_backup = copy.copy(
            objects_base.CinderObjectRegistry._registry._obj_classes)
        self.addCleanup(self._restore_obj_registry)

        # emulate some of the mox stuff, we can't use the metaclass
        # because it screws with our generators
        mox_fixture = self.useFixture(moxstubout.MoxStubout())
        self.mox = mox_fixture.mox
        self.stubs = mox_fixture.stubs
        self.addCleanup(CONF.reset)
        self.addCleanup(self._common_cleanup)
        self.injected = []
        self._services = []

        fake_notifier.stub_notifier(self.stubs)

        self.override_config('fatal_exception_format_errors', True)
        # This will be cleaned up by the NestedTempfile fixture
        lock_path = self.useFixture(fixtures.TempDir()).path
        self.fixture = self.useFixture(config_fixture.Config(lockutils.CONF))
        self.fixture.config(lock_path=lock_path, group='oslo_concurrency')
        lockutils.set_defaults(lock_path)
        self.override_config('policy_file',
                             os.path.join(
                                 os.path.abspath(
                                     os.path.join(
                                         os.path.dirname(__file__),
                                         '..',
                                     )), 'cinder/tests/unit/policy.json'),
                             group='oslo_policy')

        self._disable_osprofiler()

        # NOTE(geguileo): This is required because common get_by_id method in
        # cinder.db.sqlalchemy.api caches get methods and if we use a mocked
        # get method in one test it would carry on to the next test.  So we
        # clear out the cache.
        sqla_api._GET_METHODS = {}
Esempio n. 43
0
    def get_base_parser(self, argv):
        parser = NovaClientArgumentParser(
            prog='nova',
            description=__doc__.strip(),
            epilog='See "nova help COMMAND" '
            'for help on a specific command.',
            add_help=False,
            formatter_class=OpenStackHelpFormatter,
        )

        # Global arguments
        parser.add_argument(
            '-h',
            '--help',
            action='store_true',
            help=argparse.SUPPRESS,
        )

        parser.add_argument('--version',
                            action='version',
                            version=novaclient.__version__)

        parser.add_argument('--debug',
                            default=False,
                            action='store_true',
                            help=_("Print debugging output."))

        parser.add_argument(
            '--os-cache',
            default=strutils.bool_from_string(
                utils.env('OS_CACHE', default=False), True),
            action='store_true',
            help=_("Use the auth token cache. Defaults to False if "
                   "env[OS_CACHE] is not set."))

        parser.add_argument('--timings',
                            default=False,
                            action='store_true',
                            help=_("Print call timing info."))

        parser.add_argument('--os-region-name',
                            metavar='<region-name>',
                            default=utils.env('OS_REGION_NAME',
                                              'NOVA_REGION_NAME'),
                            help=_('Defaults to env[OS_REGION_NAME].'))

        parser.add_argument('--service-type',
                            metavar='<service-type>',
                            help=_('Defaults to compute for most actions.'))

        parser.add_argument('--service-name',
                            metavar='<service-name>',
                            default=utils.env('NOVA_SERVICE_NAME'),
                            help=_('Defaults to env[NOVA_SERVICE_NAME].'))

        parser.add_argument('--os-endpoint-type',
                            metavar='<endpoint-type>',
                            dest='endpoint_type',
                            default=utils.env(
                                'NOVA_ENDPOINT_TYPE',
                                default=utils.env(
                                    'OS_ENDPOINT_TYPE',
                                    default=DEFAULT_NOVA_ENDPOINT_TYPE)),
                            help=_('Defaults to env[NOVA_ENDPOINT_TYPE], '
                                   'env[OS_ENDPOINT_TYPE] or ') +
                            DEFAULT_NOVA_ENDPOINT_TYPE + '.')

        parser.add_argument(
            '--os-compute-api-version',
            metavar='<compute-api-ver>',
            default=utils.env('OS_COMPUTE_API_VERSION',
                              default=DEFAULT_OS_COMPUTE_API_VERSION),
            help=_('Accepts X, X.Y (where X is major and Y is minor part) or '
                   '"X.latest", defaults to env[OS_COMPUTE_API_VERSION].'))

        parser.add_argument(
            '--os-endpoint-override',
            metavar='<bypass-url>',
            dest='endpoint_override',
            default=utils.env('OS_ENDPOINT_OVERRIDE',
                              'NOVACLIENT_ENDPOINT_OVERRIDE',
                              'NOVACLIENT_BYPASS_URL'),
            help=_("Use this API endpoint instead of the Service Catalog. "
                   "Defaults to env[OS_ENDPOINT_OVERRIDE]."))

        parser.set_defaults(func=self.do_help)
        parser.set_defaults(command='')

        if osprofiler_profiler:
            parser.add_argument('--profile',
                                metavar='HMAC_KEY',
                                default=utils.env('OS_PROFILE'),
                                help='HMAC key to use for encrypting context '
                                'data for performance profiling of operation. '
                                'This key should be the value of the HMAC key '
                                'configured for the OSprofiler middleware in '
                                'nova; it is specified in the Nova '
                                'configuration file at "/etc/nova/nova.conf". '
                                'Without the key, profiling will not be '
                                'triggered even if OSprofiler is enabled on '
                                'the server side.')

        self._append_global_identity_args(parser, argv)

        return parser
Esempio n. 44
0
 def coerce(obj, attr, value):
     return strutils.bool_from_string(value)
Esempio n. 45
0
    def test_int_bool_from_string(self):
        self.assertTrue(strutils.bool_from_string(1))

        self.assertFalse(strutils.bool_from_string(-1))
        self.assertFalse(strutils.bool_from_string(0))
        self.assertFalse(strutils.bool_from_string(2))
Esempio n. 46
0
    def get_base_parser(self):
        parser = NovaClientArgumentParser(
            prog='nova',
            description=__doc__.strip(),
            epilog='See "nova help COMMAND" '
            'for help on a specific command.',
            add_help=False,
            formatter_class=OpenStackHelpFormatter,
        )

        # Global arguments
        parser.add_argument(
            '-h',
            '--help',
            action='store_true',
            help=argparse.SUPPRESS,
        )

        parser.add_argument('--version',
                            action='version',
                            version=novaclient.__version__)

        parser.add_argument('--debug',
                            default=False,
                            action='store_true',
                            help=_("Print debugging output"))

        parser.add_argument(
            '--os-cache',
            default=strutils.bool_from_string(
                cliutils.env('OS_CACHE', default=False), True),
            action='store_true',
            help=_("Use the auth token cache. Defaults to False if "
                   "env[OS_CACHE] is not set."))

        parser.add_argument('--timings',
                            default=False,
                            action='store_true',
                            help=_("Print call timing info"))

        parser.add_argument('--os-auth-token',
                            default=cliutils.env('OS_AUTH_TOKEN'),
                            help='Defaults to env[OS_AUTH_TOKEN]')

        parser.add_argument('--os_username', help=argparse.SUPPRESS)

        parser.add_argument('--os_password', help=argparse.SUPPRESS)

        parser.add_argument('--os-tenant-name',
                            metavar='<auth-tenant-name>',
                            default=cliutils.env('OS_TENANT_NAME',
                                                 'NOVA_PROJECT_ID'),
                            help=_('Defaults to env[OS_TENANT_NAME].'))
        parser.add_argument('--os_tenant_name', help=argparse.SUPPRESS)

        parser.add_argument('--os-tenant-id',
                            metavar='<auth-tenant-id>',
                            default=cliutils.env('OS_TENANT_ID'),
                            help=_('Defaults to env[OS_TENANT_ID].'))

        parser.add_argument('--os_auth_url', help=argparse.SUPPRESS)

        parser.add_argument('--os-region-name',
                            metavar='<region-name>',
                            default=cliutils.env('OS_REGION_NAME',
                                                 'NOVA_REGION_NAME'),
                            help=_('Defaults to env[OS_REGION_NAME].'))
        parser.add_argument('--os_region_name', help=argparse.SUPPRESS)

        parser.add_argument('--os-auth-system',
                            metavar='<auth-system>',
                            default=cliutils.env('OS_AUTH_SYSTEM'),
                            help='Defaults to env[OS_AUTH_SYSTEM].')
        parser.add_argument('--os_auth_system', help=argparse.SUPPRESS)

        parser.add_argument('--service-type',
                            metavar='<service-type>',
                            help=_('Defaults to compute for most actions'))
        parser.add_argument('--service_type', help=argparse.SUPPRESS)

        parser.add_argument('--service-name',
                            metavar='<service-name>',
                            default=cliutils.env('NOVA_SERVICE_NAME'),
                            help=_('Defaults to env[NOVA_SERVICE_NAME]'))
        parser.add_argument('--service_name', help=argparse.SUPPRESS)

        parser.add_argument(
            '--volume-service-name',
            metavar='<volume-service-name>',
            default=cliutils.env('NOVA_VOLUME_SERVICE_NAME'),
            help=_('Defaults to env[NOVA_VOLUME_SERVICE_NAME]'))
        parser.add_argument('--volume_service_name', help=argparse.SUPPRESS)

        parser.add_argument('--os-endpoint-type',
                            metavar='<endpoint-type>',
                            dest='endpoint_type',
                            default=cliutils.env(
                                'NOVA_ENDPOINT_TYPE',
                                default=cliutils.env(
                                    'OS_ENDPOINT_TYPE',
                                    default=DEFAULT_NOVA_ENDPOINT_TYPE)),
                            help=_('Defaults to env[NOVA_ENDPOINT_TYPE], '
                                   'env[OS_ENDPOINT_TYPE] or ') +
                            DEFAULT_NOVA_ENDPOINT_TYPE + '.')

        parser.add_argument('--endpoint-type', help=argparse.SUPPRESS)
        # NOTE(dtroyer): We can't add --endpoint_type here due to argparse
        #                thinking usage-list --end is ambiguous; but it
        #                works fine with only --endpoint-type present
        #                Go figure.  I'm leaving this here for doc purposes.
        # parser.add_argument('--endpoint_type',
        #     help=argparse.SUPPRESS)

        parser.add_argument('--os-compute-api-version',
                            metavar='<compute-api-ver>',
                            default=cliutils.env(
                                'OS_COMPUTE_API_VERSION',
                                default=DEFAULT_OS_COMPUTE_API_VERSION),
                            help=_('Accepts 1.1 or 3, '
                                   'defaults to env[OS_COMPUTE_API_VERSION].'))
        parser.add_argument('--os_compute_api_version', help=argparse.SUPPRESS)

        parser.add_argument(
            '--bypass-url',
            metavar='<bypass-url>',
            dest='bypass_url',
            default=cliutils.env('NOVACLIENT_BYPASS_URL'),
            help="Use this API endpoint instead of the Service Catalog. "
            "Defaults to env[NOVACLIENT_BYPASS_URL]")
        parser.add_argument('--bypass_url', help=argparse.SUPPRESS)

        # The auth-system-plugins might require some extra options
        novaclient.auth_plugin.load_auth_system_opts(parser)

        self._append_global_identity_args(parser)

        return parser
Esempio n. 47
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 printable characters "
                "and horizontal 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 = six.text_type(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"))

    flavor = objects.Flavor(context=context.get_admin_context(), **kwargs)
    flavor.create()
    return flavor
Esempio n. 48
0
    def _poll_health_status(self, k8s_api):
        """Poll health status of API and nodes for given cluster

        Design Policy:
        1.  How to calculate the overall health status?
            Any node (including API and minion nodes) is not OK, then the
            overall health status is UNHEALTHY

        2.  The data structure of health_status_reason
            As an attribute of the cluster, the health_status_reason have to
            use the field type from
            oslo.versionedobjects/blob/master/oslo_versionedobjects/fields.py

        3.  How to get the health_status and health_status_reason?
            3.1 Call /healthz to get the API health status
            3.2 Call list_node (using API /api/v1/nodes) to get the nodes
                health status

        :param k8s_api: The api client to the cluster
        :return: Tumple including status and reason. Example:
            (
                ClusterHealthStatus.HEALTHY,
                {
                    'api': 'ok',
                    'k8scluster-ydz7cfbxqqu3-node-0.Ready': False,
                    'k8scluster-ydz7cfbxqqu3-node-1.Ready': True,
                    'k8scluster-ydz7cfbxqqu3-node-2.Ready': True,
                }
            )

        """

        health_status = m_fields.ClusterHealthStatus.UNHEALTHY
        health_status_reason = {}
        api_status = None

        try:
            api_status = k8s_api.get_healthz()

            for node in k8s_api.list_node()['items']:
                node_key = node['metadata']['name'] + ".Ready"
                ready = False
                for condition in node['status']['conditions']:
                    if condition['type'] == 'Ready':
                        ready = strutils.bool_from_string(condition['status'])
                        break

                health_status_reason[node_key] = ready

            if (api_status == 'ok'
                    and all(n for n in health_status_reason.values())):
                health_status = m_fields.ClusterHealthStatus.HEALTHY

            health_status_reason['api'] = api_status
        except Exception as exp_api:
            if not api_status:
                api_status = (getattr(exp_api, 'body', None)
                              or getattr(exp_api, 'message', None))
                if api_status is not None:
                    health_status_reason['api'] = api_status

        return health_status, health_status_reason
Esempio n. 49
0
    def update(self, req, id, body):
        """Perform service update

        Starting with microversion 2.53, the service uuid is passed in on the
        path of the request to uniquely identify the service record on which to
        perform a given update, which is defined in the body of the request.
        """
        service_id = id
        # Validate that the service ID is a UUID.
        if not uuidutils.is_uuid_like(service_id):
            msg = _('Invalid uuid %s') % service_id
            raise webob.exc.HTTPBadRequest(explanation=msg)

        # Validate the request context against the policy.
        context = req.environ['nova.context']
        context.can(services_policies.BASE_POLICY_NAME)

        # Get the service by uuid.
        try:
            service = self.host_api.service_get_by_id(context, service_id)
            # At this point the context is targeted to the cell that the
            # service was found in so we don't need to do any explicit cell
            # targeting below.
        except exception.ServiceNotFound as e:
            raise webob.exc.HTTPNotFound(explanation=e.format_message())

        # Return 400 if service.binary is not nova-compute.
        # Before the earlier PUT handlers were made cells-aware, you could
        # technically disable a nova-scheduler service, although that doesn't
        # really do anything within Nova and is just confusing. Now trying to
        # do that will fail as a nova-scheduler service won't have a host
        # mapping so you'll get a 404. In this new microversion, we close that
        # old gap and make sure you can only enable/disable and set forced_down
        # on nova-compute services since those are the only ones that make
        # sense to update for those operations.
        if service.binary != 'nova-compute':
            msg = (_('Updating a %(binary)s service is not supported. Only '
                     'nova-compute services can be updated.') % {
                         'binary': service.binary
                     })
            raise webob.exc.HTTPBadRequest(explanation=msg)

        # Now determine the update to perform based on the body. We are
        # intentionally not using _perform_action or the other old-style
        # action functions.
        if 'status' in body:
            # This is a status update for either enabled or disabled.
            if body['status'] == 'enabled':

                # Fail if 'disabled_reason' was requested when enabling the
                # service since those two combined don't make sense.
                if body.get('disabled_reason'):
                    msg = _("Specifying 'disabled_reason' with status "
                            "'enabled' is invalid.")
                    raise webob.exc.HTTPBadRequest(explanation=msg)

                service.disabled = False
                service.disabled_reason = None
            elif body['status'] == 'disabled':
                service.disabled = True
                # The disabled reason is optional.
                service.disabled_reason = body.get('disabled_reason')

        # This is intentionally not an elif, i.e. it's in addition to the
        # status update.
        if 'forced_down' in body:
            service.forced_down = strutils.bool_from_string(
                body['forced_down'], strict=True)

        # Check to see if anything was actually updated since the schema does
        # not define any required fields.
        if not service.obj_what_changed():
            msg = _("No updates were requested. Fields 'status' or "
                    "'forced_down' should be specified.")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        # Now save our updates to the service record in the database.
        service.save()

        # Return the full service record details.
        additional_fields = ['forced_down']
        return {
            'service': self._get_service_detail(service, additional_fields,
                                                req)
        }
Esempio n. 50
0
    def get_base_parser(self):
        parser = ZunClientArgumentParser(
            prog='zun',
            description=__doc__.strip(),
            epilog='See "zun help COMMAND" '
            'for help on a specific command.',
            add_help=False,
            formatter_class=OpenStackHelpFormatter,
        )

        # Global arguments
        parser.add_argument('-h',
                            '--help',
                            action='store_true',
                            help=argparse.SUPPRESS)

        parser.add_argument('--version',
                            action='version',
                            version=version.version_info.version_string())

        parser.add_argument('--debug',
                            default=False,
                            action='store_true',
                            help="Print debugging output.")

        parser.add_argument('--os-cache',
                            default=strutils.bool_from_string(
                                cliutils.env('OS_CACHE', default=False)),
                            action='store_true',
                            help="Use the auth token cache. Defaults to False "
                            "if env[OS_CACHE] is not set.")

        parser.add_argument('--os-region-name',
                            metavar='<region-name>',
                            default=os.environ.get('OS_REGION_NAME'),
                            help='Region name. Default=env[OS_REGION_NAME].')

        # TODO(mattf) - add get_timings support to Client
        #        parser.add_argument('--timings',
        #            default=False,
        #            action='store_true',
        #            help="Print call timing info")

        # TODO(mattf) - use timeout
        #        parser.add_argument('--timeout',
        #            default=600,
        #            metavar='<seconds>',
        #            type=positive_non_zero_float,
        #            help="Set HTTP call timeout (in seconds)")

        parser.add_argument('--os-project-id',
                            metavar='<auth-project-id>',
                            default=cliutils.env('OS_PROJECT_ID',
                                                 default=None),
                            help='Defaults to env[OS_PROJECT_ID].')

        parser.add_argument('--os-project-name',
                            metavar='<auth-project-name>',
                            default=cliutils.env('OS_PROJECT_NAME',
                                                 default=None),
                            help='Defaults to env[OS_PROJECT_NAME].')

        parser.add_argument('--os-user-domain-id',
                            metavar='<auth-user-domain-id>',
                            default=cliutils.env('OS_USER_DOMAIN_ID'),
                            help='Defaults to env[OS_USER_DOMAIN_ID].')

        parser.add_argument('--os-user-domain-name',
                            metavar='<auth-user-domain-name>',
                            default=cliutils.env('OS_USER_DOMAIN_NAME'),
                            help='Defaults to env[OS_USER_DOMAIN_NAME].')

        parser.add_argument('--os-project-domain-id',
                            metavar='<auth-project-domain-id>',
                            default=cliutils.env('OS_PROJECT_DOMAIN_ID'),
                            help='Defaults to env[OS_PROJECT_DOMAIN_ID].')

        parser.add_argument('--os-project-domain-name',
                            metavar='<auth-project-domain-name>',
                            default=cliutils.env('OS_PROJECT_DOMAIN_NAME'),
                            help='Defaults to env[OS_PROJECT_DOMAIN_NAME].')

        parser.add_argument('--service-type',
                            metavar='<service-type>',
                            help='Defaults to container for all '
                            'actions.')
        parser.add_argument('--service_type', help=argparse.SUPPRESS)

        parser.add_argument('--endpoint-type',
                            metavar='<endpoint-type>',
                            default=cliutils.env(
                                'OS_ENDPOINT_TYPE',
                                default=DEFAULT_ENDPOINT_TYPE),
                            help='Defaults to env[OS_ENDPOINT_TYPE] or ' +
                            DEFAULT_ENDPOINT_TYPE + '.')
        # NOTE(dtroyer): We can't add --endpoint_type here due to argparse
        #                thinking usage-list --end is ambiguous; but it
        #                works fine with only --endpoint-type present
        #                Go figure.  I'm leaving this here for doc purposes.
        # parser.add_argument('--endpoint_type',
        #    help=argparse.SUPPRESS)

        parser.add_argument('--zun-api-version',
                            metavar='<zun-api-ver>',
                            default=cliutils.env('ZUN_API_VERSION',
                                                 default=DEFAULT_API_VERSION),
                            help='Accepts X, X.Y (where X is major, Y is minor'
                            ' part) or "X.latest", defaults to'
                            ' env[ZUN_API_VERSION].')
        parser.add_argument('--zun_api_version', help=argparse.SUPPRESS)

        parser.add_argument('--os-cacert',
                            metavar='<ca-certificate>',
                            default=cliutils.env('OS_CACERT', default=None),
                            help='Specify a CA bundle file to use in '
                            'verifying a TLS (https) server certificate. '
                            'Defaults to env[OS_CACERT].')
        parser.add_argument('--os-cert',
                            metavar='<ca-certificate>',
                            default=cliutils.env('OS_CERT', default=None),
                            help='Specify a client certificate file (for '
                            'client auth). '
                            'Defaults to env[OS_CERT].')
        parser.add_argument('--os-key',
                            metavar='<ca-certificate>',
                            default=cliutils.env('OS_KEY', default=None),
                            help='Specify a client certificate key file (for '
                            'client auth). '
                            'Defaults to env[OS_KEY].')

        parser.add_argument('--bypass-url',
                            metavar='<bypass-url>',
                            default=cliutils.env('BYPASS_URL', default=None),
                            dest='bypass_url',
                            help="Use this API endpoint instead of the "
                            "Service Catalog.")
        parser.add_argument('--bypass_url', help=argparse.SUPPRESS)

        parser.add_argument('--insecure',
                            default=cliutils.env('ZUNCLIENT_INSECURE',
                                                 default=False),
                            action='store_true',
                            help="Do not verify https connections")

        if profiler:
            parser.add_argument('--profile',
                                metavar='HMAC_KEY',
                                default=cliutils.env('OS_PROFILE',
                                                     default=None),
                                help='HMAC key to use for encrypting context '
                                'data for performance profiling of '
                                'operation. This key should be the '
                                'value of the HMAC key configured for '
                                'the OSprofiler middleware in zun; it '
                                'is specified in the Zun configuration '
                                'file at "/etc/zun/zun.conf". Without '
                                'the key, profiling functions will not '
                                'be triggered even if OSprofiler is '
                                'enabled on the server side.')

        # The auth-system-plugins might require some extra options
        auth.load_auth_system_opts(parser)

        return parser
Esempio n. 51
0
    def _get_opts_from_specs(self, opts, specs):
        qos = {}
        for k, value in specs.iteritems():
            # Get the scope, if using scope format
            key_split = k.split(':')
            if len(key_split) == 1:
                scope = None
                key = key_split[0]
            else:
                scope = key_split[0]
                key = key_split[1]

            # We generally do not look at capabilities in the driver, but
            # protocol is a special case where the user asks for a given
            # protocol and we want both the scheduler and the driver to act
            # on the value.
            if ((not scope or scope == 'capabilities') and
                    key == 'storage_protocol'):
                scope = None
                key = 'protocol'
                words = value.split()
                if not (words and len(words) == 2 and words[0] == '<in>'):
                    LOG.error(_LE('Protocol must be specified as '
                                  '\'<in> iSCSI\' or \'<in> FC\'.'))
                del words[0]
                value = words[0]

            # We generally do not look at capabilities in the driver, but
            # replication is a special case where the user asks for
            # a volume to be replicated, and we want both the scheduler and
            # the driver to act on the value.
            if ((not scope or scope == 'capabilities') and
               key == 'replication'):
                scope = None
                key = 'replication'
                words = value.split()
                if not (words and len(words) == 2 and words[0] == '<is>'):
                    LOG.error(_LE('Replication must be specified as '
                                  '\'<is> True\' or \'<is> False\'.'))
                del words[0]
                value = words[0]

            # Add the QoS.
            if scope and scope == 'qos':
                if key in self.svc_qos_keys.keys():
                    try:
                        type_fn = self.svc_qos_keys[key]['type']
                        value = type_fn(value)
                        qos[key] = value
                    except ValueError:
                        continue

            # Any keys that the driver should look at should have the
            # 'drivers' scope.
            if scope and scope != 'drivers':
                continue
            if key in opts:
                this_type = type(opts[key]).__name__
                if this_type == 'int':
                    value = int(value)
                elif this_type == 'bool':
                    value = strutils.bool_from_string(value)
                opts[key] = value
        if len(qos) != 0:
            opts['qos'] = qos
        return opts
Esempio n. 52
0
File: api.py Progetto: dinghb/manila
    def create(self,
               context,
               name=None,
               description=None,
               share_type_ids=None,
               source_share_group_snapshot_id=None,
               share_network_id=None,
               share_group_type_id=None):
        """Create new share group."""

        share_group_snapshot = None
        original_share_group = None
        # NOTE(gouthamr): share_server_id is inherited from the
        # parent share group if a share group snapshot is specified,
        # else, it will be set in the share manager.
        share_server_id = None
        if source_share_group_snapshot_id:
            share_group_snapshot = self.db.share_group_snapshot_get(
                context, source_share_group_snapshot_id)
            if share_group_snapshot['status'] != constants.STATUS_AVAILABLE:
                msg = (_("Share group snapshot status must be %s.") %
                       constants.STATUS_AVAILABLE)
                raise exception.InvalidShareGroupSnapshot(reason=msg)

            original_share_group = self.db.share_group_get(
                context, share_group_snapshot['share_group_id'])
            share_type_ids = [
                s['share_type_id'] for s in original_share_group['share_types']
            ]
            share_network_id = original_share_group['share_network_id']
            share_server_id = original_share_group['share_server_id']

        # Get share_type_objects
        share_type_objects = []
        driver_handles_share_servers = None
        for share_type_id in (share_type_ids or []):
            try:
                share_type_object = share_types.get_share_type(
                    context, share_type_id)
            except exception.ShareTypeNotFound:
                msg = _("Share type with id %s could not be found.")
                raise exception.InvalidInput(msg % share_type_id)
            share_type_objects.append(share_type_object)

            extra_specs = share_type_object.get('extra_specs')
            if extra_specs:
                share_type_handle_ss = strutils.bool_from_string(
                    extra_specs.get(
                        constants.ExtraSpecs.DRIVER_HANDLES_SHARE_SERVERS))
                if driver_handles_share_servers is None:
                    driver_handles_share_servers = share_type_handle_ss
                elif not driver_handles_share_servers == share_type_handle_ss:
                    # NOTE(ameade): if the share types have conflicting values
                    #  for driver_handles_share_servers then raise bad request
                    msg = _("The specified share_types cannot have "
                            "conflicting values for the "
                            "driver_handles_share_servers extra spec.")
                    raise exception.InvalidInput(reason=msg)

                if (not share_type_handle_ss) and share_network_id:
                    msg = _("When using a share types with the "
                            "driver_handles_share_servers extra spec as "
                            "False, a share_network_id must not be provided.")
                    raise exception.InvalidInput(reason=msg)

        try:
            if share_network_id:
                self.db.share_network_get(context, share_network_id)
        except exception.ShareNetworkNotFound:
            msg = _("The specified share network does not exist.")
            raise exception.InvalidInput(reason=msg)

        if (driver_handles_share_servers
                and not (source_share_group_snapshot_id or share_network_id)):
            msg = _("When using a share type with the "
                    "driver_handles_share_servers extra spec as "
                    "True, a share_network_id must be provided.")
            raise exception.InvalidInput(reason=msg)

        try:
            share_group_type = self.db.share_group_type_get(
                context, share_group_type_id)
        except exception.ShareGroupTypeNotFound:
            msg = _("The specified share group type %s does not exist.")
            raise exception.InvalidInput(reason=msg % share_group_type_id)

        supported_share_types = set(
            [x['share_type_id'] for x in share_group_type['share_types']])

        if not set(share_type_ids or []) <= supported_share_types:
            msg = _("The specified share types must be a subset of the share "
                    "types supported by the share group type.")
            raise exception.InvalidInput(reason=msg)

        options = {
            'share_group_type_id': share_group_type_id,
            'source_share_group_snapshot_id': source_share_group_snapshot_id,
            'share_network_id': share_network_id,
            'share_server_id': share_server_id,
            'name': name,
            'description': description,
            'user_id': context.user_id,
            'project_id': context.project_id,
            'status': constants.STATUS_CREATING,
            'share_types': share_type_ids or supported_share_types
        }
        if original_share_group:
            options['host'] = original_share_group['host']

        share_group = self.db.share_group_create(context, options)

        try:
            if share_group_snapshot:
                members = self.db.share_group_snapshot_members_get_all(
                    context, source_share_group_snapshot_id)
                for member in members:
                    share = self.db.share_get(context, member['share_id'])
                    share_type = share_types.get_share_type(
                        context, share['share_type_id'])
                    member['share_instance'] = self.db.share_instance_get(
                        context,
                        member['share_instance_id'],
                        with_share_data=True)
                    self.share_api.create(context,
                                          member['share_proto'],
                                          member['size'],
                                          None,
                                          None,
                                          share_group_id=share_group['id'],
                                          share_group_snapshot_member=member,
                                          share_type=share_type,
                                          share_network_id=share_network_id)
        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_group_destroy(context.elevated(),
                                            share_group['id'])

        request_spec = {'share_group_id': share_group['id']}
        request_spec.update(options)
        request_spec['share_types'] = share_type_objects
        request_spec['resource_type'] = share_group_type

        if share_group_snapshot and original_share_group:
            self.share_rpcapi.create_share_group(context, share_group,
                                                 original_share_group['host'])
        else:
            self.scheduler_rpcapi.create_share_group(
                context,
                share_group_id=share_group['id'],
                request_spec=request_spec,
                filter_properties={})

        return share_group
Esempio n. 53
0
 def validate(value):
     try:
         return strutils.bool_from_string(value, strict=True)
     except ValueError as e:
         # raise Invalid to return 400 (BadRequest) in the API
         raise exception.Invalid(e)
Esempio n. 54
0
 def password(self):
     if self._validate_string(self.args.os_password):
         return self.args.os_password
     verify_pass = (strutils.bool_from_string(
         cliutils.env("OS_VERIFY_PASSWORD")))
     return self._prompt_password(verify_pass)
Esempio n. 55
0
 def to_schema_type(self, value):
     try:
         return strutils.bool_from_string(str(value), strict=True)
     except ValueError:
         msg = _("The value '%s' is not a valid Boolean") % value
         raise exc.ESchema(message=msg)
Esempio n. 56
0
 def _extract_dns_hide_counts(self, ctxt, request):
     ctxt.hide_counts = False
     value = request.headers.get('OpenStack-DNS-Hide-Counts')
     if value:
         ctxt.hide_counts = strutils.bool_from_string(value)
Esempio n. 57
0
def bool_from_env(key, strict=False, default=False):
    value = os.environ.get(key)
    return strutils.bool_from_string(value, strict=strict, default=default)
Esempio n. 58
0
 def coerce(self, obj, attr, value):
     return strutils.bool_from_string(value,
                                      strict=True,
                                      default=self._default)
Esempio n. 59
0
    def _volume_upload_image(self, req, id, body):
        """Uploads the specified volume to image service."""
        context = req.environ['cinder.context']
        params = body['os-volume_upload_image']
        req_version = req.api_version_request
        if not params.get("image_name"):
            msg = _("No image_name was specified in request.")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        force = params.get('force', 'False')
        try:
            force = strutils.bool_from_string(force, strict=True)
        except ValueError as error:
            err_msg = encodeutils.exception_to_unicode(error)
            msg = _("Invalid value for 'force': '%s'") % err_msg
            raise webob.exc.HTTPBadRequest(explanation=msg)

        # Not found exception will be handled at the wsgi level
        volume = self.volume_api.get(context, id)

        context.authorize(policy.UPLOAD_IMAGE_POLICY)
        # check for valid disk-format
        disk_format = params.get("disk_format", "raw")
        if not image_utils.validate_disk_format(disk_format):
            msg = _("Invalid disk-format '%(disk_format)s' is specified. "
                    "Allowed disk-formats are %(allowed_disk_formats)s.") % {
                        "disk_format": disk_format,
                        "allowed_disk_formats": ", ".join(
                            image_utils.VALID_DISK_FORMATS)
                    }
            raise webob.exc.HTTPBadRequest(explanation=msg)

        image_metadata = {
            "container_format": params.get("container_format", "bare"),
            "disk_format": disk_format,
            "name": params["image_name"]
        }

        if volume.encryption_key_id:
            # Clone volume encryption key: the current key cannot
            # be reused because it will be deleted when the volume is
            # deleted.
            # TODO(eharney): Currently, there is no mechanism to remove
            # these keys, because Glance will not delete the key from
            # Barbican when the image is deleted.
            encryption_key_id = self._key_manager.store(
                context,
                self._key_manager.get(context, volume.encryption_key_id))

            image_metadata['cinder_encryption_key_id'] = encryption_key_id

        if req_version >= mv.get_api_version(mv.UPLOAD_IMAGE_PARAMS):

            image_metadata['visibility'] = params.get('visibility', 'private')
            image_metadata['protected'] = params.get('protected', 'False')

            if image_metadata['visibility'] == 'public':
                context.authorize(policy.UPLOAD_PUBLIC_POLICY)

            image_metadata['protected'] = (utils.get_bool_param(
                'protected', image_metadata))

        try:
            response = self.volume_api.copy_volume_to_image(
                context, volume, image_metadata, force)
        except exception.InvalidVolume as error:
            raise webob.exc.HTTPBadRequest(explanation=error.msg)
        except ValueError as error:
            raise webob.exc.HTTPBadRequest(explanation=six.text_type(error))
        except messaging.RemoteError as error:
            msg = "%(err_type)s: %(err_msg)s" % {
                'err_type': error.exc_type,
                'err_msg': error.value
            }
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except Exception as error:
            raise webob.exc.HTTPBadRequest(explanation=six.text_type(error))
        return {'os-volume_upload_image': response}
Esempio n. 60
0
 def test_other_bool_from_string(self):
     self.assertFalse(strutils.bool_from_string(None))
     self.assertFalse(strutils.bool_from_string(mock.Mock()))