Switch to keystoneauth
move cinderclient to keystoneauth as keystoneclient's auth session, plugins and adapter code has been deprecated. Co-Authored-By: Paulo Ewerton <pauloewerton@lsd.ufcg.edu.br> Co-Authored-By: Sean McGinnis <sean.mcginnis@gmail.com> Co-Authored-By: Jamie Lennox <jamielennox@gmail.com> Change-Id: Id4bf0e2088e8ad99e83cd4f9b8549c2aca1f65a2
This commit is contained in:
parent
b61ec1e6a7
commit
16f83c4a53
cinderclient
requirements.txt@ -30,10 +30,10 @@ import pkgutil
|
||||
import re
|
||||
import six
|
||||
|
||||
from keystoneclient import access
|
||||
from keystoneclient import adapter
|
||||
from keystoneclient.auth.identity import base
|
||||
from keystoneclient import discover
|
||||
from keystoneauth1 import access
|
||||
from keystoneauth1 import adapter
|
||||
from keystoneauth1.identity import base
|
||||
from keystoneauth1 import discover
|
||||
import requests
|
||||
|
||||
from cinderclient import api_versions
|
||||
@ -109,7 +109,7 @@ class SessionClient(adapter.LegacyJsonAdapter):
|
||||
api_versions.update_headers(kwargs["headers"], self.api_version)
|
||||
kwargs.setdefault('authenticated', False)
|
||||
# Note(tpatil): The standard call raises errors from
|
||||
# keystoneclient, here we need to raise the cinderclient errors.
|
||||
# keystoneauth, here we need to raise the cinderclient errors.
|
||||
raise_exc = kwargs.pop('raise_exc', True)
|
||||
resp, body = super(SessionClient, self).request(*args,
|
||||
raise_exc=False,
|
||||
@ -427,7 +427,7 @@ class HTTPClient(object):
|
||||
if resp.status_code == 200: # content must always present
|
||||
try:
|
||||
self.auth_url = url
|
||||
self.auth_ref = access.AccessInfo.factory(resp, body)
|
||||
self.auth_ref = access.create(resp=resp, body=body)
|
||||
self.service_catalog = self.auth_ref.service_catalog
|
||||
|
||||
if extract_token:
|
||||
@ -435,7 +435,7 @@ class HTTPClient(object):
|
||||
|
||||
management_url = self.service_catalog.url_for(
|
||||
region_name=self.region_name,
|
||||
endpoint_type=self.endpoint_type,
|
||||
interface=self.endpoint_type,
|
||||
service_type=self.service_type,
|
||||
service_name=self.service_name)
|
||||
self.management_url = management_url.rstrip('/')
|
||||
@ -444,7 +444,10 @@ class HTTPClient(object):
|
||||
print("Found more than one valid endpoint. Use a more "
|
||||
"restrictive filter")
|
||||
raise
|
||||
except KeyError:
|
||||
except ValueError:
|
||||
# ValueError is raised when you pass an invalid response to
|
||||
# access.create. This should never happen in reality if the
|
||||
# status code is 200.
|
||||
raise exceptions.AuthorizationFailure()
|
||||
except exceptions.EndpointNotFound:
|
||||
print("Could not find any suitable endpoint. Correct region?")
|
||||
|
@ -34,11 +34,12 @@ from cinderclient import utils
|
||||
import cinderclient.auth_plugin
|
||||
from cinderclient._i18n import _
|
||||
|
||||
from keystoneclient import discover
|
||||
from keystoneclient import session
|
||||
from keystoneclient.auth.identity import v2 as v2_auth
|
||||
from keystoneclient.auth.identity import v3 as v3_auth
|
||||
from keystoneclient.exceptions import DiscoveryFailure
|
||||
from keystoneauth1 import discover
|
||||
from keystoneauth1 import loading
|
||||
from keystoneauth1 import session
|
||||
from keystoneauth1.identity import v2 as v2_auth
|
||||
from keystoneauth1.identity import v3 as v3_auth
|
||||
from keystoneauth1.exceptions import DiscoveryFailure
|
||||
import six.moves.urllib.parse as urlparse
|
||||
from oslo_utils import encodeutils
|
||||
from oslo_utils import importutils
|
||||
@ -390,7 +391,7 @@ class OpenStackCinderShell(object):
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
# Register the CLI arguments that have moved to the session object.
|
||||
session.Session.register_cli_options(parser)
|
||||
loading.register_session_argparse_arguments(parser)
|
||||
parser.set_defaults(insecure=utils.env('CINDERCLIENT_INSECURE',
|
||||
default=False))
|
||||
|
||||
@ -468,9 +469,8 @@ class OpenStackCinderShell(object):
|
||||
if hasattr(requests, 'logging'):
|
||||
requests.logging.getLogger(requests.__name__).addHandler(ch)
|
||||
|
||||
# required for logging when using a keystone session
|
||||
self.ks_logger = logging.getLogger("keystoneclient")
|
||||
self.ks_logger.setLevel(logging.DEBUG)
|
||||
ks_logger = logging.getLogger("keystoneauth")
|
||||
ks_logger.setLevel(logging.DEBUG)
|
||||
|
||||
def _delimit_metadata_args(self, argv):
|
||||
"""This function adds -- separator at the appropriate spot
|
||||
@ -788,7 +788,7 @@ class OpenStackCinderShell(object):
|
||||
v2_auth_url = None
|
||||
v3_auth_url = None
|
||||
try:
|
||||
ks_discover = discover.Discover(session=session, auth_url=auth_url)
|
||||
ks_discover = discover.Discover(session=session, url=auth_url)
|
||||
v2_auth_url = ks_discover.url_for('2.0')
|
||||
v3_auth_url = ks_discover.url_for('3.0')
|
||||
except DiscoveryFailure:
|
||||
|
@ -10,7 +10,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from keystoneclient import fixture
|
||||
from keystoneauth1 import fixture
|
||||
|
||||
from cinderclient.tests.unit.fixture_data import base
|
||||
from cinderclient.v1 import client as v1client
|
||||
|
@ -11,19 +11,20 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import logging
|
||||
import json
|
||||
import logging
|
||||
|
||||
import fixtures
|
||||
from keystoneauth1 import adapter
|
||||
from keystoneauth1 import exceptions as keystone_exception
|
||||
import mock
|
||||
import six
|
||||
|
||||
import cinderclient.client
|
||||
import cinderclient.v1.client
|
||||
import cinderclient.v2.client
|
||||
from cinderclient import exceptions
|
||||
from cinderclient.tests.unit import utils
|
||||
from keystoneclient import adapter
|
||||
from keystoneclient import exceptions as keystone_exception
|
||||
|
||||
|
||||
class ClientTest(utils.TestCase):
|
||||
@ -115,7 +116,7 @@ class ClientTest(utils.TestCase):
|
||||
|
||||
mock_response = utils.TestResponse({
|
||||
"status_code": 202,
|
||||
"text": json.dumps(resp),
|
||||
"text": six.b(json.dumps(resp)),
|
||||
})
|
||||
|
||||
# 'request' method of Adaptor will return 202 response
|
||||
@ -155,7 +156,7 @@ class ClientTest(utils.TestCase):
|
||||
|
||||
mock_response = utils.TestResponse({
|
||||
"status_code": 400,
|
||||
"text": json.dumps(resp),
|
||||
"text": six.b(json.dumps(resp)),
|
||||
})
|
||||
|
||||
# 'request' method of Adaptor will return 400 response
|
||||
@ -182,7 +183,7 @@ class ClientTest(utils.TestCase):
|
||||
|
||||
mock_response = utils.TestResponse({
|
||||
"status_code": 413,
|
||||
"text": json.dumps(resp),
|
||||
"text": six.b(json.dumps(resp)),
|
||||
})
|
||||
|
||||
# 'request' method of Adaptor will return 413 response
|
||||
|
@ -12,7 +12,6 @@
|
||||
# limitations under the License.
|
||||
|
||||
import mock
|
||||
|
||||
import requests
|
||||
|
||||
from cinderclient import client
|
||||
@ -24,18 +23,17 @@ fake_response = utils.TestResponse({
|
||||
"status_code": 200,
|
||||
"text": '{"hi": "there"}',
|
||||
})
|
||||
|
||||
fake_response_empty = utils.TestResponse({
|
||||
"status_code": 200,
|
||||
"text": '{"access": {}}'
|
||||
})
|
||||
|
||||
mock_request = mock.Mock(return_value=(fake_response))
|
||||
mock_request_empty = mock.Mock(return_value=(fake_response_empty))
|
||||
|
||||
refused_response = utils.TestResponse({
|
||||
"status_code": 400,
|
||||
"text": '[Errno 111] Connection refused',
|
||||
})
|
||||
refused_mock_request = mock.Mock(return_value=(refused_response))
|
||||
|
||||
bad_400_response = utils.TestResponse({
|
||||
"status_code": 400,
|
||||
"text": '{"error": {"message": "n/a", "details": "Terrible!"}}',
|
||||
"text": '',
|
||||
})
|
||||
bad_400_request = mock.Mock(return_value=(bad_400_response))
|
||||
|
||||
@ -74,6 +72,7 @@ def get_authed_client(retries=0):
|
||||
cl = get_client(retries=retries)
|
||||
cl.management_url = "http://example.com"
|
||||
cl.auth_token = "token"
|
||||
cl.get_service_url = mock.Mock(return_value="http://example.com")
|
||||
return cl
|
||||
|
||||
|
||||
@ -287,24 +286,13 @@ class ClientTest(utils.TestCase):
|
||||
cl = get_client()
|
||||
|
||||
# response must not have x-server-management-url header
|
||||
@mock.patch.object(requests, "request", mock_request_empty)
|
||||
@mock.patch.object(requests, "request", mock_request)
|
||||
def test_auth_call():
|
||||
self.assertRaises(exceptions.AuthorizationFailure,
|
||||
cl.authenticate)
|
||||
|
||||
test_auth_call()
|
||||
|
||||
def test_auth_not_implemented(self):
|
||||
cl = get_client()
|
||||
|
||||
# response must not have x-server-management-url header
|
||||
# {'hi': 'there'} is neither V2 or V3
|
||||
@mock.patch.object(requests, "request", mock_request)
|
||||
def test_auth_call():
|
||||
self.assertRaises(NotImplementedError, cl.authenticate)
|
||||
|
||||
test_auth_call()
|
||||
|
||||
def test_get_retry_timeout_error(self):
|
||||
cl = get_authed_client(retries=1)
|
||||
|
||||
|
@ -16,6 +16,9 @@ import re
|
||||
import sys
|
||||
|
||||
import fixtures
|
||||
import keystoneauth1.exceptions as ks_exc
|
||||
from keystoneauth1.exceptions import DiscoveryFailure
|
||||
from keystoneauth1 import session
|
||||
import mock
|
||||
import pkg_resources
|
||||
import requests_mock
|
||||
@ -31,8 +34,6 @@ from cinderclient.tests.unit.test_auth_plugins import mock_http_request
|
||||
from cinderclient.tests.unit.test_auth_plugins import requested_headers
|
||||
from cinderclient.tests.unit.fixture_data import keystone_client
|
||||
from cinderclient.tests.unit import utils
|
||||
import keystoneclient.exceptions as ks_exc
|
||||
from keystoneclient.exceptions import DiscoveryFailure
|
||||
|
||||
|
||||
class ShellTest(utils.TestCase):
|
||||
@ -103,23 +104,27 @@ class ShellTest(utils.TestCase):
|
||||
@requests_mock.Mocker()
|
||||
def test_version_discovery(self, mocker):
|
||||
_shell = shell.OpenStackCinderShell()
|
||||
sess = session.Session()
|
||||
|
||||
os_auth_url = "https://WrongDiscoveryResponse.discovery.com:35357/v2.0"
|
||||
self.register_keystone_auth_fixture(mocker, os_auth_url)
|
||||
self.assertRaises(DiscoveryFailure, _shell._discover_auth_versions,
|
||||
None, auth_url=os_auth_url)
|
||||
|
||||
self.assertRaises(DiscoveryFailure,
|
||||
_shell._discover_auth_versions,
|
||||
sess,
|
||||
auth_url=os_auth_url)
|
||||
|
||||
os_auth_url = "https://DiscoveryNotSupported.discovery.com:35357/v2.0"
|
||||
self.register_keystone_auth_fixture(mocker, os_auth_url)
|
||||
v2_url, v3_url = _shell._discover_auth_versions(
|
||||
None, auth_url=os_auth_url)
|
||||
v2_url, v3_url = _shell._discover_auth_versions(sess,
|
||||
auth_url=os_auth_url)
|
||||
self.assertEqual(os_auth_url, v2_url, "Expected v2 url")
|
||||
self.assertIsNone(v3_url, "Expected no v3 url")
|
||||
|
||||
os_auth_url = "https://DiscoveryNotSupported.discovery.com:35357/v3.0"
|
||||
self.register_keystone_auth_fixture(mocker, os_auth_url)
|
||||
v2_url, v3_url = _shell._discover_auth_versions(
|
||||
None, auth_url=os_auth_url)
|
||||
v2_url, v3_url = _shell._discover_auth_versions(sess,
|
||||
auth_url=os_auth_url)
|
||||
self.assertEqual(os_auth_url, v3_url, "Expected v3 url")
|
||||
self.assertIsNone(v2_url, "Expected no v2 url")
|
||||
|
||||
@ -142,18 +147,18 @@ class ShellTest(utils.TestCase):
|
||||
for count in range(1, 4):
|
||||
self.list_volumes_on_service(count)
|
||||
|
||||
@mock.patch('keystoneclient.auth.identity.v2.Password')
|
||||
@mock.patch('keystoneclient.adapter.Adapter.get_token',
|
||||
side_effect=ks_exc.ConnectionRefused())
|
||||
@mock.patch('keystoneclient.discover.Discover',
|
||||
side_effect=ks_exc.ConnectionRefused())
|
||||
@mock.patch('keystoneauth1.identity.v2.Password')
|
||||
@mock.patch('keystoneauth1.adapter.Adapter.get_token',
|
||||
side_effect=ks_exc.ConnectFailure())
|
||||
@mock.patch('keystoneauth1.discover.Discover',
|
||||
side_effect=ks_exc.ConnectFailure())
|
||||
@mock.patch('sys.stdin', side_effect=mock.MagicMock)
|
||||
@mock.patch('getpass.getpass', return_value='password')
|
||||
def test_password_prompted(self, mock_getpass, mock_stdin, mock_discover,
|
||||
mock_token, mock_password):
|
||||
self.make_env(exclude='OS_PASSWORD')
|
||||
_shell = shell.OpenStackCinderShell()
|
||||
self.assertRaises(ks_exc.ConnectionRefused, _shell.main, ['list'])
|
||||
self.assertRaises(ks_exc.ConnectFailure, _shell.main, ['list'])
|
||||
mock_getpass.assert_called_with('OS Password: ')
|
||||
# Verify that Password() is called with value of param 'password'
|
||||
# equal to mock_getpass.return_value.
|
||||
@ -223,7 +228,7 @@ class ShellTest(utils.TestCase):
|
||||
|
||||
self.assertEqual(False, _shell.cs.client.verify_cert)
|
||||
|
||||
@mock.patch('keystoneclient.session.Session.__init__',
|
||||
@mock.patch('keystoneauth1.session.Session.__init__',
|
||||
side_effect=RuntimeError())
|
||||
def test_http_client_with_cert(self, mock_session):
|
||||
_shell = shell.OpenStackCinderShell()
|
||||
@ -234,7 +239,7 @@ class ShellTest(utils.TestCase):
|
||||
self.assertRaises(RuntimeError, _shell.main, args)
|
||||
mock_session.assert_called_once_with(cert='minnie', verify=mock.ANY)
|
||||
|
||||
@mock.patch('keystoneclient.session.Session.__init__',
|
||||
@mock.patch('keystoneauth1.session.Session.__init__',
|
||||
side_effect=RuntimeError())
|
||||
def test_http_client_with_cert_and_key(self, mock_session):
|
||||
_shell = shell.OpenStackCinderShell()
|
||||
|
@ -87,25 +87,34 @@ class FixturedTestCase(TestCase):
|
||||
|
||||
|
||||
class TestResponse(requests.Response):
|
||||
"""Class used to wrap requests.Response and provide some
|
||||
convenience to initialize with a dict.
|
||||
"""Class used to wrap requests.Response.
|
||||
|
||||
Provides some convenience to initialize with a dict.
|
||||
"""
|
||||
|
||||
def __init__(self, data):
|
||||
super(TestResponse, self).__init__()
|
||||
self._content = None
|
||||
self._text = None
|
||||
super(TestResponse, self)
|
||||
|
||||
if isinstance(data, dict):
|
||||
self.status_code = data.get('status_code', None)
|
||||
self.headers = data.get('headers', None)
|
||||
self.reason = data.get('reason', '')
|
||||
# Fake the text attribute to streamline Response creation
|
||||
self._text = data.get('text', None)
|
||||
# Fake text and content attributes to streamline Response creation
|
||||
text = data.get('text', None)
|
||||
self._content = text
|
||||
self._text = text
|
||||
else:
|
||||
self.status_code = data
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.__dict__ == other.__dict__
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
return self._content
|
||||
|
||||
@property
|
||||
def text(self):
|
||||
return self._text
|
||||
|
@ -3,7 +3,7 @@
|
||||
# process, which may cause wedges in the gate later.
|
||||
pbr>=1.6 # Apache-2.0
|
||||
PrettyTable<0.8,>=0.7 # BSD
|
||||
python-keystoneclient!=1.8.0,!=2.1.0,>=1.7.0 # Apache-2.0
|
||||
keystoneauth1>=2.7.0 # Apache-2.0
|
||||
requests>=2.10.0 # Apache-2.0
|
||||
simplejson>=2.2.0 # MIT
|
||||
Babel>=2.3.4 # BSD
|
||||
|
Loading…
x
Reference in New Issue
Block a user