blob: b31c19ac8c2b5f8e443757d10969ff7c2eea30db [file] [log] [blame]
Matthew Treinishc791ac42014-07-16 09:15:23 -04001# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15import hashlib
16import os
Matthew Treinish96e9e882014-06-09 18:37:19 -040017
Matthew Treinishc791ac42014-07-16 09:15:23 -040018import yaml
19
20from tempest import auth
21from tempest.common import cred_provider
22from tempest import config
23from tempest import exceptions
24from tempest.openstack.common import lockutils
25from tempest.openstack.common import log as logging
26
27CONF = config.CONF
28LOG = logging.getLogger(__name__)
29
30
31def read_accounts_yaml(path):
32 yaml_file = open(path, 'r')
33 accounts = yaml.load(yaml_file)
34 return accounts
35
36
37class Accounts(cred_provider.CredentialProvider):
38
39 def __init__(self, name):
40 super(Accounts, self).__init__(name)
41 accounts = read_accounts_yaml(CONF.auth.test_accounts_file)
42 self.hash_dict = self.get_hash_dict(accounts)
43 self.accounts_dir = os.path.join(CONF.lock_path, 'test_accounts')
44 self.isolated_creds = {}
45
46 @classmethod
47 def get_hash_dict(cls, accounts):
48 hash_dict = {}
49 for account in accounts:
50 temp_hash = hashlib.md5()
51 temp_hash.update(str(account))
52 hash_dict[temp_hash.hexdigest()] = account
53 return hash_dict
54
Matthew Treinish09f17832014-08-15 15:22:50 -040055 def is_multi_user(self):
56 return len(self.hash_dict) > 1
57
58 def _create_hash_file(self, hash_string):
59 path = os.path.join(os.path.join(self.accounts_dir, hash_string))
Matthew Treinishc791ac42014-07-16 09:15:23 -040060 if not os.path.isfile(path):
61 open(path, 'w').close()
62 return True
63 return False
64
65 @lockutils.synchronized('test_accounts_io', external=True)
66 def _get_free_hash(self, hashes):
67 if not os.path.isdir(self.accounts_dir):
68 os.mkdir(self.accounts_dir)
69 # Create File from first hash (since none are in use)
70 self._create_hash_file(hashes[0])
71 return hashes[0]
Matthew Treinish09f17832014-08-15 15:22:50 -040072 for _hash in hashes:
73 res = self._create_hash_file(_hash)
Matthew Treinishc791ac42014-07-16 09:15:23 -040074 if res:
Matthew Treinish09f17832014-08-15 15:22:50 -040075 return _hash
Matthew Treinishc791ac42014-07-16 09:15:23 -040076 msg = 'Insufficient number of users provided'
77 raise exceptions.InvalidConfiguration(msg)
78
79 def _get_creds(self):
Matthew Treinish09f17832014-08-15 15:22:50 -040080 free_hash = self._get_free_hash(self.hash_dict.keys())
Matthew Treinishc791ac42014-07-16 09:15:23 -040081 return self.hash_dict[free_hash]
82
83 @lockutils.synchronized('test_accounts_io', external=True)
Matthew Treinish09f17832014-08-15 15:22:50 -040084 def remove_hash(self, hash_string):
85 hash_path = os.path.join(self.accounts_dir, hash_string)
Matthew Treinishc791ac42014-07-16 09:15:23 -040086 if not os.path.isfile(hash_path):
87 LOG.warning('Expected an account lock file %s to remove, but '
88 'one did not exist')
89 else:
90 os.remove(hash_path)
91 if not os.listdir(self.accounts_dir):
92 os.rmdir(self.accounts_dir)
93
94 def get_hash(self, creds):
Matthew Treinish09f17832014-08-15 15:22:50 -040095 for _hash in self.hash_dict:
96 # Comparing on the attributes that are expected in the YAML
97 if all([getattr(creds, k) == self.hash_dict[_hash][k] for k in
98 creds.CONF_ATTRIBUTES]):
99 return _hash
Matthew Treinishc791ac42014-07-16 09:15:23 -0400100 raise AttributeError('Invalid credentials %s' % creds)
101
102 def remove_credentials(self, creds):
Matthew Treinish09f17832014-08-15 15:22:50 -0400103 _hash = self.get_hash(creds)
104 self.remove_hash(_hash)
Matthew Treinishc791ac42014-07-16 09:15:23 -0400105
106 def get_primary_creds(self):
Matthew Treinish09f17832014-08-15 15:22:50 -0400107 if self.isolated_creds.get('primary'):
108 return self.isolated_creds.get('primary')
Matthew Treinishc791ac42014-07-16 09:15:23 -0400109 creds = self._get_creds()
110 primary_credential = auth.get_credentials(**creds)
Matthew Treinish09f17832014-08-15 15:22:50 -0400111 self.isolated_creds['primary'] = primary_credential
Matthew Treinishc791ac42014-07-16 09:15:23 -0400112 return primary_credential
113
114 def get_alt_creds(self):
Matthew Treinish09f17832014-08-15 15:22:50 -0400115 if self.isolated_creds.get('alt'):
116 return self.isolated_creds.get('alt')
Matthew Treinishc791ac42014-07-16 09:15:23 -0400117 creds = self._get_creds()
118 alt_credential = auth.get_credentials(**creds)
Matthew Treinish09f17832014-08-15 15:22:50 -0400119 self.isolated_creds['alt'] = alt_credential
Matthew Treinishc791ac42014-07-16 09:15:23 -0400120 return alt_credential
121
122 def clear_isolated_creds(self):
Matthew Treinish09f17832014-08-15 15:22:50 -0400123 for creds in self.isolated_creds.values():
Matthew Treinishc791ac42014-07-16 09:15:23 -0400124 self.remove_credentials(creds)
125
126 def get_admin_creds(self):
127 msg = ('If admin credentials are available tenant_isolation should be'
128 ' used instead')
129 raise NotImplementedError(msg)