Example #1
0
def cinderclient(context, microversion=None, skip_version_check=False):
    """Constructs a cinder client object for making API requests.

    :param context: The nova request context for auth.
    :param microversion: Optional microversion to check against the client.
        This implies that Cinder v3 is required for any calls that require a
        microversion. If the microversion is not available, this method will
        raise an CinderAPIVersionNotAvailable exception.
    :param skip_version_check: If True and a specific microversion is
        requested, the version discovery check is skipped and the microversion
        is used directly. This should only be used if a previous check for the
        same microversion was successful.
    """
    global _SESSION

    if not _SESSION:
        _SESSION = ks_loading.load_session_from_conf_options(
            CONF, nova.conf.cinder.cinder_group.name)

    url = None
    endpoint_override = None

    auth = service_auth.get_auth_plugin(context)
    service_type, service_name, interface = CONF.cinder.catalog_info.split(':')

    service_parameters = {'service_type': service_type,
                          'service_name': service_name,
                          'interface': interface,
                          'region_name': CONF.cinder.os_region_name}

    if CONF.cinder.endpoint_template:
        url = CONF.cinder.endpoint_template % context.to_dict()
        endpoint_override = url
    else:
        url = _SESSION.get_endpoint(auth, **service_parameters)

    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinder_client.get_volume_api_from_url(url)

    if version != '3':
        raise exception.UnsupportedCinderAPIVersion(version=version)

    version = '3.0'
    # Check to see a specific microversion is requested and if so, can it
    # be handled by the backing server.
    if microversion is not None:
        if skip_version_check:
            version = microversion
        else:
            version = _check_microversion(url, microversion)

    return cinder_client.Client(version,
                                session=_SESSION,
                                auth=auth,
                                endpoint_override=endpoint_override,
                                connect_retries=CONF.cinder.http_retries,
                                global_request_id=context.global_id,
                                **service_parameters)
Example #2
0
def cinder(context):
    url = context.session.get_endpoint(service_type=CONF.cinder_service_type)
    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinderclient.get_volume_api_from_url(url)
    return cinderclient.Client(version, session=context.session,
                               service_type=CONF.cinder_service_type)
Example #3
0
def cinderclient(context,
                 microversion=None,
                 skip_version_check=False,
                 check_only=False):
    """Constructs a cinder client object for making API requests.

    :param context: The nova request context for auth.
    :param microversion: Optional microversion to check against the client.
        This implies that Cinder v3 is required for any calls that require a
        microversion. If the microversion is not available, this method will
        raise an CinderAPIVersionNotAvailable exception.
    :param skip_version_check: If True and a specific microversion is
        requested, the version discovery check is skipped and the microversion
        is used directly. This should only be used if a previous check for the
        same microversion was successful.
    :param check_only: If True, don't build the actual client; just do the
        setup and version checking.
    :raises: UnsupportedCinderAPIVersion if a major version other than 3 is
        requested.
    :raises: CinderAPIVersionNotAvailable if microversion checking is requested
        and the specified microversion is higher than what the service can
        handle.
    :returns: A cinderclient.client.Client wrapper, unless check_only is False.
    """

    endpoint_override = None
    auth, service_parameters, url = _get_cinderclient_parameters(context)

    if CONF.cinder.endpoint_template:
        endpoint_override = url

    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinder_client.get_volume_api_from_url(url)

    if version != '3':
        raise exception.UnsupportedCinderAPIVersion(version=version)

    version = '3.0'
    # Check to see a specific microversion is requested and if so, can it
    # be handled by the backing server.
    if microversion is not None:
        if skip_version_check:
            version = microversion
        else:
            version = _check_microversion(context, url, microversion)

    if check_only:
        return

    return cinder_client.Client(version,
                                session=_SESSION,
                                auth=auth,
                                endpoint_override=endpoint_override,
                                connect_retries=CONF.cinder.http_retries,
                                global_request_id=context.global_id,
                                **service_parameters)
Example #4
0
File: cinder.py Project: mahak/nova
def cinderclient(context, microversion=None, skip_version_check=False,
                 check_only=False):
    """Constructs a cinder client object for making API requests.

    :param context: The nova request context for auth.
    :param microversion: Optional microversion to check against the client.
        This implies that Cinder v3 is required for any calls that require a
        microversion. If the microversion is not available, this method will
        raise an CinderAPIVersionNotAvailable exception.
    :param skip_version_check: If True and a specific microversion is
        requested, the version discovery check is skipped and the microversion
        is used directly. This should only be used if a previous check for the
        same microversion was successful.
    :param check_only: If True, don't build the actual client; just do the
        setup and version checking.
    :raises: UnsupportedCinderAPIVersion if a major version other than 3 is
        requested.
    :raises: CinderAPIVersionNotAvailable if microversion checking is requested
        and the specified microversion is higher than what the service can
        handle.
    :returns: A cinderclient.client.Client wrapper, unless check_only is False.
    """

    endpoint_override = None
    auth, service_parameters, url = _get_cinderclient_parameters(context)

    if CONF.cinder.endpoint_template:
        endpoint_override = url

    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinder_client.get_volume_api_from_url(url)

    if version != '3':
        raise exception.UnsupportedCinderAPIVersion(version=version)

    version = '3.0'
    # Check to see a specific microversion is requested and if so, can it
    # be handled by the backing server.
    if microversion is not None:
        if skip_version_check:
            version = microversion
        else:
            version = _check_microversion(context, url, microversion)

    if check_only:
        return

    return cinder_client.Client(version,
                                session=_SESSION,
                                auth=auth,
                                endpoint_override=endpoint_override,
                                connect_retries=CONF.cinder.http_retries,
                                global_request_id=context.global_id,
                                **service_parameters)
Example #5
0
def cinderclient(context):
    global _SESSION

    if not _SESSION:
        _SESSION = ks_loading.load_session_from_conf_options(
            CONF, nova.conf.cinder.cinder_group.name)

    url = None
    endpoint_override = None

    auth = service_auth.get_auth_plugin(context)
    service_type, service_name, interface = CONF.cinder.catalog_info.split(':')

    service_parameters = {
        'service_type': service_type,
        'service_name': service_name,
        'interface': interface,
        'region_name': CONF.cinder.os_region_name
    }

    if CONF.cinder.endpoint_template:
        url = CONF.cinder.endpoint_template % context.to_dict()
        endpoint_override = url
    else:
        url = _SESSION.get_endpoint(auth, **service_parameters)

    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinder_client.get_volume_api_from_url(url)

    if version == '1':
        raise exception.UnsupportedCinderAPIVersion(version=version)

    if version == '2':
        LOG.warning("The support for the Cinder API v2 is deprecated, please "
                    "upgrade to Cinder API v3.")

    if version == '3':
        # TODO(ildikov): Add microversion support for picking up the new
        # attach/detach API that was added in 3.27.
        version = '3.0'

    return cinder_client.Client(version,
                                session=_SESSION,
                                auth=auth,
                                endpoint_override=endpoint_override,
                                connect_retries=CONF.cinder.http_retries,
                                global_request_id=context.global_id,
                                **service_parameters)
Example #6
0
def cinderclient(context):
    global _SESSION
    global _V1_ERROR_RAISED

    if not _SESSION:
        _SESSION = session.Session.load_from_conf_options(CONF, CINDER_OPT_GROUP)

    url = None
    endpoint_override = None

    auth = context.get_auth_plugin()
    service_type, service_name, interface = CONF.cinder.catalog_info.split(":")

    service_parameters = {
        "service_type": service_type,
        "service_name": service_name,
        "interface": interface,
        "region_name": CONF.cinder.os_region_name,
    }

    if CONF.cinder.endpoint_template:
        url = CONF.cinder.endpoint_template % context.to_dict()
        endpoint_override = url
    else:
        url = _SESSION.get_endpoint(auth, **service_parameters)

    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinder_client.get_volume_api_from_url(url)

    if version == "1" and not _V1_ERROR_RAISED:
        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)
        _V1_ERROR_RAISED = True

    return cinder_client.Client(
        version,
        session=_SESSION,
        auth=auth,
        endpoint_override=endpoint_override,
        connect_retries=CONF.cinder.http_retries,
        **service_parameters
    )
Example #7
0
def cinderclient(context):
    global _SESSION

    if not _SESSION:
        _SESSION = ks_loading.load_session_from_conf_options(
            CONF, nova.conf.cinder.cinder_group.name)

    url = None
    endpoint_override = None

    auth = service_auth.get_auth_plugin(context)
    service_type, service_name, interface = CONF.cinder.catalog_info.split(':')

    service_parameters = {'service_type': service_type,
                          'service_name': service_name,
                          'interface': interface,
                          'region_name': CONF.cinder.os_region_name}

    if CONF.cinder.endpoint_template:
        url = CONF.cinder.endpoint_template % context.to_dict()
        endpoint_override = url
    else:
        url = _SESSION.get_endpoint(auth, **service_parameters)

    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinder_client.get_volume_api_from_url(url)

    if version == '1':
        raise exception.UnsupportedCinderAPIVersion(version=version)

    if version == '2':
        LOG.warning("The support for the Cinder API v2 is deprecated, please "
                    "upgrade to Cinder API v3.")

    if version == '3':
        # TODO(ildikov): Add microversion support for picking up the new
        # attach/detach API that was added in 3.27.
        version = '3.0'

    return cinder_client.Client(version,
                                session=_SESSION,
                                auth=auth,
                                endpoint_override=endpoint_override,
                                connect_retries=CONF.cinder.http_retries,
                                global_request_id=context.global_id,
                                **service_parameters)
Example #8
0
def cinderclient(context):
    global _SESSION
    global _V1_ERROR_RAISED

    if not _SESSION:
        _SESSION = session.Session.load_from_conf_options(
            CONF, CINDER_OPT_GROUP)

    url = None
    endpoint_override = None

    auth = context.get_auth_plugin()
    service_type, service_name, interface = CONF.cinder.catalog_info.split(':')

    service_parameters = {
        'service_type': service_type,
        'service_name': service_name,
        'interface': interface,
        'region_name': CONF.cinder.os_region_name
    }

    if CONF.cinder.endpoint_template:
        url = CONF.cinder.endpoint_template % context.to_dict()
        endpoint_override = url
    else:
        url = _SESSION.get_endpoint(auth, **service_parameters)

    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinder_client.get_volume_api_from_url(url)

    if version == '1' and not _V1_ERROR_RAISED:
        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)
        _V1_ERROR_RAISED = True

    return cinder_client.Client(version,
                                session=_SESSION,
                                auth=auth,
                                endpoint_override=endpoint_override,
                                connect_retries=CONF.cinder.http_retries,
                                **service_parameters)
Example #9
0
def cinderclient(context):
    global _SESSION
    global _V1_ERROR_RAISED

    if not _SESSION:
        _SESSION = ks_loading.load_session_from_conf_options(
            CONF, nova.conf.cinder.cinder_group.name)

    url = None
    endpoint_override = None

    auth = context.get_auth_plugin()
    service_type, service_name, interface = CONF.cinder.catalog_info.split(':')

    service_parameters = {'service_type': service_type,
                          'service_name': service_name,
                          'interface': interface,
                          'region_name': CONF.cinder.os_region_name}

    if CONF.cinder.endpoint_template:
        url = CONF.cinder.endpoint_template % context.to_dict()
        endpoint_override = url
    else:
        url = _SESSION.get_endpoint(auth, **service_parameters)

    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinder_client.get_volume_api_from_url(url)

    if version == '1' and not _V1_ERROR_RAISED:
        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.warning(msg)
        _V1_ERROR_RAISED = True

    return cinder_client.Client(version,
                                session=_SESSION,
                                auth=auth,
                                endpoint_override=endpoint_override,
                                connect_retries=CONF.cinder.http_retries,
                                **service_parameters)
Example #10
0
def cinderclient(context):
    global _SESSION

    if not _SESSION:
        _SESSION = ks_loading.load_session_from_conf_options(
            CONF, nova.conf.cinder.cinder_group.name)

    url = None
    endpoint_override = None

    auth = service_auth.get_auth_plugin(context)
    service_type, service_name, interface = CONF.cinder.catalog_info.split(':')

    service_parameters = {
        'service_type': service_type,
        'service_name': service_name,
        'interface': interface,
        'region_name': CONF.cinder.os_region_name
    }

    if CONF.cinder.endpoint_template:
        url = CONF.cinder.endpoint_template % context.to_dict()
        endpoint_override = url
    else:
        url = _SESSION.get_endpoint(auth, **service_parameters)

    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinder_client.get_volume_api_from_url(url)

    if version == '1':
        raise exception.UnsupportedCinderAPIVersion(version=version)

    return cinder_client.Client(version,
                                session=_SESSION,
                                auth=auth,
                                endpoint_override=endpoint_override,
                                connect_retries=CONF.cinder.http_retries,
                                **service_parameters)
Example #11
0
def cinderclient(context):
    global _SESSION

    if not _SESSION:
        _SESSION = ks_loading.load_session_from_conf_options(
            CONF, nova.conf.cinder.cinder_group.name)

    url = None
    endpoint_override = None

    auth = service_auth.get_auth_plugin(context)
    service_type, service_name, interface = CONF.cinder.catalog_info.split(':')

    service_parameters = {'service_type': service_type,
                          'service_name': service_name,
                          'interface': interface,
                          'region_name': CONF.cinder.os_region_name}

    if CONF.cinder.endpoint_template:
        url = CONF.cinder.endpoint_template % context.to_dict()
        endpoint_override = url
    else:
        url = _SESSION.get_endpoint(auth, **service_parameters)

    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinder_client.get_volume_api_from_url(url)

    if version == '1':
        raise exception.UnsupportedCinderAPIVersion(version=version)

    return cinder_client.Client(version,
                                session=_SESSION,
                                auth=auth,
                                endpoint_override=endpoint_override,
                                connect_retries=CONF.cinder.http_retries,
                                **service_parameters)
Example #12
0
    def get_legacy_client(self,
                          service_key,
                          client_class=None,
                          interface_key=None,
                          pass_version_arg=True,
                          version=None,
                          min_version=None,
                          max_version=None,
                          **kwargs):
        """Return a legacy OpenStack client object for the given config.

        Most of the OpenStack python-*client libraries have the same
        interface for their client constructors, but there are several
        parameters one wants to pass given a :class:`CloudConfig` object.

        In the future, OpenStack API consumption should be done through
        the OpenStack SDK, but that's not ready yet. This is for getting
        Client objects from python-*client only.

        :param service_key: Generic key for service, such as 'compute' or
                            'network'
        :param client_class: Class of the client to be instantiated. This
                             should be the unversioned version if there
                             is one, such as novaclient.client.Client, or
                             the versioned one, such as
                             neutronclient.v2_0.client.Client if there isn't
        :param interface_key: (optional) Some clients, such as glanceclient
                              only accept the parameter 'interface' instead
                              of 'endpoint_type' - this is a get-out-of-jail
                              parameter for those until they can be aligned.
                              os-client-config understands this to be the
                              case if service_key is image, so this is really
                              only for use with other unknown broken clients.
        :param pass_version_arg: (optional) If a versioned Client constructor
                                 was passed to client_class, set this to
                                 False, which will tell get_client to not
                                 pass a version parameter. os-client-config
                                 already understand that this is the
                                 case for network, so it can be omitted in
                                 that case.
        :param version: (optional) Version string to override the configured
                                   version string.
        :param min_version: (options) Minimum version acceptable.
        :param max_version: (options) Maximum version acceptable.
        :param kwargs: (optional) keyword args are passed through to the
                       Client constructor, so this is in case anything
                       additional needs to be passed in.
        """
        if not client_class:
            client_class = _get_client(service_key)

        interface = self.get_interface(service_key)
        # trigger exception on lack of service
        endpoint = self.get_session_endpoint(service_key,
                                             min_version=min_version,
                                             max_version=max_version)
        endpoint_override = self.get_endpoint(service_key)

        if service_key == 'object-store':
            constructor_kwargs = dict(
                session=self.get_session(),
                os_options=dict(
                    service_type=self.get_service_type(service_key),
                    object_storage_url=endpoint_override,
                    region_name=self.region))
        else:
            constructor_kwargs = dict(
                session=self.get_session(),
                service_name=self.get_service_name(service_key),
                service_type=self.get_service_type(service_key),
                endpoint_override=endpoint_override,
                region_name=self.region)

        if service_key == 'image':
            # os-client-config does not depend on glanceclient, but if
            # the user passed in glanceclient.client.Client, which they
            # would need to do if they were requesting 'image' - then
            # they necessarily have glanceclient installed
            from glanceclient.common import utils as glance_utils
            endpoint, detected_version = glance_utils.strip_version(endpoint)
            # If the user has passed in a version, that's explicit, use it
            if not version:
                version = detected_version
            # If the user has passed in or configured an override, use it.
            # Otherwise, ALWAYS pass in an endpoint_override becuase
            # we've already done version stripping, so we don't want version
            # reconstruction to happen twice
            if not endpoint_override:
                constructor_kwargs['endpoint_override'] = endpoint
        constructor_kwargs.update(kwargs)
        if pass_version_arg and service_key != 'object-store':
            if not version:
                version = self.get_api_version(service_key)
            if not version and service_key == 'volume':
                from cinderclient import client as cinder_client
                version = cinder_client.get_volume_api_from_url(endpoint)
            # Temporary workaround while we wait for python-openstackclient
            # to be able to handle 2.0 which is what neutronclient expects
            if service_key == 'network' and version == '2':
                version = '2.0'
            if service_key == 'identity':
                # Workaround for bug#1513839
                if 'endpoint' not in constructor_kwargs:
                    endpoint = self.get_session_endpoint('identity')
                    constructor_kwargs['endpoint'] = endpoint
            if service_key == 'network':
                constructor_kwargs['api_version'] = version
            elif service_key == 'baremetal':
                if version != '1':
                    # Set Ironic Microversion
                    constructor_kwargs['os_ironic_api_version'] = version
                # Version arg is the major version, not the full microstring
                constructor_kwargs['version'] = version[0]
            else:
                constructor_kwargs['version'] = version
            if min_version and min_version > float(version):
                raise exceptions.OpenStackConfigVersionException(
                    "Minimum version {min_version} requested but {version}"
                    " found".format(min_version=min_version, version=version),
                    version=version)
            if max_version and max_version < float(version):
                raise exceptions.OpenStackConfigVersionException(
                    "Maximum version {max_version} requested but {version}"
                    " found".format(max_version=max_version, version=version),
                    version=version)
        if service_key == 'database':
            # TODO(mordred) Remove when https://review.openstack.org/314032
            # has landed and released. We're passing in a Session, but the
            # trove Client object has username and password as required
            # args
            constructor_kwargs['username'] = None
            constructor_kwargs['password'] = None

        if not interface_key:
            if service_key in ('image', 'key-manager'):
                interface_key = 'interface'
            elif (service_key == 'identity' and version
                  and version.startswith('3')):
                interface_key = 'interface'
            else:
                interface_key = 'endpoint_type'
        if service_key == 'object-store':
            constructor_kwargs['os_options'][interface_key] = interface
        else:
            constructor_kwargs[interface_key] = interface

        return client_class(**constructor_kwargs)
    def get_legacy_client(
            self, service_key, client_class=None, interface_key=None,
            pass_version_arg=True, version=None, min_version=None,
            max_version=None, **kwargs):
        """Return a legacy OpenStack client object for the given config.

        Most of the OpenStack python-*client libraries have the same
        interface for their client constructors, but there are several
        parameters one wants to pass given a :class:`CloudConfig` object.

        In the future, OpenStack API consumption should be done through
        the OpenStack SDK, but that's not ready yet. This is for getting
        Client objects from python-*client only.

        :param service_key: Generic key for service, such as 'compute' or
                            'network'
        :param client_class: Class of the client to be instantiated. This
                             should be the unversioned version if there
                             is one, such as novaclient.client.Client, or
                             the versioned one, such as
                             neutronclient.v2_0.client.Client if there isn't
        :param interface_key: (optional) Some clients, such as glanceclient
                              only accept the parameter 'interface' instead
                              of 'endpoint_type' - this is a get-out-of-jail
                              parameter for those until they can be aligned.
                              os-client-config understands this to be the
                              case if service_key is image, so this is really
                              only for use with other unknown broken clients.
        :param pass_version_arg: (optional) If a versioned Client constructor
                                 was passed to client_class, set this to
                                 False, which will tell get_client to not
                                 pass a version parameter. os-client-config
                                 already understand that this is the
                                 case for network, so it can be omitted in
                                 that case.
        :param version: (optional) Version string to override the configured
                                   version string.
        :param min_version: (options) Minimum version acceptable.
        :param max_version: (options) Maximum version acceptable.
        :param kwargs: (optional) keyword args are passed through to the
                       Client constructor, so this is in case anything
                       additional needs to be passed in.
        """
        if not client_class:
            client_class = _get_client(service_key)

        interface = self.get_interface(service_key)
        # trigger exception on lack of service
        endpoint = self.get_session_endpoint(
            service_key, min_version=min_version, max_version=max_version)
        endpoint_override = self.get_endpoint(service_key)

        if service_key == 'object-store':
            constructor_kwargs = dict(
                session=self.get_session(),
                os_options=dict(
                    service_type=self.get_service_type(service_key),
                    object_storage_url=endpoint_override,
                    region_name=self.region))
        else:
            constructor_kwargs = dict(
                session=self.get_session(),
                service_name=self.get_service_name(service_key),
                service_type=self.get_service_type(service_key),
                endpoint_override=endpoint_override,
                region_name=self.region)

        if service_key == 'image':
            # os-client-config does not depend on glanceclient, but if
            # the user passed in glanceclient.client.Client, which they
            # would need to do if they were requesting 'image' - then
            # they necessarily have glanceclient installed
            from glanceclient.common import utils as glance_utils
            endpoint, detected_version = glance_utils.strip_version(endpoint)
            # If the user has passed in a version, that's explicit, use it
            if not version:
                version = detected_version
            # If the user has passed in or configured an override, use it.
            # Otherwise, ALWAYS pass in an endpoint_override becuase
            # we've already done version stripping, so we don't want version
            # reconstruction to happen twice
            if not endpoint_override:
                constructor_kwargs['endpoint_override'] = endpoint
        constructor_kwargs.update(kwargs)
        if pass_version_arg and service_key != 'object-store':
            if not version:
                version = self.get_api_version(service_key)
            if not version and service_key == 'volume':
                from cinderclient import client as cinder_client
                version = cinder_client.get_volume_api_from_url(endpoint)
            # Temporary workaround while we wait for python-openstackclient
            # to be able to handle 2.0 which is what neutronclient expects
            if service_key == 'network' and version == '2':
                version = '2.0'
            if service_key == 'identity':
                # Workaround for bug#1513839
                if 'endpoint' not in constructor_kwargs:
                    endpoint = self.get_session_endpoint('identity')
                    constructor_kwargs['endpoint'] = endpoint
            if service_key == 'network':
                constructor_kwargs['api_version'] = version
            elif service_key == 'baremetal':
                if version != '1':
                    # Set Ironic Microversion
                    constructor_kwargs['os_ironic_api_version'] = version
                # Version arg is the major version, not the full microstring
                constructor_kwargs['version'] = version[0]
            else:
                constructor_kwargs['version'] = version
            if min_version and min_version > float(version):
                raise exceptions.OpenStackConfigVersionException(
                    "Minimum version {min_version} requested but {version}"
                    " found".format(min_version=min_version, version=version),
                    version=version)
            if max_version and max_version < float(version):
                raise exceptions.OpenStackConfigVersionException(
                    "Maximum version {max_version} requested but {version}"
                    " found".format(max_version=max_version, version=version),
                    version=version)
        if service_key == 'database':
            # TODO(mordred) Remove when https://review.openstack.org/314032
            # has landed and released. We're passing in a Session, but the
            # trove Client object has username and password as required
            # args
            constructor_kwargs['username'] = None
            constructor_kwargs['password'] = None

        if not interface_key:
            if service_key in ('image', 'key-manager'):
                interface_key = 'interface'
            elif (service_key == 'identity'
                  and version and version.startswith('3')):
                interface_key = 'interface'
            else:
                interface_key = 'endpoint_type'
        if service_key == 'object-store':
            constructor_kwargs['os_options'][interface_key] = interface
        else:
            constructor_kwargs[interface_key] = interface

        return client_class(**constructor_kwargs)
Example #14
0
def cinderclient(context, microversion=None, skip_version_check=False):
    """Constructs a cinder client object for making API requests.

    :param context: The nova request context for auth.
    :param microversion: Optional microversion to check against the client.
        This implies that Cinder v3 is required for any calls that require a
        microversion. If the microversion is not available, this method will
        raise an CinderAPIVersionNotAvailable exception.
    :param skip_version_check: If True and a specific microversion is
        requested, the version discovery check is skipped and the microversion
        is used directly. This should only be used if a previous check for the
        same microversion was successful.
    """
    global _SESSION

    if not _SESSION:
        _SESSION = ks_loading.load_session_from_conf_options(
            CONF, nova.conf.cinder.cinder_group.name)

    url = None
    endpoint_override = None

    auth = service_auth.get_auth_plugin(context)
    service_type, service_name, interface = CONF.cinder.catalog_info.split(':')

    service_parameters = {'service_type': service_type,
                          'service_name': service_name,
                          'interface': interface,
                          'region_name': CONF.cinder.os_region_name}

    if CONF.cinder.endpoint_template:
        url = CONF.cinder.endpoint_template % context.to_dict()
        endpoint_override = url
    else:
        url = _SESSION.get_endpoint(auth, **service_parameters)

    # TODO(jamielennox): This should be using proper version discovery from
    # the cinder service rather than just inspecting the URL for certain string
    # values.
    version = cinder_client.get_volume_api_from_url(url)

    if version == '1':
        raise exception.UnsupportedCinderAPIVersion(version=version)

    if version == '2':
        if microversion is not None:
            # The Cinder v2 API does not support microversions.
            raise exception.CinderAPIVersionNotAvailable(version=microversion)
        LOG.warning("The support for the Cinder API v2 is deprecated, please "
                    "upgrade to Cinder API v3.")

    if version == '3':
        version = '3.0'
        # Check to see a specific microversion is requested and if so, can it
        # be handled by the backing server.
        if microversion is not None:
            if skip_version_check:
                version = microversion
            else:
                version = _check_microversion(url, microversion)

    return cinder_client.Client(version,
                                session=_SESSION,
                                auth=auth,
                                endpoint_override=endpoint_override,
                                connect_retries=CONF.cinder.http_retries,
                                global_request_id=context.global_id,
                                **service_parameters)