def test_available_versions(self): self.requests.get(BASE_URL, status_code=300, text=V3_VERSION_ENTRY) disc = discover.Discover(auth_url=BASE_URL) versions = disc.available_versions() self.assertEqual(1, len(versions)) self.assertEqual(V3_VERSION, versions[0])
def test_available_cinder_data(self): text = jsonutils.dumps(CINDER_EXAMPLES) self.requests.get(BASE_URL, status_code=300, text=text) v1_url = "%sv1/" % BASE_URL v2_url = "%sv2/" % BASE_URL disc = discover.Discover(auth_url=BASE_URL) versions = disc.version_data() self.assertEqual((1, 0), versions[0]['version']) self.assertEqual('CURRENT', versions[0]['raw_status']) self.assertEqual(v1_url, versions[0]['url']) self.assertEqual((2, 0), versions[1]['version']) self.assertEqual('CURRENT', versions[1]['raw_status']) self.assertEqual(v2_url, versions[1]['url']) version = disc.data_for('v2.0') self.assertEqual((2, 0), version['version']) self.assertEqual('CURRENT', version['raw_status']) self.assertEqual(v2_url, version['url']) version = disc.data_for(1) self.assertEqual((1, 0), version['version']) self.assertEqual('CURRENT', version['raw_status']) self.assertEqual(v1_url, version['url']) self.assertIsNone(disc.url_for('v3')) self.assertEqual(v2_url, disc.url_for('v2')) self.assertEqual(v1_url, disc.url_for('v1'))
def auth(profile=None, **connection_args): ''' Set up keystone credentials. Only intended to be used within Keystone-enabled modules. CLI Example: .. code-block:: bash salt '*' keystone.auth ''' kwargs = _get_kwargs(profile=profile, **connection_args) disc = discover.Discover(auth_url=kwargs['auth_url']) v2_auth_url = disc.url_for('v2.0') v3_auth_url = disc.url_for('v3.0') if v3_auth_url: global _OS_IDENTITY_API_VERSION global _TENANTS _OS_IDENTITY_API_VERSION = 3 _TENANTS = 'projects' kwargs['auth_url'] = v3_auth_url else: kwargs['auth_url'] = v2_auth_url kwargs.pop('user_domain_name') kwargs.pop('project_domain_name') auth = generic.Password(**kwargs) sess = session.Session(auth=auth) ks_cl = disc.create_client(session=sess) return ks_cl
def test_allow_deprecated(self): status = 'deprecated' version_list = [{ 'id': 'v3.0', 'links': [{ 'href': V3_URL, 'rel': 'self' }], 'media-types': V3_MEDIA_TYPES, 'status': status, 'updated': UPDATED }] text = jsonutils.dumps({'versions': version_list}) self.requests_mock.get(BASE_URL, text=text) disc = discover.Discover(auth_url=BASE_URL) # deprecated is allowed by default versions = disc.version_data(allow_deprecated=False) self.assertEqual(0, len(versions)) versions = disc.version_data(allow_deprecated=True) self.assertEqual(1, len(versions)) self.assertEqual(status, versions[0]['raw_status']) self.assertEqual(V3_URL, versions[0]['url']) self.assertEqual((3, 0), versions[0]['version'])
def test_allow_experimental(self): status = 'experimental' version_list = [{ 'id': 'v3.0', 'links': [{ 'href': V3_URL, 'rel': 'self' }], 'media-types': V3_MEDIA_TYPES, 'status': status, 'updated': UPDATED }] body = jsonutils.dumps({'versions': version_list}) httpretty.register_uri(httpretty.GET, BASE_URL, status=200, body=body) disc = discover.Discover(auth_url=BASE_URL) versions = disc.version_data() self.assertEqual(0, len(versions)) versions = disc.version_data(allow_experimental=True) self.assertEqual(1, len(versions)) self.assertEqual(status, versions[0]['raw_status']) self.assertEqual(V3_URL, versions[0]['url']) self.assertEqual((3, 0), versions[0]['version'])
def test_allow_experimental(self): status = 'experimental' version_list = [{ 'id': 'v3.0', 'links': [{ 'href': V3_URL, 'rel': 'self' }], 'media-types': V3_MEDIA_TYPES, 'status': status, 'updated': UPDATED }] text = jsonutils.dumps({'versions': version_list}) self.requests_mock.get(BASE_URL, text=text) # Creating Discover not using session is deprecated. with self.deprecations.expect_deprecations_here(): disc = discover.Discover(auth_url=BASE_URL) versions = disc.version_data() self.assertEqual(0, len(versions)) versions = disc.version_data(allow_experimental=True) self.assertEqual(1, len(versions)) self.assertEqual(status, versions[0]['raw_status']) self.assertEqual(V3_URL, versions[0]['url']) self.assertEqual((3, 0), versions[0]['version'])
def _discover_auth_versions(session, auth_url): # discover the API versions the server is supporting based on the # given URL v2_auth_url = None v3_auth_url = None try: ks_discover = discover.Discover(session=session, auth_url=auth_url) v2_auth_url = ks_discover.url_for('2.0') v3_auth_url = ks_discover.url_for('3.0') except ks_exc.DiscoveryFailure: raise except exceptions.ClientException: # Identity service may not support discovery. In that case, # try to determine version from auth_url url_parts = urlparse.urlparse(auth_url) (scheme, netloc, path, params, query, fragment) = url_parts path = path.lower() if path.startswith('/v3'): v3_auth_url = auth_url elif path.startswith('/v2'): v2_auth_url = auth_url else: raise exc.CommandError('Unable to determine the Keystone ' 'version to authenticate with ' 'using the given auth_url.') return v2_auth_url, v3_auth_url
def test_available_keystone_data(self): self.requests_mock.get(BASE_URL, status_code=300, text=V3_VERSION_LIST) # Creating Discover not using session is deprecated. with self.deprecations.expect_deprecations_here(): disc = discover.Discover(auth_url=BASE_URL) versions = disc.version_data() self.assertEqual((2, 0), versions[0]['version']) self.assertEqual('stable', versions[0]['raw_status']) self.assertEqual(V2_URL, versions[0]['url']) self.assertEqual((3, 0), versions[1]['version']) self.assertEqual('stable', versions[1]['raw_status']) self.assertEqual(V3_URL, versions[1]['url']) version = disc.data_for('v3.0') self.assertEqual((3, 0), version['version']) self.assertEqual('stable', version['raw_status']) self.assertEqual(V3_URL, version['url']) version = disc.data_for(2) self.assertEqual((2, 0), version['version']) self.assertEqual('stable', version['raw_status']) self.assertEqual(V2_URL, version['url']) self.assertIsNone(disc.url_for('v4')) self.assertEqual(V3_URL, disc.url_for('v3')) self.assertEqual(V2_URL, disc.url_for('v2'))
def test_ignoring_invalid_lnks(self): version_list = [{'id': 'v3.0', 'links': [{'href': V3_URL, 'rel': 'self'}], 'media-types': V3_MEDIA_TYPES, 'status': 'stable', 'updated': UPDATED}, {'id': 'v3.1', 'media-types': V3_MEDIA_TYPES, 'status': 'stable', 'updated': UPDATED}, {'media-types': V3_MEDIA_TYPES, 'status': 'stable', 'updated': UPDATED, 'links': [{'href': V3_URL, 'rel': 'self'}], }] text = jsonutils.dumps({'versions': version_list}) self.requests.register_uri('GET', BASE_URL, status_code=200, text=text) disc = discover.Discover(auth_url=BASE_URL) # raw_version_data will return all choices, even invalid ones versions = disc.raw_version_data() self.assertEqual(3, len(versions)) # only the version with both id and links will be actually returned versions = disc.version_data() self.assertEqual(1, len(versions))
def test_available_keystone_data(self): self.requests_mock.get(BASE_URL, status_code=300, text=V3_VERSION_LIST) disc = discover.Discover(auth_url=BASE_URL) versions = disc.version_data() self.assertEqual((2, 0), versions[0]['version']) self.assertEqual('stable', versions[0]['raw_status']) self.assertEqual(V2_URL, versions[0]['url']) self.assertEqual((3, 0), versions[1]['version']) self.assertEqual('stable', versions[1]['raw_status']) self.assertEqual(V3_URL, versions[1]['url']) version = disc.data_for('v3.0') self.assertEqual((3, 0), version['version']) self.assertEqual('stable', version['raw_status']) self.assertEqual(V3_URL, version['url']) version = disc.data_for(2) self.assertEqual((2, 0), version['version']) self.assertEqual('stable', version['raw_status']) self.assertEqual(V2_URL, version['url']) self.assertIsNone(disc.url_for('v4')) self.assertEqual(V3_URL, disc.url_for('v3')) self.assertEqual(V2_URL, disc.url_for('v2'))
def Client(version=None, unstable=False, session=None, **kwargs): """Factory function to create a new identity service client. :param tuple version: The required version of the identity API. If specified the client will be selected such that the major version is equivalent and an endpoint provides at least the specified minor version. For example to specify the 3.1 API use (3, 1). :param bool unstable: Accept endpoints not marked as 'stable'. (optional) :param Session session: A session object to be used for communication. If one is not provided it will be constructed from the provided kwargs. (optional) :param kwargs: Additional arguments are passed through to the client that is being created. :returns: New keystone client object (keystoneclient.v2_0.Client or keystoneclient.v3.Client). :raises: DiscoveryFailure if the server's response is invalid :raises: VersionNotAvailable if a suitable client cannot be found. """ if not session: session = client_session.Session.construct(kwargs) d = discover.Discover(session=session, **kwargs) return d.create_client(version=version, unstable=unstable)
def Client(version=None, unstable=False, session=None, **kwargs): """Factory function to create a new identity service client. The returned client will be either a V3 or V2 client. Check the version using the :py:attr:`~keystoneclient.v3.client.Client.version` property or the instance's class (with instanceof). :param tuple version: The required version of the identity API. If specified the client will be selected such that the major version is equivalent and an endpoint provides at least the specified minor version. For example to specify the 3.1 API use ``(3, 1)``. (optional) :param bool unstable: Accept endpoints not marked as 'stable'. (optional) :param session: A session object to be used for communication. If one is not provided it will be constructed from the provided kwargs. (optional) :type session: keystoneclient.session.Session :param kwargs: Additional arguments are passed through to the client that is being created. :returns: New keystone client object. :rtype: :py:class:`keystoneclient.v3.client.Client` or :py:class:`keystoneclient.v2_0.client.Client` :raises keystoneclient.exceptions.DiscoveryFailure: if the server's response is invalid. :raises keystoneclient.exceptions.VersionNotAvailable: if a suitable client cannot be found. """ if not session: session = client_session.Session._construct(kwargs) d = discover.Discover(session=session, **kwargs) return d.create_client(version=version, unstable=unstable)
def _discover_auth_versions(self, session, auth_url): # discover the API versions the server is supporting based on the # given URL v2_auth_url = None v3_auth_url = None try: ks_discover = discover.Discover(session=session, auth_url=auth_url) v2_auth_url = ks_discover.url_for('2.0') v3_auth_url = ks_discover.url_for('3.0') except DiscoveryFailure: # Discovery response mismatch. Raise the error raise except Exception: # Some public clouds throw some other exception or doesn't support # discovery. In that case try to determine version from auth_url # API version from the original URL url_parts = urlparse.urlparse(auth_url) (scheme, netloc, path, params, query, fragment) = url_parts path = path.lower() if path.startswith('/v3'): v3_auth_url = auth_url elif path.startswith('/v2'): v2_auth_url = auth_url else: raise exc.CommandError('Unable to determine the Keystone' ' version to authenticate with ' 'using the given auth_url.') return (v2_auth_url, v3_auth_url)
def auth(profile=None, **connection_args): ''' Set up keystone credentials. Only intended to be used within Keystone-enabled modules. CLI Example: .. code-block:: bash salt '*' keystone.auth ''' __utils__['versions.warn_until']( 'Sodium', ('The keystone module has been deprecated and will be removed in {version}. ' 'Please update to using the keystoneng module'), ) kwargs = _get_kwargs(profile=profile, **connection_args) disc = discover.Discover(auth_url=kwargs['auth_url']) v2_auth_url = disc.url_for('v2.0') v3_auth_url = disc.url_for('v3.0') if v3_auth_url: global _OS_IDENTITY_API_VERSION global _TENANTS _OS_IDENTITY_API_VERSION = 3 _TENANTS = 'projects' kwargs['auth_url'] = v3_auth_url else: kwargs['auth_url'] = v2_auth_url kwargs.pop('user_domain_name') kwargs.pop('project_domain_name') auth = generic.Password(**kwargs) sess = session.Session(auth=auth) ks_cl = disc.create_client(session=sess) return ks_cl
def test_available_keystone_data(self): httpretty.register_uri(httpretty.GET, BASE_URL, status=300, body=V3_VERSION_LIST) disc = discover.Discover(auth_url=BASE_URL) versions = disc.version_data() self.assertEqual((2, 0), versions[0]['version']) self.assertEqual('stable', versions[0]['raw_status']) self.assertEqual(V2_URL, versions[0]['url']) self.assertEqual((3, 0), versions[1]['version']) self.assertEqual('stable', versions[1]['raw_status']) self.assertEqual(V3_URL, versions[1]['url']) version = disc.data_for('v3.0') self.assertEqual((3, 0), version['version']) self.assertEqual('stable', version['raw_status']) self.assertEqual(V3_URL, version['url']) version = disc.data_for(2) self.assertEqual((2, 0), version['version']) self.assertEqual('stable', version['raw_status']) self.assertEqual(V2_URL, version['url']) self.assertIsNone(disc.url_for('v4')) self.assertEqual(V3_URL, disc.url_for('v3')) self.assertEqual(V2_URL, disc.url_for('v2'))
def _member_role_exists(instack_env): # This is a workaround for puppet removing the deprecated _member_ # role on upgrade - if it exists we must not remove role assignments # or trusts stored in the undercloud heat will break if not _stackrc_exists(): instack_env['MEMBER_ROLE_EXISTS'] = 'False' return user, password, tenant, auth_url = _get_auth_values() role_exists = False try: # Note this is made somewhat verbose due to trying to handle # any format auth_url (versionless, v2,0/v3 suffix) auth_plugin_class = auth.get_plugin_class('password') auth_kwargs = { 'auth_url': auth_url, 'username': user, 'password': password, 'project_name': tenant } if 'v2.0' not in auth_url: auth_kwargs.update({ 'project_domain_name': 'default', 'user_domain_name': 'default' }) auth_plugin = auth_plugin_class(**auth_kwargs) sess = session.Session(auth=auth_plugin) disc = discover.Discover(session=sess) c = disc.create_client() role_names = [r.name for r in c.roles.list()] role_exists = '_member_' in role_names except ks_exceptions.ConnectionError: # This will happen on initial deployment, assume False # as no new deployments should have _member_ role_exists = False instack_env['MEMBER_ROLE_EXISTS'] = six.text_type(role_exists)
def test_ignoring_invalid_lnks(self): version_list = [{'id': 'v3.0', 'links': [{'href': V3_URL, 'rel': 'self'}], 'media-types': V3_MEDIA_TYPES, 'status': 'stable', 'updated': UPDATED}, {'id': 'v3.1', 'media-types': V3_MEDIA_TYPES, 'status': 'stable', 'updated': UPDATED}, {'media-types': V3_MEDIA_TYPES, 'status': 'stable', 'updated': UPDATED, 'links': [{'href': V3_URL, 'rel': 'self'}], }] text = jsonutils.dumps({'versions': version_list}) self.requests_mock.get(BASE_URL, text=text) # Creating Discover not using session is deprecated. with self.deprecations.expect_deprecations_here(): disc = discover.Discover(auth_url=BASE_URL) # raw_version_data will return all choices, even invalid ones versions = disc.raw_version_data() self.assertEqual(3, len(versions)) # only the version with both id and links will be actually returned versions = disc.version_data() self.assertEqual(1, len(versions))
def test_available_cinder_data(self): body = jsonutils.dumps(CINDER_EXAMPLES) httpretty.register_uri(httpretty.GET, BASE_URL, status=300, body=body) v1_url = "%sv1/" % BASE_URL v2_url = "%sv2/" % BASE_URL disc = discover.Discover(auth_url=BASE_URL) versions = disc.version_data() self.assertEqual((1, 0), versions[0]['version']) self.assertEqual('CURRENT', versions[0]['raw_status']) self.assertEqual(v1_url, versions[0]['url']) self.assertEqual((2, 0), versions[1]['version']) self.assertEqual('CURRENT', versions[1]['raw_status']) self.assertEqual(v2_url, versions[1]['url']) version = disc.data_for('v2.0') self.assertEqual((2, 0), version['version']) self.assertEqual('CURRENT', version['raw_status']) self.assertEqual(v2_url, version['url']) version = disc.data_for(1) self.assertEqual((1, 0), version['version']) self.assertEqual('CURRENT', version['raw_status']) self.assertEqual(v1_url, version['url']) self.assertIsNone(disc.url_for('v3')) self.assertEqual(v2_url, disc.url_for('v2')) self.assertEqual(v1_url, disc.url_for('v1'))
def auth(profile=None, **connection_args): """ Set up keystone credentials. Only intended to be used within Keystone-enabled modules. CLI Example: .. code-block:: bash salt '*' keystone.auth """ __utils__["versions.warn_until"]( "Phosphorus", ("The keystone module has been deprecated and will be removed in {version}. " "Please update to using the keystoneng module"), ) kwargs = _get_kwargs(profile=profile, **connection_args) disc = discover.Discover(auth_url=kwargs["auth_url"]) v2_auth_url = disc.url_for("v2.0") v3_auth_url = disc.url_for("v3.0") if v3_auth_url: global _OS_IDENTITY_API_VERSION global _TENANTS _OS_IDENTITY_API_VERSION = 3 _TENANTS = "projects" kwargs["auth_url"] = v3_auth_url else: kwargs["auth_url"] = v2_auth_url kwargs.pop("user_domain_name") kwargs.pop("project_domain_name") auth = generic.Password(**kwargs) sess = session.Session(auth=auth) ks_cl = disc.create_client(session=sess) return ks_cl
def _discover_auth_versions(self, session, auth_url): # discover the API versions the server is supporting base on the # given URL v2_auth_url = None v3_auth_url = None try: ks_discover = discover.Discover(session=session, auth_url=auth_url) v2_auth_url = ks_discover.url_for('2.0') v3_auth_url = ks_discover.url_for('3.0') except ks_exc.ClientException as e: # Identity service may not support discover API version. # Lets trying to figure out the API version from the original URL. url_parts = urlparse.urlparse(auth_url) (scheme, netloc, path, params, query, fragment) = url_parts path = path.lower() if path.startswith('/v3'): v3_auth_url = auth_url elif path.startswith('/v2'): v2_auth_url = auth_url else: # not enough information to determine the auth version msg = ('Unable to determine the Keystone version ' 'to authenticate with using the given ' 'auth_url. Identity service may not support API ' 'version discovery. Please provide a versioned ' 'auth_url instead. error=%s') % (e) raise exc.CommandError(msg) return (v2_auth_url, v3_auth_url)
def test_available_cinder_data(self): text = jsonutils.dumps(CINDER_EXAMPLES) self.requests_mock.get(BASE_URL, status_code=300, text=text) v1_url = "%sv1/" % BASE_URL v2_url = "%sv2/" % BASE_URL # Creating Discover not using session is deprecated. with self.deprecations.expect_deprecations_here(): disc = discover.Discover(auth_url=BASE_URL) versions = disc.version_data() self.assertEqual((1, 0), versions[0]['version']) self.assertEqual('CURRENT', versions[0]['raw_status']) self.assertEqual(v1_url, versions[0]['url']) self.assertEqual((2, 0), versions[1]['version']) self.assertEqual('CURRENT', versions[1]['raw_status']) self.assertEqual(v2_url, versions[1]['url']) version = disc.data_for('v2.0') self.assertEqual((2, 0), version['version']) self.assertEqual('CURRENT', version['raw_status']) self.assertEqual(v2_url, version['url']) version = disc.data_for(1) self.assertEqual((1, 0), version['version']) self.assertEqual('CURRENT', version['raw_status']) self.assertEqual(v1_url, version['url']) self.assertIsNone(disc.url_for('v3')) self.assertEqual(v2_url, disc.url_for('v2')) self.assertEqual(v1_url, disc.url_for('v1'))
def test_discovery_fail_for_missing_v3(self): versions = fixture.DiscoveryList(v2=True, v3=False) self.requests_mock.get(BASE_URL, status_code=300, json=versions) disc = discover.Discover(auth_url=BASE_URL) self.assertRaises(exceptions.DiscoveryFailure, disc.create_client, version=(3, 0))
def create_keystone_client(args): discover = keystone_discover.Discover(auth_url=args['auth_url']) for version_data in discover.version_data(): version = version_data['version'] if version[0] <= 2: return keystone_v2.Client(**args) elif version[0] == 3: return keystone_v3.Client(**args)
def test_discovery_fail_for_missing_v3(self): versions = fixture.DiscoveryList(v2=True, v3=False) self.requests_mock.get(BASE_URL, status_code=300, json=versions) # Creating Discover not using session is deprecated. with self.deprecations.expect_deprecations_here(): disc = discover.Discover(auth_url=BASE_URL) self.assertRaises(exceptions.DiscoveryFailure, disc.create_client, version=(3, 0))
def create_keystone_client(args): discover = keystone_discover.Discover(**args) for version_data in discover.version_data(): version = version_data["version"] if version[0] <= 2: return keystone_v2.Client(**args) elif version[0] == 3: return keystone_v3.Client(**args) raise exceptions.RallyException( "Failed to discover keystone version for url %(auth_url)s.", **args)
def test_available_versions(self): httpretty.register_uri(httpretty.GET, BASE_URL, status=300, body=V3_VERSION_ENTRY) disc = discover.Discover(auth_url=BASE_URL) versions = disc.available_versions() self.assertEqual(1, len(versions)) self.assertEqual(V3_VERSION, versions[0])
def test_available_versions(self): self.requests_mock.get(BASE_URL, status_code=300, text=V3_VERSION_ENTRY) disc = discover.Discover(auth_url=BASE_URL) with self.deprecations.expect_deprecations_here(): versions = disc.available_versions() self.assertEqual(1, len(versions)) self.assertEqual(V3_VERSION, versions[0])
def is_keystone_version_available(session, version): """Given a (major, minor) pair, check if the API version is enabled.""" d = keystone_discover.Discover(session) try: d.create_client(version) except (discovery_exc.DiscoveryFailure, discovery_exc.VersionNotAvailable): return False else: return True
def test_discovery_fail_for_missing_v3(self): versions = fixture.DiscoveryList(v2=True, v3=False) httpretty.register_uri(httpretty.GET, BASE_URL, status=300, body=jsonutils.dumps(versions)) disc = discover.Discover(auth_url=BASE_URL) self.assertRaises(exceptions.DiscoveryFailure, disc.create_client, version=(3, 0))
def _get_client(self): creds = func_base.credentials() session_params = {} ks_session = session.Session.construct(session_params) ks_discover = discover.Discover(session=ks_session, auth_url=creds['auth_url']) # At the moment, we use keystone v2 API v2_auth_url = ks_discover.url_for('2.0') return v2_client.Client(username=creds['username'], password=creds['password'], tenant_name=creds['project_name'], auth_url=v2_auth_url)