Use keystoneauth1.loading instead of specifying V2 or V3 of keystone

In devstack, there is an error:
Not Found (HTTP 404) (Request-ID: req-c5b74593-ecd6-4c06-9db1-b1fa9c124fc1).
This is a keystone authentication failure.
Use keystoneauth1.load.get_plugin_loader to load and discovery dynamically
without explicitly specifying V2 or V3 of keystone.

Change-Id: Ic43d7c194387a4063b38a11e1a1c850aaaf713c0
This commit is contained in:
gengchc2 2018-09-21 00:17:44 -07:00
parent 77e63223f0
commit 60aa9ec5dd
3 changed files with 171 additions and 60 deletions

View File

View File

@ -0,0 +1,142 @@
# Copyright (c) 2018 ZTE Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import mock
from keystoneauth1 import loading as kaloading
from freezerclient.v2 import client
class TestClientMock(unittest.TestCase):
@mock.patch.object(kaloading.session, 'Session', autospec=True)
@mock.patch.object(kaloading, 'get_plugin_loader', autospec=True)
def test_client_new(self, mock_ks_loader, mock_ks_session):
session = mock_ks_session.return_value.load_from_options.return_value
mock_ks_loader.return_value.load_from_options.return_value = 'auth'
c = client.Client(endpoint='blabla', auth_url='blabla')
self.assertIsInstance(c, client.Client)
self.assertEqual(session, c.session)
@mock.patch.object(kaloading.session, 'Session', autospec=True)
@mock.patch.object(kaloading, 'get_plugin_loader', autospec=True)
def test_client_new_with_kwargs_session(self, mock_ks_loader,
mock_ks_session):
mock_ks_loader.return_value.load_from_options.return_value = 'auth'
mock_session = mock.Mock()
kwargs = {'token': 'alpha',
'username': 'bravo',
'password': 'charlie',
'tenant_name': 'delta',
'auth_url': 'echo',
'endpoint': 'golf',
'session': mock_session}
c = client.Client(**kwargs)
self.assertIsInstance(c, client.Client)
self.assertEqual('alpha', c.opts.os_token)
self.assertEqual('bravo', c.opts.os_username)
self.assertEqual('charlie', c.opts.os_password)
self.assertEqual('delta', c.opts.os_tenant_name)
self.assertEqual('echo', c.opts.os_auth_url)
self.assertEqual(mock_session, c._session)
self.assertEqual(mock_session, c.session)
self.assertEqual('golf', c.endpoint)
@mock.patch.object(kaloading.session, 'Session', autospec=True)
@mock.patch.object(kaloading, 'get_plugin_loader', autospec=True)
def test_client_new_with_kwargs_usename_password(self, mock_ks_loader,
mock_ks_session):
session = mock_ks_session.return_value.load_from_options.return_value
mock_ks_loader.return_value.load_from_options.return_value = 'auth'
kwargs = {'auth_url': 'one',
'project_id': 'two',
'tenant_name': 'three',
'project_name': 'four',
'user_domain_id': 'five',
'user_domain_name': 'six',
'project_domain_id': 'senven',
'project_domain_name': 'eight',
'username': 'nine',
'password': 'ten'}
c = client.Client(**kwargs)
self.assertIsInstance(c, client.Client)
self.assertEqual('one', c.opts.os_auth_url)
self.assertEqual('two', c.opts.os_project_id)
self.assertEqual('three', c.opts.os_tenant_name)
self.assertEqual('four', c.opts.os_project_name)
self.assertEqual('five', c.opts.os_user_domain_id)
self.assertEqual('six', c.opts.os_user_domain_name)
self.assertEqual('senven', c.opts.os_project_domain_id)
self.assertEqual('eight', c.opts.os_project_domain_name)
self.assertEqual('nine', c.opts.os_username)
self.assertEqual('ten', c.opts.os_password)
self.assertEqual(session, c.session)
@mock.patch.object(kaloading.session, 'Session', autospec=True)
@mock.patch.object(kaloading, 'get_plugin_loader', autospec=True)
def test_client_new_with_kwargs_token(self, mock_ks_loader,
mock_ks_session):
session = mock_ks_session.return_value.load_from_options.return_value
mock_ks_loader.return_value.load_from_options.return_value = 'auth'
kwargs = {'auth_url': 'one',
'project_id': 'two',
'tenant_name': 'three',
'project_name': 'four',
'user_domain_id': 'five',
'user_domain_name': 'six',
'project_domain_id': 'senven',
'project_domain_name': 'eight',
'token': 'nine'}
c = client.Client(**kwargs)
self.assertIsInstance(c, client.Client)
self.assertEqual('one', c.opts.os_auth_url)
self.assertEqual('two', c.opts.os_project_id)
self.assertEqual('three', c.opts.os_tenant_name)
self.assertEqual('four', c.opts.os_project_name)
self.assertEqual('five', c.opts.os_user_domain_id)
self.assertEqual('six', c.opts.os_user_domain_name)
self.assertEqual('senven', c.opts.os_project_domain_id)
self.assertEqual('eight', c.opts.os_project_domain_name)
self.assertEqual('nine', c.opts.os_token)
self.assertEqual(session, c.session)
@mock.patch.object(kaloading.session, 'Session', autospec=True)
@mock.patch.object(kaloading, 'get_plugin_loader', autospec=True)
def test_get_token(self, mock_ks_loader, mock_ks_session):
mock_ks_loader.return_value.load_from_options.return_value = 'auth'
mock_session = mock.Mock()
mock_session.get_token.return_value = 'antaniX2'
c = client.Client(session=mock_session, endpoint='justtest',
auth_url='blabla')
self.assertIsInstance(c, client.Client)
self.assertEqual(c.auth_token, 'antaniX2')
@mock.patch('freezerclient.v2.client.socket')
@mock.patch.object(kaloading.session, 'Session', autospec=True)
@mock.patch.object(kaloading, 'get_plugin_loader', autospec=True)
def test_get_client_id(self, mock_ks_loader, mock_ks_session,
mock_socket):
mock_ks_loader.return_value.load_from_options.return_value = 'auth'
mock_socket.gethostname.return_value = 'parmenide'
mock_session = mock.Mock()
mock_session.get_project_id.return_value = 'H2O'
c = client.Client(session=mock_session, endpoint='justtest',
auth_url='blabla')
self.assertIsInstance(c, client.Client)
self.assertEqual(c.client_id, 'H2O_parmenide')

View File

@ -14,9 +14,7 @@
import socket
from keystoneauth1.identity import v2
from keystoneauth1.identity import v3
from keystoneauth1 import session as ksa_session
from keystoneauth1 import loading as kaloading
from freezerclient import utils
from freezerclient.v2.managers import actions
@ -28,58 +26,6 @@ from freezerclient.v2.managers import sessions
FREEZER_SERVICE_TYPE = 'backup'
def guess_auth_version(opts):
"""Guess keystone version to connect to"""
if opts.os_identity_api_version == '3':
return '3'
elif opts.os_identity_api_version == '2.0':
return '2.0'
elif opts.os_auth_url.endswith('v3'):
return '3'
elif opts.os_auth_url.endswith('v2.0'):
return '2.0'
raise Exception('Please provide valid keystone auth url with valid'
' keystone api version to use')
def get_auth_plugin(opts):
"""Create the right keystone connection depending on the version
for the api, if username/password and token are provided, username and
password takes precedence.
"""
auth_version = guess_auth_version(opts)
if opts.os_username:
if auth_version == '3':
return v3.Password(auth_url=opts.os_auth_url,
username=opts.os_username,
password=opts.os_password,
project_name=opts.os_project_name,
user_domain_name=opts.os_user_domain_name,
user_domain_id=opts.os_user_domain_id,
project_domain_name=opts.os_project_domain_name,
project_domain_id=opts.os_project_domain_id,
project_id=opts.os_project_id)
elif auth_version == '2.0':
return v2.Password(auth_url=opts.os_auth_url,
username=opts.os_username,
password=opts.os_password,
tenant_name=opts.os_tenant_name)
elif opts.os_token:
if auth_version == '3':
return v3.Token(auth_url=opts.os_auth_url,
token=opts.os_token,
project_name=opts.os_project_name,
project_domain_name=opts.os_project_domain_name,
project_domain_id=opts.os_project_domain_id,
project_id=opts.os_project_id)
elif auth_version == '2.0':
return v2.Token(auth_url=opts.os_auth_url,
token=opts.os_token,
tenant_name=opts.os_tenant_name)
raise Exception('Unable to determine correct auth method, please provide'
' either username or token')
class Client(object):
"""Client for the OpenStack Disaster Recovery v1 API.
"""
@ -164,11 +110,34 @@ class Client(object):
def session(self):
if self._session:
return self._session
auth_plugin = get_auth_plugin(self.opts)
return ksa_session.Session(auth=auth_plugin,
verify=(self.cacert or
not self.opts.insecure),
cert=self.cert)
auth_type = 'password'
auth_kwargs = {
'auth_url': self.opts.os_auth_url,
'project_id': self.opts.os_project_id,
'tenant_name': self.opts.os_tenant_name,
'project_name': self.opts.os_project_name,
'user_domain_id': self.opts.os_user_domain_id,
'user_domain_name': self.opts.os_user_domain_name,
'project_domain_id': self.opts.os_project_domain_id,
'project_domain_name': self.opts.os_project_domain_name,
}
if self.opts.os_username and self.opts.os_password:
auth_kwargs.update({
'username': self.opts.os_username,
'password': self.opts.os_password,
})
elif self.opts.os_token:
auth_type = 'token'
auth_kwargs.update({
'token': self.opts.os_token,
})
loader = kaloading.get_plugin_loader(auth_type)
auth_plugin = loader.load_from_options(**auth_kwargs)
# Let keystoneauth do the necessary parameter conversions
session = kaloading.session.Session().load_from_options(
auth=auth_plugin, insecure=self.opts.insecure, cacert=self.cacert,
cert=self.cert)
return session
@utils.CachedProperty
def endpoint(self):