diff --git a/refstack_client/refstack_client.py b/refstack_client/refstack_client.py index 877e62c..465c213 100755 --- a/refstack_client/refstack_client.py +++ b/refstack_client/refstack_client.py @@ -44,6 +44,7 @@ import requests.exceptions import six.moves from subunit_processor import SubunitProcessor from list_parser import TestListParser +import yaml def get_input(): @@ -53,6 +54,13 @@ def get_input(): return raw_input().lower() # pragma: no cover +def read_accounts_yaml(path): + """Reads a set of accounts from the specified file""" + with open(path, 'r') as yaml_file: + accounts = yaml.load(yaml_file) + return accounts + + class RefstackClient: log_format = "%(asctime)s %(name)s:%(lineno)d %(levelname)s %(message)s" @@ -135,16 +143,45 @@ class RefstackClient: 'api_v3') and conf_file.has_option('identity', 'uri_v3')) else 'v2') + + if conf_file.has_option('auth', 'test_accounts_file'): + account_file = os.path.expanduser( + conf_file.get('auth', 'test_accounts_file')) + if not os.path.isfile(account_file): + self.logger.error( + 'Accounts file not found: %s' % account_file) + exit(1) + + accounts = read_accounts_yaml(account_file) + if not accounts: + self.logger.error('Accounts file %s found, ' + 'but was empty.' % account_file) + exit(1) + + account = accounts[0] + username = account.get('username') + password = account.get('password') + tenant_id = account.get('tenant_id') + tenant_name = account.get('tenant_name') + else: + username = conf_file.get('identity', 'username') + password = conf_file.get('identity', 'password') + + if self.conf.has_option('identity', 'tenant_id'): + tenant_id = conf_file.get('identity', 'tenant_id') + else: + tenant_id = None + tenant_name = conf_file.get('identity', 'tenant_name') + args = { 'insecure': self.args.insecure, - 'username': conf_file.get('identity', 'username'), - 'password': conf_file.get('identity', 'password') + 'username': username, + 'password': password } - - if self.conf.has_option('identity', 'tenant_id'): - args['tenant_id'] = conf_file.get('identity', 'tenant_id') + if tenant_id: + args['tenant_id'] = tenant_id else: - args['tenant_name'] = conf_file.get('identity', 'tenant_name') + args['tenant_name'] = tenant_name if auth_version == 'v2': args['auth_url'] = conf_file.get('identity', 'uri') diff --git a/refstack_client/tests/unit/test-accounts.yaml b/refstack_client/tests/unit/test-accounts.yaml new file mode 100644 index 0000000..b294c6e --- /dev/null +++ b/refstack_client/tests/unit/test-accounts.yaml @@ -0,0 +1,5 @@ +- username: 'admin' + tenant_name: 'tenant_name' + password: 'test' + roles: + - 'Member' diff --git a/refstack_client/tests/unit/test_client.py b/refstack_client/tests/unit/test_client.py index c38dec6..3045454 100755 --- a/refstack_client/tests/unit/test_client.py +++ b/refstack_client/tests/unit/test_client.py @@ -182,6 +182,103 @@ class TestRefstackClient(unittest.TestCase): ) self.assertEqual('test-id', cpid) + def test_get_cpid_from_keystone_by_tenant_name_from_account_file(self): + """ + Test getting a CPID from Keystone using an admin tenant name + from an accounts file. + """ + + args = rc.parse_cli_args(self.mock_argv()) + client = rc.RefstackClient(args) + client.tempest_dir = self.test_path + client._prep_test() + client.conf.add_section('auth') + client.conf.set('auth', + 'test_accounts_file', + '%s/test-accounts.yaml' % self.test_path) + self.mock_keystone() + cpid = client._get_cpid_from_keystone(client.conf) + self.ks2_client_builder.assert_called_with( + username='admin', tenant_name='tenant_name', + password='test', auth_url='0.0.0.0:35357/v2.0', insecure=False + ) + self.assertEqual('test-id', cpid) + + def test_get_cpid_from_keystone_by_tenant_id_from_account_file(self): + """ + Test getting a CPID from Keystone using an admin tenant ID + from an accounts file. + """ + + accounts = [ + { + 'username': 'admin', + 'tenant_id': 'tenant_id', + 'password': 'test' + } + ] + self.patch( + 'refstack_client.refstack_client.read_accounts_yaml', + return_value=accounts) + + args = rc.parse_cli_args(self.mock_argv()) + client = rc.RefstackClient(args) + client.tempest_dir = self.test_path + client._prep_test() + client.conf.add_section('auth') + client.conf.set('auth', + 'test_accounts_file', + '%s/test-accounts.yaml' % self.test_path) + self.mock_keystone() + cpid = client._get_cpid_from_keystone(client.conf) + self.ks2_client_builder.assert_called_with( + username='admin', tenant_id='tenant_id', + password='test', auth_url='0.0.0.0:35357/v2.0', insecure=False + ) + self.assertEqual('test-id', cpid) + + def test_get_cpid_account_file_not_found(self): + """ + Test that the client will exit if an accounts file is specified, + but does not exist. + """ + args = rc.parse_cli_args(self.mock_argv()) + client = rc.RefstackClient(args) + client.tempest_dir = self.test_path + client._prep_test() + + client.conf.add_section('auth') + client.conf.set('auth', + 'test_accounts_file', + '%s/some-file.yaml' % self.test_path) + + self.mock_keystone() + with self.assertRaises(SystemExit): + client._get_cpid_from_keystone(client.conf) + + def test_get_cpid_account_file_empty(self): + """ + Test that the client will exit if an accounts file exists, + but is empty. + """ + self.patch( + 'refstack_client.refstack_client.read_accounts_yaml', + return_value=None) + + args = rc.parse_cli_args(self.mock_argv()) + client = rc.RefstackClient(args) + client.tempest_dir = self.test_path + client._prep_test() + + client.conf.add_section('auth') + client.conf.set('auth', + 'test_accounts_file', + '%s/some-file.yaml' % self.test_path) + + self.mock_keystone() + with self.assertRaises(SystemExit): + client._get_cpid_from_keystone(client.conf) + def test_get_cpid_from_keystone_insecure(self): """ Test getting the CPID from Keystone with the insecure arg passed in. diff --git a/requirements.txt b/requirements.txt index ae29239..2b066f0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ gitpython>=0.3.2.RC1 python-subunit>=0.0.18 pycrypto>=2.6.1 requests>=2.5.2 +PyYAML>=3.1.0