Remove dependency on admin creds
This patch changes the way refstack-client gets keystone service id. Now non-admin creds should be enought for that. This patch adds support for Keystone API V3. Keystone API version selected from tempest.conf Section: 'identity-feature-enabled', key: 'api_v3' Closes-Bug: #1495671 Change-Id: I1f9edffba88cf99c39b2c8b99f792088d35dbd2e
This commit is contained in:
parent
bd2205afc0
commit
ecba34b7dd
@ -37,7 +37,8 @@ import time
|
|||||||
from Crypto.Hash import SHA256
|
from Crypto.Hash import SHA256
|
||||||
from Crypto.PublicKey import RSA
|
from Crypto.PublicKey import RSA
|
||||||
from Crypto.Signature import PKCS1_v1_5
|
from Crypto.Signature import PKCS1_v1_5
|
||||||
from keystoneclient.v2_0 import client as ksclient
|
from keystoneclient.v2_0 import client as ksclient2
|
||||||
|
from keystoneclient.v3 import client as ksclient3
|
||||||
import requests
|
import requests
|
||||||
import requests.exceptions
|
import requests.exceptions
|
||||||
import six.moves
|
import six.moves
|
||||||
@ -126,23 +127,54 @@ class RefstackClient:
|
|||||||
def _get_cpid_from_keystone(self, conf_file):
|
def _get_cpid_from_keystone(self, conf_file):
|
||||||
'''This will get the Keystone service ID which is used as the CPID.'''
|
'''This will get the Keystone service ID which is used as the CPID.'''
|
||||||
try:
|
try:
|
||||||
args = {'auth_url': conf_file.get('identity', 'uri'),
|
# Prefer Keystone V3 API if it is enabled
|
||||||
'username': conf_file.get('identity', 'admin_username'),
|
auth_version = (
|
||||||
'password': conf_file.get('identity', 'admin_password'),
|
'v3' if (conf_file.has_option('identity-feature-enabled',
|
||||||
'insecure': self.args.insecure}
|
'api_v3')
|
||||||
|
and conf_file.get('identity-feature-enabled',
|
||||||
|
'api_v3')
|
||||||
|
and conf_file.has_option('identity', 'uri_v3'))
|
||||||
|
else 'v2')
|
||||||
|
args = {'insecure': self.args.insecure}
|
||||||
|
|
||||||
if self.conf.has_option('identity', 'admin_tenant_id'):
|
auth_args = {
|
||||||
args['tenant_id'] = conf_file.get('identity',
|
'username': conf_file.get('identity', 'username'),
|
||||||
'admin_tenant_id')
|
'password': conf_file.get('identity', 'password')
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.conf.has_option('identity', 'tenant_id'):
|
||||||
|
auth_args['tenant_id'] = conf_file.get('identity',
|
||||||
|
'tenant_id')
|
||||||
else:
|
else:
|
||||||
args['tenant_name'] = conf_file.get('identity',
|
auth_args['tenant_name'] = conf_file.get('identity',
|
||||||
'admin_tenant_name')
|
'tenant_name')
|
||||||
|
|
||||||
client = ksclient.Client(**args)
|
args.update(auth_args)
|
||||||
services = client.services.list()
|
if auth_version == 'v2':
|
||||||
for service in services:
|
args['auth_url'] = conf_file.get('identity', 'uri')
|
||||||
if service.type == "identity":
|
client = ksclient2.Client(**args)
|
||||||
return service.id
|
token = client.tokens.authenticate(**auth_args)
|
||||||
|
for service in token.serviceCatalog:
|
||||||
|
if service['type'] == 'identity':
|
||||||
|
return service['endpoints'][0]['id']
|
||||||
|
elif auth_version == 'v3':
|
||||||
|
args['auth_url'] = conf_file.get('identity', 'uri_v3')
|
||||||
|
if conf_file.has_option('identity', 'domain_name'):
|
||||||
|
args['project_domain_name'] = conf_file.get('identity',
|
||||||
|
'domain_name')
|
||||||
|
args['user_domain_name'] = conf_file.get('identity',
|
||||||
|
'domain_name')
|
||||||
|
if conf_file.has_option('identity', 'region'):
|
||||||
|
args['region_name'] = conf_file.get('identity',
|
||||||
|
'region')
|
||||||
|
client = ksclient3.Client(**args)
|
||||||
|
token = client.auth_ref
|
||||||
|
for service in token['catalog']:
|
||||||
|
if service['type'] == 'identity':
|
||||||
|
return service['id']
|
||||||
|
else:
|
||||||
|
raise ValueError('Auth_version %s is unsupported'
|
||||||
|
'' % auth_version)
|
||||||
|
|
||||||
except ConfigParser.Error as e:
|
except ConfigParser.Error as e:
|
||||||
# Most likely a missing section or option in the config file.
|
# Most likely a missing section or option in the config file.
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
[identity]
|
[identity]
|
||||||
uri = 0.0.0.0:35357
|
auth_version = v2
|
||||||
admin_username = admin
|
uri = 0.0.0.0:35357/v2.0
|
||||||
admin_password = test
|
uri_v3 = 0.0.0.0:35357/v3
|
||||||
admin_tenant_id = admin_tenant_id
|
username = admin
|
||||||
|
password = test
|
||||||
|
tenant_id = admin_tenant_id
|
||||||
|
|
||||||
|
[identity-feature-enabled]
|
||||||
|
api_v2 = true
|
@ -70,15 +70,27 @@ class TestRefstackClient(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
Mock the Keystone client methods.
|
Mock the Keystone client methods.
|
||||||
"""
|
"""
|
||||||
self.mock_identity_service = MagicMock(
|
self.mock_identity_service_v2 = {'type': 'identity',
|
||||||
name='service', **{'type': 'identity', 'id': 'test-id'})
|
'endpoints': [{'id': 'test-id'}]}
|
||||||
self.mock_ks_client = MagicMock(
|
self.mock_identity_service_v3 = {'type': 'identity',
|
||||||
|
'id': 'test-id'}
|
||||||
|
self.mock_ks2_client = MagicMock(
|
||||||
name='ks_client',
|
name='ks_client',
|
||||||
**{'services.list.return_value': [self.mock_identity_service]}
|
**{'tokens.authenticate.return_value.serviceCatalog':
|
||||||
|
[self.mock_identity_service_v2]}
|
||||||
)
|
)
|
||||||
self.ks_client_builder = self.patch(
|
self.mock_ks3_client = MagicMock(
|
||||||
'refstack_client.refstack_client.ksclient.Client',
|
name='ks_client',
|
||||||
return_value=self.mock_ks_client
|
**{'auth_ref':
|
||||||
|
{'catalog': [self.mock_identity_service_v3]}}
|
||||||
|
)
|
||||||
|
self.ks2_client_builder = self.patch(
|
||||||
|
'refstack_client.refstack_client.ksclient2.Client',
|
||||||
|
return_value=self.mock_ks2_client
|
||||||
|
)
|
||||||
|
self.ks3_client_builder = self.patch(
|
||||||
|
'refstack_client.refstack_client.ksclient3.Client',
|
||||||
|
return_value=self.mock_ks3_client
|
||||||
)
|
)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -146,9 +158,9 @@ class TestRefstackClient(unittest.TestCase):
|
|||||||
client._prep_test()
|
client._prep_test()
|
||||||
self.mock_keystone()
|
self.mock_keystone()
|
||||||
cpid = client._get_cpid_from_keystone(client.conf)
|
cpid = client._get_cpid_from_keystone(client.conf)
|
||||||
self.ks_client_builder.assert_called_with(
|
self.ks2_client_builder.assert_called_with(
|
||||||
username='admin', tenant_id='admin_tenant_id',
|
username='admin', tenant_id='admin_tenant_id',
|
||||||
password='test', auth_url='0.0.0.0:35357', insecure=False
|
password='test', auth_url='0.0.0.0:35357/v2.0', insecure=False
|
||||||
)
|
)
|
||||||
self.assertEqual('test-id', cpid)
|
self.assertEqual('test-id', cpid)
|
||||||
|
|
||||||
@ -160,13 +172,13 @@ class TestRefstackClient(unittest.TestCase):
|
|||||||
client = rc.RefstackClient(args)
|
client = rc.RefstackClient(args)
|
||||||
client.tempest_dir = self.test_path
|
client.tempest_dir = self.test_path
|
||||||
client._prep_test()
|
client._prep_test()
|
||||||
client.conf.remove_option('identity', 'admin_tenant_id')
|
client.conf.remove_option('identity', 'tenant_id')
|
||||||
client.conf.set('identity', 'admin_tenant_name', 'admin_tenant_name')
|
client.conf.set('identity', 'tenant_name', 'tenant_name')
|
||||||
self.mock_keystone()
|
self.mock_keystone()
|
||||||
cpid = client._get_cpid_from_keystone(client.conf)
|
cpid = client._get_cpid_from_keystone(client.conf)
|
||||||
self.ks_client_builder.assert_called_with(
|
self.ks2_client_builder.assert_called_with(
|
||||||
username='admin', tenant_name='admin_tenant_name',
|
username='admin', tenant_name='tenant_name',
|
||||||
password='test', auth_url='0.0.0.0:35357', insecure=False
|
password='test', auth_url='0.0.0.0:35357/v2.0', insecure=False
|
||||||
)
|
)
|
||||||
self.assertEqual('test-id', cpid)
|
self.assertEqual('test-id', cpid)
|
||||||
|
|
||||||
@ -182,22 +194,29 @@ class TestRefstackClient(unittest.TestCase):
|
|||||||
client._prep_test()
|
client._prep_test()
|
||||||
self.mock_keystone()
|
self.mock_keystone()
|
||||||
client._get_cpid_from_keystone(client.conf)
|
client._get_cpid_from_keystone(client.conf)
|
||||||
self.ks_client_builder.assert_called_with(
|
self.ks2_client_builder.assert_called_with(
|
||||||
username='admin', tenant_id='admin_tenant_id',
|
username='admin', tenant_id='admin_tenant_id',
|
||||||
password='test', auth_url='0.0.0.0:35357', insecure=True
|
password='test', auth_url='0.0.0.0:35357/v2.0', insecure=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_get_cpid_from_keystone_no_admin_tenant(self):
|
def test_get_cpid_from_keystone_v3(self):
|
||||||
"""
|
"""
|
||||||
Test exit under absence of information about admin tenant info.
|
Test getting the CPID from Keystone API v3.
|
||||||
"""
|
"""
|
||||||
args = rc.parse_cli_args(self.mock_argv(verbose='-vv'))
|
args = rc.parse_cli_args(self.mock_argv())
|
||||||
client = rc.RefstackClient(args)
|
client = rc.RefstackClient(args)
|
||||||
client.tempest_dir = self.test_path
|
client.tempest_dir = self.test_path
|
||||||
client._prep_test()
|
client._prep_test()
|
||||||
client.conf.remove_option('identity', 'admin_tenant_id')
|
client.conf.remove_option('identity', 'tenant_id')
|
||||||
self.assertRaises(SystemExit, client._get_cpid_from_keystone,
|
client.conf.set('identity', 'tenant_name', 'tenant_name')
|
||||||
client.conf)
|
client.conf.set('identity-feature-enabled', 'api_v3', 'true')
|
||||||
|
self.mock_keystone()
|
||||||
|
cpid = client._get_cpid_from_keystone(client.conf)
|
||||||
|
self.ks3_client_builder.assert_called_with(
|
||||||
|
username='admin', tenant_name='tenant_name',
|
||||||
|
password='test', auth_url='0.0.0.0:35357/v3', insecure=False
|
||||||
|
)
|
||||||
|
self.assertEqual('test-id', cpid)
|
||||||
|
|
||||||
def test_form_result_content(self):
|
def test_form_result_content(self):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user