Ejemplo n.º 1
0
 def _max_attempts(self):
     max_attempts = CONF.storage_scheduler_max_attempts
     if max_attempts < 1:
         raise exception.InvalidParameterValue(
             err=_("Invalid value for 'storage_scheduler_max_attempts', "
                   "must be >=1"))
     return max_attempts
Ejemplo n.º 2
0
    def get_all(self,
                context,
                search_opts=None,
                marker=None,
                limit=None,
                offset=None,
                sort_keys=None,
                sort_dirs=None):
        check_policy(context, 'get_all')

        search_opts = search_opts or {}

        all_tenants = search_opts.pop('all_tenants', '0')
        if not utils.is_valid_boolstr(all_tenants):
            msg = _("all_tenants must be a boolean, got '%s'.") % all_tenants
            raise exception.InvalidParameterValue(err=msg)

        if context.is_admin and strutils.bool_from_string(all_tenants):
            backups = storage.BackupList.get_all(context, search_opts, marker,
                                                 limit, offset, sort_keys,
                                                 sort_dirs)
        else:
            backups = storage.BackupList.get_all_by_project(
                context, context.project_id, search_opts, marker, limit,
                offset, sort_keys, sort_dirs)

        return backups
Ejemplo n.º 3
0
    def show_target(self, iscsi_target, iqn, **kwargs):
        if iqn is None:
            raise exception.InvalidParameterValue(
                err=_('valid iqn needed for show_target'))

        tid = self._get_target(iqn)
        if tid is None:
            raise exception.NotFound()
Ejemplo n.º 4
0
def get_bool_param(param_string, params):
    param = params.get(param_string, False)
    if not is_valid_boolstr(param):
        msg = _('Value %(param)s for %(param_string)s is not a '
                'boolean.') % {'param': param, 'param_string': param_string}
        raise exception.InvalidParameterValue(err=msg)

    return strutils.bool_from_string(param, strict=True)
Ejemplo n.º 5
0
    def show_target(self, tid, iqn):
        if iqn is None:
            raise exception.InvalidParameterValue(
                err=_('valid iqn needed for show_target'))

        tid = self._get_target(iqn)
        if tid is None:
            raise exception.ISCSITargetHelperCommandFailed(
                error_message="Target not found")
Ejemplo n.º 6
0
    def matches_versioned_method(self, method):
        """Compares this version to that of a versioned method."""

        if type(method) != versioned_method.VersionedMethod:
            msg = _('An API version request must be compared '
                    'to a VersionedMethod object.')
            raise exception.InvalidParameterValue(err=msg)

        return self.matches(method.start_version, method.end_version,
                            method.experimental)
Ejemplo n.º 7
0
    def create(self, req, body):
        """Creates a new snapshot."""
        kwargs = {}
        context = req.environ['storage.context']

        self.assert_valid_body(body, 'snapshot')

        snapshot = body['snapshot']
        kwargs['metadata'] = snapshot.get('metadata', None)

        try:
            volume_id = snapshot['volume_id']
        except KeyError:
            msg = _("'volume_id' must be specified")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            volume = self.volume_api.get(context, volume_id)
        except exception.VolumeNotFound as error:
            raise exc.HTTPNotFound(explanation=error.msg)
        force = snapshot.get('force', False)
        msg = _LI("Create snapshot from volume %s")
        LOG.info(msg, volume_id, context=context)
        self.validate_name_and_description(snapshot)

        # NOTE(thingee): v2 API allows name instead of display_name
        if 'name' in snapshot:
            snapshot['display_name'] = snapshot.pop('name')

        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 exception.InvalidParameterValue(err=msg)

        if force:
            new_snapshot = self.volume_api.create_snapshot_force(
                context, volume, snapshot.get('display_name'),
                snapshot.get('description'), **kwargs)
        else:
            new_snapshot = self.volume_api.create_snapshot(
                context, volume, snapshot.get('display_name'),
                snapshot.get('description'), **kwargs)
        req.cache_db_snapshot(new_snapshot)

        return self._view_builder.detail(req, new_snapshot)
Ejemplo n.º 8
0
    def create(self, req, body):
        """Creates a new snapshot."""
        kwargs = {}
        context = req.environ['storage.context']

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

        snapshot = body['snapshot']
        kwargs['metadata'] = snapshot.get('metadata', None)

        try:
            volume_id = snapshot['volume_id']
        except KeyError:
            msg = _("'volume_id' must be specified")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            volume = self.volume_api.get(context, volume_id)
        except exception.NotFound:
            raise exc.HTTPNotFound()

        force = snapshot.get('force', False)
        msg = _LI("Create snapshot from volume %s")
        LOG.info(msg, volume_id, context=context)

        if not utils.is_valid_boolstr(force):
            msg = _("Invalid value '%s' for force. ") % force
            raise exception.InvalidParameterValue(err=msg)

        if strutils.bool_from_string(force):
            new_snapshot = self.volume_api.create_snapshot_force(
                context, volume, snapshot.get('display_name'),
                snapshot.get('display_description'), **kwargs)
        else:
            new_snapshot = self.volume_api.create_snapshot(
                context, volume, snapshot.get('display_name'),
                snapshot.get('display_description'), **kwargs)
        req.cache_db_snapshot(new_snapshot)

        retval = _translate_snapshot_detail_view(new_snapshot)

        return {'snapshot': retval}
Ejemplo n.º 9
0
    def _parse_ns_output(self, switch_data):
        """Parses name server data.

        Parses nameserver raw data and adds the device port wwns to the list

        :returns: List -- list of device port wwn from ns info
        """
        return_list = []
        for line in switch_data:
            if not(" N " in line):
                continue
            linesplit = line.split()
            if len(linesplit) > 2:
                node_port_wwn = linesplit[2]
                return_list.append(node_port_wwn)
            else:
                msg = _("Malformed show fcns database string: %s") % line
                LOG.error(msg)
                raise exception.InvalidParameterValue(err=msg)
        return return_list
Ejemplo n.º 10
0
    def get_device_mapping_from_network(self, initiator_wwn_list,
                                        target_wwn_list):
        """Provides the initiator/target map for available SAN contexts.

        Looks up fcns database of each fc SAN configured to find logged in
        devices and returns a map of initiator and target port WWNs for each
        fabric.

        :param initiator_wwn_list: List of initiator port WWN
        :param target_wwn_list: List of target port WWN
        :returns: List -- device wwn map in following format
            {
                <San name>: {
                    'initiator_port_wwn_list':
                    ('200000051e55a100', '200000051e55a121'..)
                    'target_port_wwn_list':
                    ('100000051e55a100', '100000051e55a121'..)
                }
            }
        :raises: Exception when connection to fabric is failed
        """
        device_map = {}
        formatted_target_list = []
        formatted_initiator_list = []
        fabric_map = {}
        fabric_names = self.configuration.fc_fabric_names

        if not fabric_names:
            raise exception.InvalidParameterValue(
                err=_("Missing Fibre Channel SAN configuration "
                      "param - fc_fabric_names"))

        fabrics = [x.strip() for x in fabric_names.split(',')]

        LOG.debug("FC Fabric List: %s", fabrics)
        if fabrics:
            for t in target_wwn_list:
                formatted_target_list.append(zm_utils.get_formatted_wwn(t))

            for i in initiator_wwn_list:
                formatted_initiator_list.append(zm_utils.get_formatted_wwn(i))

            for fabric_name in fabrics:
                self.switch_ip = self.fabric_configs[fabric_name].safe_get(
                    'cisco_fc_fabric_address')
                self.switch_user = self.fabric_configs[fabric_name].safe_get(
                    'cisco_fc_fabric_user')
                self.switch_pwd = self.fabric_configs[fabric_name].safe_get(
                    'cisco_fc_fabric_password')
                self.switch_port = self.fabric_configs[fabric_name].safe_get(
                    'cisco_fc_fabric_port')
                zoning_vsan = self.fabric_configs[fabric_name].safe_get(
                    'cisco_zoning_vsan')

                # Get name server data from fabric and find the targets
                # logged in
                nsinfo = ''
                LOG.debug("show fcns database for vsan %s", zoning_vsan)
                nsinfo = self.get_nameserver_info(zoning_vsan)

                LOG.debug("Lookup service:fcnsdatabase-%s", nsinfo)
                LOG.debug("Lookup service:initiator list from caller-%s",
                          formatted_initiator_list)
                LOG.debug("Lookup service:target list from caller-%s",
                          formatted_target_list)
                visible_targets = [
                    x for x in nsinfo if x in formatted_target_list
                ]
                visible_initiators = [
                    x for x in nsinfo if x in formatted_initiator_list
                ]

                if visible_targets:
                    LOG.debug("Filtered targets is: %s", visible_targets)
                    # getting rid of the : before returning
                    for idx, elem in enumerate(visible_targets):
                        elem = str(elem).replace(':', '')
                        visible_targets[idx] = elem
                else:
                    LOG.debug(
                        "No targets are in the fcns database"
                        " for vsan %s", zoning_vsan)

                if visible_initiators:
                    # getting rid of the : before returning ~sk
                    for idx, elem in enumerate(visible_initiators):
                        elem = str(elem).replace(':', '')
                        visible_initiators[idx] = elem
                else:
                    LOG.debug(
                        "No initiators are in the fcns database"
                        " for vsan %s", zoning_vsan)

                fabric_map = {
                    'initiator_port_wwn_list': visible_initiators,
                    'target_port_wwn_list': visible_targets
                }
                device_map[zoning_vsan] = fabric_map
        LOG.debug("Device map for SAN context: %s", device_map)
        return device_map
Ejemplo n.º 11
0
    def get_device_mapping_from_network(self, initiator_wwn_list,
                                        target_wwn_list):
        """Provides the initiator/target map for available SAN contexts.

        Looks up nameserver of each fc SAN configured to find logged in devices
        and returns a map of initiator and target port WWNs for each fabric.

        :param initiator_wwn_list: List of initiator port WWN
        :param target_wwn_list: List of target port WWN
        :returns: List -- device wwn map in following format
            {
                <San name>: {
                    'initiator_port_wwn_list':
                    ('200000051e55a100', '200000051e55a121'..)
                    'target_port_wwn_list':
                    ('100000051e55a100', '100000051e55a121'..)
                }
            }
        :raises: Exception when connection to fabric is failed
        """
        device_map = {}
        formatted_target_list = []
        formatted_initiator_list = []
        fabric_map = {}
        fabric_names = self.configuration.fc_fabric_names
        fabrics = None
        if not fabric_names:
            raise exception.InvalidParameterValue(
                err=_("Missing Fibre Channel SAN configuration "
                      "param - fc_fabric_names"))

        fabrics = [x.strip() for x in fabric_names.split(',')]
        LOG.debug("FC Fabric List: %s", fabrics)
        if fabrics:
            for t in target_wwn_list:
                formatted_target_list.append(fczm_utils.get_formatted_wwn(t))

            for i in initiator_wwn_list:
                formatted_initiator_list.append(
                    fczm_utils.get_formatted_wwn(i))

            for fabric_name in fabrics:
                fabric_ip = self.fabric_configs[fabric_name].safe_get(
                    'fc_fabric_address')

                # Get name server data from fabric and find the targets
                # logged in
                nsinfo = ''
                try:
                    LOG.debug("Getting name server data for "
                              "fabric %s", fabric_ip)
                    conn = self._get_southbound_client(fabric_name)
                    nsinfo = conn.get_nameserver_info()
                except exception.FCSanLookupServiceException:
                    with excutils.save_and_reraise_exception():
                        LOG.error(
                            _LE("Failed collecting name server info from"
                                " fabric %s"), fabric_ip)
                except Exception as e:
                    msg = _("SSH connection failed "
                            "for %(fabric)s with error: %(err)s") % {
                                'fabric': fabric_ip,
                                'err': e
                            }
                    LOG.error(msg)
                    raise exception.FCSanLookupServiceException(message=msg)

                LOG.debug("Lookup service:nsinfo-%s", nsinfo)
                LOG.debug("Lookup service:initiator list from "
                          "caller-%s", formatted_initiator_list)
                LOG.debug("Lookup service:target list from "
                          "caller-%s", formatted_target_list)
                visible_targets = [
                    x for x in nsinfo if x in formatted_target_list
                ]
                visible_initiators = [
                    x for x in nsinfo if x in formatted_initiator_list
                ]

                if visible_targets:
                    LOG.debug("Filtered targets is: %s", visible_targets)
                    # getting rid of the : before returning
                    for idx, elem in enumerate(visible_targets):
                        elem = str(elem).replace(':', '')
                        visible_targets[idx] = elem
                else:
                    LOG.debug("No targets are in the nameserver for SAN %s",
                              fabric_name)

                if visible_initiators:
                    # getting rid of the : before returning ~sk
                    for idx, elem in enumerate(visible_initiators):
                        elem = str(elem).replace(':', '')
                        visible_initiators[idx] = elem
                else:
                    LOG.debug(
                        "No initiators are in the nameserver "
                        "for SAN %s", fabric_name)

                fabric_map = {
                    'initiator_port_wwn_list': visible_initiators,
                    'target_port_wwn_list': visible_targets
                }
                device_map[fabric_name] = fabric_map
        LOG.debug("Device map for SAN context: %s", device_map)
        return device_map
Ejemplo n.º 12
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['storage.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,
                    is_admin_project=context.is_admin)
                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 = utils.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)}