def test__parse_versions_response_no_json(self): sot = session.Session(None) retval = mock.Mock() retval.json = mock.Mock(side_effect=ValueError) sot.get = mock.Mock(return_value=retval) self.assertIsNone(sot._parse_versions_response("test"))
def test__get_version_match_fuzzy(self): match = "http://devstack/v2.1" root_endpoint = "http://devstack" versions = [{ "id": "v2.0", "links": [{ "href": "http://devstack/v2/", "rel": "self" }] }, { "id": "v2.1", "links": [{ "href": match, "rel": "self" }] }] sot = session.Session(None) endpoint = session.Session._Endpoint(root_endpoint, versions) # Look for a v2 match, which we internally denote as a minor # version of -1 so we can find the highest matching minor. rv = sot._get_version_match(endpoint, session.Version(2, -1), "service") self.assertEqual(rv, match)
def test__parse_versions_response_no_versions(self): sot = session.Session(None) retval = mock.Mock() retval.json = mock.Mock(return_value={"no_versions_here": "blarga"}) sot.get = mock.Mock(return_value=retval) self.assertIsNone(sot._parse_versions_response("test"))
def setUp(self): super(TestSession, self).setUp() self.xport = fakes.FakeTransport() self.auth = fakes.FakeAuthenticator() self.serv = service_filter.ServiceFilter(service_type='identity') self.sess = session.Session(self.xport, self.auth) self.expected = {'headers': {'X-Auth-Token': self.auth.TOKEN}}
def setUp(self): super(TestObjectStoreProxy, self).setUp() self.transport = transport.Transport(accept=transport.JSON) self.auth = fakes.FakeAuthenticator() self.session = session.Session(self.transport, self.auth) self.proxy = _proxy.Proxy(self.session)
def test__get_endpoint_versions_at_path(self): # This test covers a common case of services deployed under # a path. Additionally, it covers the case of a service # deployed at a path deeper than the root, which will mean # more than one request will need to be made. sc_uri = "https://cloud.com/api/service/v2/project_id" versions_uri = "https://cloud.com/api/service" sot = session.Session(None) sot.get_project_id = mock.Mock(return_value="project_id") responses = [ None, None, session.Session._Endpoint(versions_uri, "versions") ] sot._parse_versions_response = mock.Mock(side_effect=responses) result = sot._get_endpoint_versions("type", sc_uri) sot._parse_versions_response.assert_has_calls([ mock.call("https://cloud.com"), mock.call("https://cloud.com/api"), mock.call(versions_uri) ]) self.assertEqual(result, responses[2]) self.assertTrue(result.needs_project_id)
def test__parse_version(self): sot = session.Session(None) self.assertEqual(sot._parse_version("2"), (2, -1)) self.assertEqual(sot._parse_version("v2"), (2, -1)) self.assertEqual(sot._parse_version("v2.1"), (2, 1)) self.assertRaises(ValueError, sot._parse_version, "lol")
def __init__(self, transport=None, authenticator=None, profile=None, verify=True, user_agent=None, auth_plugin=None, **auth_args): """Create a context for a connection to a cloud provider. A connection needs a transport and an authenticator. The user may pass in a transport and authenticator they want to use or they may pass in the parameters to create a transport and authenticator. The connection creates a :class:`~openstack.session.Session` which uses the transport and authenticator to perform HTTP requests. :param transport: A transport object such as that was previously created. If this parameter is not passed in, the connection will create a transport. :type transport: :class:`~openstack.transport.Transport` :param authenticator: An authenticator derived from the base authenticator plugin that was previously created. Two common authentication identity plugins are :class:`identity_v2 <openstack.auth.identity.v2.Auth>` and :class:`identity_v3 <openstack.auth.identity.v3.Auth>`. If this parameter is not passed in, the connection will create an authenticator. :type authenticator: :class:`~openstack.auth.base.BaseAuthPlugin` :param profile: If the user has any special profiles such as the service name, region, version or visibility, they may be provided in the profile object. If no profiles are provided, the services that appear first in the service catalog will be used. :type profile: :class:`~openstack.profile.Profile` :param bool verify: If a transport is not provided to the connection, this parameter will be used to create a transport. If ``verify`` is set to true, which is the default, the SSL cert will be verified. It can also be set to a CA_BUNDLE path. :param str user_agent: If a transport is not provided to the connection, this parameter will be used when creating a transport. The value given here will be prepended to the default, which is specified in :attr:`~openstack.transport.USER_AGENT`. The resulting ``user_agent`` value is used for the ``User-Agent`` HTTP header. :param str auth_plugin: The name of authentication plugin to use. If the authentication plugin name is not provided, the connection will try to guess what plugin to use based on the *auth_url* in the *auth_args*. Two common values for the plugin would be ``identity_v2`` and ``identity_v3``. :param auth_args: The rest of the parameters provided are assumed to be authentication arguments that are used by the authentication plugin. """ self.transport = self._create_transport(transport, verify, user_agent) self.authenticator = self._create_authenticator( authenticator, auth_plugin, **auth_args) self.session = session.Session(self.transport, self.authenticator, profile) self._open()
def test__get_version_match_fragment(self): root = "http://cloud.net" match = "/v2" versions = [{"id": "v2.0", "links": [{"href": match, "rel": "self"}]}] sot = session.Session(None) endpoint = session.Session._Endpoint(root, versions) rv = sot._get_version_match(endpoint, session.Version(2, 0), "service") self.assertEqual(rv, root + match)
def test_get_endpoint_cached(self): sot = session.Session(None) service_type = "compute" interface = "public" endpoint = "the world wide web" sot.endpoint_cache[(service_type, interface)] = endpoint rv = sot.get_endpoint(service_type=service_type, interface=interface) self.assertEqual(rv, endpoint)
def test_init_with_single_api_request(self): prof = profile.Profile() prof.set_api_version('clustering', '1.2') sot = session.Session(prof) # The assertion acutally tests the property assigned in parent class self.assertEqual({'openstack-api-version': 'clustering 1.2'}, sot.additional_headers)
def test__get_endpoint_versions_exception(self): sot = session.Session(None) fake_response = mock.Mock() fake_response.json = mock.Mock(return_value={}) sot.get = mock.Mock(return_value=fake_response) self.assertRaises(exceptions.EndpointNotFound, sot._get_endpoint_versions, "service", "endpoint")
def test__get_version_match_project_id(self): match = "http://devstack/v2/" project_id = "asdf123" versions = [{"id": "v2.0", "links": [{"href": match, "rel": "self"}]}] sot = session.Session(None) sot.get_project_id = mock.Mock(return_value=project_id) rv = sot._get_version_match(versions, session.Version(2, 0), "service", "root", True) self.assertEqual(rv, match + project_id)
def _create(self): interface = self._get_client_option(CLIENT_NAME, 'endpoint_type') prof = profile.Profile() prof.set_interface(self.CLUSTERING, interface) prof.set_region(self.CLUSTERING, self._get_region_name()) keystone_session = self.context.keystone_session s = session.Session(session=keystone_session, auth=keystone_session.auth, profile=prof) return client.Client(self.VERSION, session=s)
def test_init_with_multi_api_requests(self): prof = profile.Profile() prof.set_api_version('clustering', '1.2') prof.set_api_version('compute', '2.15') sot = session.Session(prof) versions = sot.additional_headers['openstack-api-version'] requests = [req.strip() for req in versions.split(',')] self.assertIn('clustering 1.2', requests) self.assertIn('compute 2.15', requests)
def test__parse_versions_response_with_versions(self): uri = "http://openstack.org" versions = [1, 2, 3] sot = session.Session(None) retval = mock.Mock() retval.json = mock.Mock(return_value={"versions": versions}) sot.get = mock.Mock(return_value=retval) expected = session.Session._Endpoint(uri, versions) self.assertEqual(expected, sot._parse_versions_response(uri))
def setUp(self): super(Test_containers, self).setUp() self.transport = transport.Transport(accept=transport.JSON) self.auth = fakes.FakeAuthenticator() self.session = session.Session(self.transport, self.auth) self.proxy = _proxy.Proxy(self.session) self.containers_body = [] for i in range(3): self.containers_body.append( {six.text_type("name"): six.text_type("container%d" % i)})
def test__parse_versions_response_exception(self): uri = "http://www.openstack.org" level = "DEBUG" sot = session.Session(None) sot.get = mock.Mock(side_effect=exceptions.NotFoundException) with self.assertLogs(logger=session.__name__, level=level) as log: self.assertIsNone(sot._parse_versions_response(uri)) self.assertEqual(len(log.output), 1, "Too many warnings were logged") self.assertEqual( log.output[0], "%s:%s:Looking for versions at %s" % (level, session.__name__, uri))
def test__get_version_match_project_id(self): match = "http://devstack/v2" root_endpoint = "http://devstack" project_id = "asdf123" versions = [{"id": "v2.0", "links": [{"href": match, "rel": "self"}]}] sot = session.Session(None) sot.get_project_id = mock.Mock(return_value=project_id) endpoint = session.Session._Endpoint(root_endpoint, versions, project_id=project_id, needs_project_id=True) rv = sot._get_version_match(endpoint, session.Version(2, 0), "service") match_endpoint = utils.urljoin(match, project_id) self.assertEqual(rv, match_endpoint)
def test__get_endpoint_versions_at_port(self): # This test covers a common case of services deployed under # a port. sc_uri = "https://cloud.com:1234/v3" versions_uri = "https://cloud.com:1234" sot = session.Session(None) sot.get_project_id = mock.Mock(return_value="project_id") responses = [session.Session._Endpoint(versions_uri, "versions")] sot._parse_versions_response = mock.Mock(side_effect=responses) result = sot._get_endpoint_versions("type", sc_uri) sot._parse_versions_response.assert_called_once_with(versions_uri) self.assertEqual(result, responses[0]) self.assertFalse(result.needs_project_id)
def test__get_endpoint_versions_at_subdomain(self): # This test covers a common case of services deployed under # subdomains. Additionally, it covers the case of a service # deployed at the root, which will be the first request made # for versions. sc_uri = "https://service.cloud.com/v1/" versions_uri = "https://service.cloud.com" sot = session.Session(None) sot.get_project_id = mock.Mock(return_value="project_id") responses = [session.Session._Endpoint(versions_uri, "versions")] sot._parse_versions_response = mock.Mock(side_effect=responses) result = sot._get_endpoint_versions("type", sc_uri) sot._parse_versions_response.assert_called_once_with(versions_uri) self.assertEqual(result, responses[0]) self.assertFalse(result.needs_project_id)
def test__get_version_match_exact(self): match = "http://devstack/v2/" versions = [{ "id": "v2.0", "links": [{ "href": match, "rel": "self" }] }, { "id": "v2.1", "links": [{ "href": "http://devstack/v2.1/", "rel": "self" }] }] sot = session.Session(None) rv = sot._get_version_match(versions, session.Version(2, 0), "service", "root", False) self.assertEqual(rv, match)
def test__get_endpoint_versions_with_domain_scope(self): # This test covers a common case of services deployed under # subdomains. Additionally, it covers the case of getting endpoint # versions with domain scope token sc_uri = "https://service.cloud.com/identity" versions_uri = "https://service.cloud.com" sot = session.Session(None) # Project id is None when domain scope session present sot.get_project_id = mock.Mock(return_value=None) responses = [session.Session._Endpoint(versions_uri, "versions")] sot._parse_versions_response = mock.Mock(side_effect=responses) result = sot._get_endpoint_versions("type", sc_uri) sot._parse_versions_response.assert_called_once_with(versions_uri) self.assertEqual(result, responses[0]) self.assertFalse(result.needs_project_id) self.assertIsNone(result.project_id)
def setUp(self): super(Test_objects, self).setUp() self.transport = transport.Transport(accept=transport.JSON) self.auth = fakes.FakeAuthenticator() self.session = session.Session(self.transport, self.auth) self.proxy = _proxy.Proxy(self.session) self.container_name = six.text_type("my_container") self.objects_body = [] for i in range(3): self.objects_body.append( {six.text_type("name"): six.text_type("object%d" % i)}) # Returned object bodies have their container inserted. self.returned_objects = [] for ob in self.objects_body: ob[six.text_type("container")] = self.container_name self.returned_objects.append(ob) self.assertEqual(len(self.objects_body), len(self.returned_objects))
def test__get_version_match_exact(self): match = "http://devstack/v2" root_endpoint = "http://devstack" versions = [{ "id": "v2.0", "links": [{ "href": match, "rel": "self" }] }, { "id": "v2.1", "links": [{ "href": "http://devstack/v2.1/", "rel": "self" }] }] sot = session.Session(None) endpoint = session.Session._Endpoint(root_endpoint, versions) rv = sot._get_version_match(endpoint, session.Version(2, 0), "service") self.assertEqual(rv, match)
def _test__get_endpoint_versions(self, body, versions, endpoint=None): sot = session.Session(None) fake_response = mock.Mock() fake_response.json = mock.Mock(return_value=body) sot.get = mock.Mock(return_value=fake_response) if endpoint is None: # default case with port numbers, we strip the path to get base endpoint = 'https://hostname:1234/v2.1/project_id' root = 'https://hostname:1234' else: # otherwise we preserve the whole URI root = endpoint rv = sot._get_endpoint_versions("compute", endpoint) sot.get.assert_called_with(root) self.assertEqual(root, rv[0]) self.assertEqual(versions, rv[1])
def __init__(self, session=None, authenticator=None, profile=None, verify=True, cert=None, user_agent=None, auth_plugin="password", **auth_args): """Create a context for a connection to a cloud provider. A connection needs a transport and an authenticator. The user may pass in a transport and authenticator they want to use or they may pass in the parameters to create a transport and authenticator. The connection creates a :class:`~openstack.session.Session` which uses the profile and authenticator to perform HTTP requests. :param session: A session object compatible with :class:`~openstack.session.Session`. :type session: :class:`~openstack.session.Session` :param authenticator: An authenticator derived from the base authenticator plugin that was previously created. Two common authentication identity plugins are :class:`identity_v2 <openstack.auth.identity.v2.Auth>` and :class:`identity_v3 <openstack.auth.identity.v3.Auth>`. If this parameter is not passed in, the connection will create an authenticator. :type authenticator: :class:`~openstack.auth.base.BaseAuthPlugin` :param profile: If the user has any special profiles such as the service name, region, version or interface, they may be provided in the profile object. If no profiles are provided, the services that appear first in the service catalog will be used. :type profile: :class:`~openstack.profile.Profile` :param bool verify: If a transport is not provided to the connection, this parameter will be used to create a transport. If ``verify`` is set to true, which is the default, the SSL cert will be verified. It can also be set to a CA_BUNDLE path. :param cert: If a transport is not provided to the connection then this parameter will be used to create a transport. `cert` allows to provide a client certificate file path or a tuple with client certificate and key paths. :type cert: str or tuple :param str user_agent: If a transport is not provided to the connection, this parameter will be used when creating a transport. The value given here will be prepended to the default, which is specified in :attr:`~openstack.transport.USER_AGENT`. The resulting ``user_agent`` value is used for the ``User-Agent`` HTTP header. :param str auth_plugin: The name of authentication plugin to use. The default value is ``password``. :param auth_args: The rest of the parameters provided are assumed to be authentication arguments that are used by the authentication plugin. """ self.profile = profile if profile else _profile.Profile() if session: # Make sure it is the right kind of session. A keystoneauth1 # session would work in some ways but show strange errors in # others. E.g. a Resource.find would work with an id but fail when # given a name because it attempts to catch # openstack.exceptions.NotFoundException to signal that a search by # ID failed before trying a search by name, but with a # keystoneauth1 session the lookup by ID raises # keystoneauth1.exceptions.NotFound instead. We need to ensure our # Session class gets used so that our implementation of various # methods always works as we expect. if not isinstance(session, _session.Session): raise exceptions.SDKException( 'Session instance is from %s but must be from %s' % (session.__module__, _session.__name__)) self.session = session else: self.authenticator = self._create_authenticator( authenticator, auth_plugin, **auth_args) self.session = _session.Session(self.profile, auth=self.authenticator, verify=verify, cert=cert, user_agent=user_agent) self._open()
def __init__(self, session=None, authenticator=None, profile=None, verify=True, cert=None, user_agent=None, auth_plugin="password", **auth_args): """Create a context for a connection to a cloud provider. A connection needs a transport and an authenticator. The user may pass in a transport and authenticator they want to use or they may pass in the parameters to create a transport and authenticator. The connection creates a :class:`~openstack.session.Session` which uses the profile and authenticator to perform HTTP requests. :param session: A session object compatible with :class:`~openstack.session.Session`. :type session: :class:`~openstack.session.Session` :param authenticator: An authenticator derived from the base authenticator plugin that was previously created. Two common authentication identity plugins are :class:`identity_v2 <openstack.auth.identity.v2.Auth>` and :class:`identity_v3 <openstack.auth.identity.v3.Auth>`. If this parameter is not passed in, the connection will create an authenticator. :type authenticator: :class:`~openstack.auth.base.BaseAuthPlugin` :param profile: If the user has any special profiles such as the service name, region, version or interface, they may be provided in the profile object. If no profiles are provided, the services that appear first in the service catalog will be used. :type profile: :class:`~openstack.profile.Profile` :param bool verify: If a transport is not provided to the connection, this parameter will be used to create a transport. If ``verify`` is set to true, which is the default, the SSL cert will be verified. It can also be set to a CA_BUNDLE path. :param cert: If a transport is not provided to the connection then this parameter will be used to create a transport. `cert` allows to provide a client certificate file path or a tuple with client certificate and key paths. :type cert: str or tuple :param str user_agent: If a transport is not provided to the connection, this parameter will be used when creating a transport. The value given here will be prepended to the default, which is specified in :attr:`~openstack.transport.USER_AGENT`. The resulting ``user_agent`` value is used for the ``User-Agent`` HTTP header. :param str auth_plugin: The name of authentication plugin to use. The default value is ``password``. :param auth_args: The rest of the parameters provided are assumed to be authentication arguments that are used by the authentication plugin. """ self.authenticator = self._create_authenticator( authenticator, auth_plugin, **auth_args) self.profile = profile if profile else _profile.Profile() self.session = session if session else _session.Session( self.profile, auth=self.authenticator, verify=verify, cert=cert, user_agent=user_agent) self._open()
def test_init_with_no_api_requests(self): prof = profile.Profile() sot = session.Session(prof) self.assertEqual({}, sot.additional_headers)
def test_init_user_agent_set(self): sot = session.Session(None, user_agent="testing/123") self.assertTrue(sot.user_agent.startswith("testing/123 openstacksdk"))