Ejemplo n.º 1
0
def _validate_server_version(server_start_version, server_end_version):
    """Validates the server version.

    Checks that the 'server_end_version' is greater than the minimum version
    supported by the client. Then checks that the 'server_start_version' is
    less than the maximum version supported by the client.

    :param server_start_version:
    :param server_end_version:
    :return:
    """
    if APIVersion(MIN_VERSION) > server_end_version:
        raise exceptions.UnsupportedVersion(
            _("Server's version is too old. The client's valid version range "
              "is '%(client_min)s' to '%(client_max)s'. The server valid "
              "version range is '%(server_min)s' to '%(server_max)s'.") % {
                  'client_min': MIN_VERSION,
                  'client_max': MAX_VERSION,
                  'server_min': server_start_version.get_string(),
                  'server_max': server_end_version.get_string()
              })
    elif APIVersion(MAX_VERSION) < server_start_version:
        raise exceptions.UnsupportedVersion(
            _("Server's version is too new. The client's valid version range "
              "is '%(client_min)s' to '%(client_max)s'. The server valid "
              "version range is '%(server_min)s' to '%(server_max)s'.") % {
                  'client_min': MIN_VERSION,
                  'client_max': MAX_VERSION,
                  'server_min': server_start_version.get_string(),
                  'server_max': server_end_version.get_string()
              })
Ejemplo n.º 2
0
def discover_version(client, requested_version):
    """Checks ``requested_version`` and returns the most recent version
    supported by both the API and the client.

    :param client: client object
    :param requested_version: requested version represented by APIVersion obj
    :returns: APIVersion
    """

    server_start_version, server_end_version = _get_server_version_range(
        client)

    both_versions_null = not (server_start_version or server_end_version)
    if (not requested_version.is_latest() and
            requested_version != APIVersion('2.0')):
        if both_versions_null:
            raise exceptions.UnsupportedVersion(
                _("Server doesn't support microversions"))
        if not requested_version.matches(server_start_version,
                                         server_end_version):
            raise exceptions.UnsupportedVersion(
                _("The specified version isn't supported by server. The valid "
                  "version range is '%(min)s' to '%(max)s'") % {
                    "min": server_start_version.get_string(),
                    "max": server_end_version.get_string()})
        return requested_version

    if requested_version == APIVersion('2.0'):
        if server_start_version == APIVersion('2.1') or both_versions_null:
            return APIVersion('2.0')
        raise exceptions.UnsupportedVersion(
            _("The server isn't backward compatible with Cinder V2 REST "
              "API"))

    if both_versions_null:
        return APIVersion('2.0')
    if cinderclient.API_MIN_VERSION > server_end_version:
        raise exceptions.UnsupportedVersion(
            _("Server version is too old. The client valid version range is "
              "'%(client_min)s' to '%(client_max)s'. The server valid version "
              "range is '%(server_min)s' to '%(server_max)s'.") % {
                  'client_min': cinderclient.API_MIN_VERSION.get_string(),
                  'client_max': cinderclient.API_MAX_VERSION.get_string(),
                  'server_min': server_start_version.get_string(),
                  'server_max': server_end_version.get_string()})
    elif cinderclient.API_MAX_VERSION < server_start_version:
        raise exceptions.UnsupportedVersion(
            _("Server version is too new. The client valid version range is "
              "'%(client_min)s' to '%(client_max)s'. The server valid version "
              "range is '%(server_min)s' to '%(server_max)s'.") % {
                  'client_min': cinderclient.API_MIN_VERSION.get_string(),
                  'client_max': cinderclient.API_MAX_VERSION.get_string(),
                  'server_min': server_start_version.get_string(),
                  'server_max': server_end_version.get_string()})
    elif cinderclient.API_MAX_VERSION <= server_end_version:
        return cinderclient.API_MAX_VERSION
    elif server_end_version < cinderclient.API_MAX_VERSION:
        return server_end_version
def _validate_requested_version(requested_version,
                                server_start_version,
                                server_end_version):
    """Validates the requested version.

    Checks 'requested_version' is within the min/max range supported by the
    server. If 'requested_version' is not within range then attempts to
    downgrade to 'server_end_version'. Otherwise an UnsupportedVersion
    exception is thrown.

    :param requested_version: requestedversion represented by APIVersion obj
    :param server_start_version: APIVersion object representing server min
    :param server_end_version: APIVersion object representing server max
    """
    valid_version = requested_version
    if not requested_version.matches(server_start_version, server_end_version):
        if server_end_version <= requested_version:
            if (APIVersion(MIN_VERSION) <= server_end_version and
                    server_end_version <= APIVersion(MAX_VERSION)):
                msg = _("Requested version %(requested_version)s is "
                        "not supported. Downgrading requested version "
                        "to %(server_end_version)s.")
                LOG.debug(msg, {
                    "requested_version": requested_version,
                    "server_end_version": server_end_version})
            valid_version = server_end_version
        else:
            raise exceptions.UnsupportedVersion(
                _("The specified version isn't supported by server. The valid "
                  "version range is '%(min)s' to '%(max)s'") % {
                    "min": server_start_version.get_string(),
                    "max": server_end_version.get_string()})

    return valid_version
Ejemplo n.º 4
0
    def get_volume_api_version_from_endpoint(self):
        try:
            version = get_volume_api_from_url(self.get_endpoint())
        except exceptions.UnsupportedVersion as e:
            msg = (_("Service catalog returned invalid url.\n"
                     "%s") % six.text_type(e.message))
            raise exceptions.UnsupportedVersion(msg)

        return version
Ejemplo n.º 5
0
def get_cinder_client_version(context):
    """Parse cinder client version by endpoint url.

    :param context: Nova auth context.
    :return: str value(1 or 2).
    """
    global CINDER_URL
    # FIXME: the cinderclient ServiceCatalog object is mis-named.
    #        It actually contains the entire access blob.
    # Only needed parts of the service catalog are passed in, see
    # nova/context.py.
    compat_catalog = {
        'access': {
            'serviceCatalog': context.service_catalog or []
        }
    }
    sc = service_catalog.ServiceCatalog(compat_catalog)
    if CONF.cinder.endpoint_template:
        url = CONF.cinder.endpoint_template % context.to_dict()
    else:
        info = CONF.cinder.catalog_info
        service_type, service_name, endpoint_type = info.split(':')
        # extract the region if set in configuration
        if CONF.os_region_name:
            attr = 'region'
            filter_value = CONF.os_region_name
        else:
            attr = None
            filter_value = None
        url = sc.url_for(attr=attr,
                         filter_value=filter_value,
                         service_type=service_type,
                         service_name=service_name,
                         endpoint_type=endpoint_type)
    LOG.debug('Cinderclient connection created using URL: %s', url)

    valid_versions = ['v1', 'v2']
    magic_tuple = urlparse.urlsplit(url)
    scheme, netloc, path, query, frag = magic_tuple
    components = path.split("/")

    for version in valid_versions:
        if version in components[1]:
            version = version[1:]

            if not CINDER_URL and version == '1':
                msg = _LW('Cinder V1 API is deprecated as of the Juno '
                          'release, and Nova is still configured to use it. '
                          'Enable the V2 API in Cinder and set '
                          'cinder_catalog_info in nova.conf to use it.')
                LOG.warn(msg)

            CINDER_URL = url
            return version
    msg = _("Invalid client version, must be one of: %s") % valid_versions
    raise cinder_exception.UnsupportedVersion(msg)
Ejemplo n.º 6
0
 def get_volume_api_version_from_endpoint(self):
     magic_tuple = urlparse.urlsplit(self.management_url)
     scheme, netloc, path, query, frag = magic_tuple
     v = path.split("/")[1]
     valid_versions = ['v1', 'v2']
     if v not in valid_versions:
         msg = "Invalid client version '%s'. must be one of: %s" % (
             (v, ', '.join(valid_versions)))
         raise exceptions.UnsupportedVersion(msg)
     return v[1:]
Ejemplo n.º 7
0
def _get_client_class_and_version(version):
    if not isinstance(version, api_versions.APIVersion):
        version = api_versions.get_api_version(version)
    else:
        api_versions.check_major_version(version)
    if version.is_latest():
        raise exceptions.UnsupportedVersion(
            _("The version should be explicit, not latest."))
    return version, importutils.import_class(
        "cinderclient.v%s.client.Client" % version.ver_major)
Ejemplo n.º 8
0
def get_volume_api_from_url(url):
    scheme, netloc, path, query, frag = urlparse.urlsplit(url)
    components = path.split("/")

    for version in _VALID_VERSIONS:
        if version in components:
            return version[1:]

    msg = (_("Invalid url: '%(url)s'. It must include one of: %(version)s.")
        % {'url': url, 'version': ', '.join(_VALID_VERSIONS)})
    raise exceptions.UnsupportedVersion(msg)
Ejemplo n.º 9
0
def get_volume_api_from_url(url):
    scheme, netloc, path, query, frag = urlparse.urlsplit(url)
    components = path.split("/")

    for version in _VALID_VERSIONS:
        if version in components:
            return version[1:]

    msg = "Invalid client version '%s'. must be one of: %s" % (
        (version, ', '.join(_VALID_VERSIONS)))
    raise exceptions.UnsupportedVersion(msg)
Ejemplo n.º 10
0
def get_client_class(version):
    version_map = {
        '1': 'cinderclient.v1.client.Client',
    }
    try:
        client_path = version_map[str(version)]
    except (KeyError, ValueError):
        msg = "Invalid client version '%s'. must be one of: %s" % (
            (version, ', '.join(version_map.keys())))
        raise exceptions.UnsupportedVersion(msg)

    return utils.import_class(client_path)
Ejemplo n.º 11
0
    def get_volume_api_version_from_endpoint(self):
        try:
            version = get_volume_api_from_url(self.management_url)
        except exceptions.UnsupportedVersion as e:
            if self.management_url == self.os_endpoint:
                msg = (_("Invalid url was specified in --os-endpoint %s")
                       % six.text_type(e))
            else:
                msg = (_("Service catalog returned invalid url.\n"
                         "%s") % six.text_type(e))

            raise exceptions.UnsupportedVersion(msg)

        return version
Ejemplo n.º 12
0
def _get_server_version_range(client):
    try:
        versions = client.services.server_api_version()
    except AttributeError:
        # Wrong client was used, translate to something helpful.
        raise exceptions.UnsupportedVersion(
            _('Invalid client version %s to get server version range. Only '
              'the v3 client is supported for this operation.') %
            client.version)

    if not versions:
        return APIVersion(), APIVersion()
    for version in versions:
        if '3.' in version.version:
            return APIVersion(version.min_version), APIVersion(version.version)
Ejemplo n.º 13
0
    def get_volume_api_version_from_endpoint(self):
        try:
            version = get_volume_api_from_url(self.management_url)
        except exceptions.UnsupportedVersion as e:
            if self.management_url == self.bypass_url:
                msg = (_("Invalid url was specified in --os-endpoint or "
                         "environment variable CINDERCLIENT_BYPASS_URL.\n"
                         "%s") % six.text_type(e.message))
            else:
                msg = (_("Service catalog returned invalid url.\n"
                         "%s") % six.text_type(e.message))

            raise exceptions.UnsupportedVersion(msg)

        return version
Ejemplo n.º 14
0
 def _init_cinder(self):
     if self.cinder:
         return  # Already initialised
     for version in CINDER_API_VERSIONS:
         try:
             self.cinder = cinder_client.Client(version,
                                                self.params['username'],
                                                self.params['password'],
                                                self.params['tenant_name'],
                                                self.params['auth_url'])
         except cinder_exceptions.ClientException as exc:
             self.logger.debug(
                 "Failed to instantiate Cinder client" +
                 " for API version '%s': %s", version, exc)
     if self.cinder is None:
         raise cinder_exceptions.UnsupportedVersion()
def check_major_version(api_version):
    """Checks major part of ``APIVersion`` obj is supported.

    :raises cinderclient.exceptions.UnsupportedVersion: if major part is not
                                                      supported
    """
    available_versions = get_available_major_versions()
    if (api_version and str(api_version.ver_major) not in available_versions):
        if len(available_versions) == 1:
            msg = ("Invalid client version '%(version)s'. "
                   "Major part should be '%(major)s'") % {
                "version": api_version.get_string(),
                "major": available_versions[0]}
        else:
            msg = ("Invalid client version '%(version)s'. "
                   "Major part must be one of: '%(major)s'") % {
                "version": api_version.get_string(),
                "major": ", ".join(available_versions)}
        raise exceptions.UnsupportedVersion(msg)
Ejemplo n.º 16
0
def get_cinder_client_version(url):
    """Parse cinder client version by endpoint url.

    :param url: URL for cinder.
    :return: str value(1 or 2).
    """
    # FIXME(jamielennox): Use cinder_client.get_volume_api_from_url when
    # bug #1386232 is fixed.
    valid_versions = ['v1', 'v2']
    scheme, netloc, path, query, frag = urlparse.urlsplit(url)
    components = path.split("/")

    for version in valid_versions:
        if version in components:
            return version[1:]

    msg = "Invalid client version '%s'. must be one of: %s" % (
        (version, ', '.join(valid_versions)))
    raise cinder_exception.UnsupportedVersion(msg)
    def __init__(self, version_str=None):
        """Create an API version object."""
        self.ver_major = 0
        self.ver_minor = 0

        if version_str is not None:
            match = re.match(r"^([1-9]\d*)\.([1-9]\d*|0|latest)$", version_str)
            if match:
                self.ver_major = int(match.group(1))
                if match.group(2) == "latest":
                    # NOTE(andreykurilin): Infinity allows to easily determine
                    # latest version and doesn't require any additional checks
                    # in comparison methods.
                    self.ver_minor = float("inf")
                else:
                    self.ver_minor = int(match.group(2))
            else:
                msg = (_("Invalid format of client version '%s'. "
                       "Expected format 'X.Y', where X is a major part and Y "
                       "is a minor part of version.") % version_str)
                raise exceptions.UnsupportedVersion(msg)