blob: ad88ea227ae0a8bb7cab0434adb6fc0f3bbaca1a [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
55 def _create_hash_file(self, hash):
56 path = os.path.join(os.path.join(self.accounts_dir, hash))
57 if not os.path.isfile(path):
58 open(path, 'w').close()
59 return True
60 return False
61
62 @lockutils.synchronized('test_accounts_io', external=True)
63 def _get_free_hash(self, hashes):
64 if not os.path.isdir(self.accounts_dir):
65 os.mkdir(self.accounts_dir)
66 # Create File from first hash (since none are in use)
67 self._create_hash_file(hashes[0])
68 return hashes[0]
69 for hash in hashes:
70 res = self._create_hash_file(hash)
71 if res:
72 return hash
73 msg = 'Insufficient number of users provided'
74 raise exceptions.InvalidConfiguration(msg)
75
76 def _get_creds(self):
77 free_hash = self._get_free_hash(self.hashes.keys())
78 return self.hash_dict[free_hash]
79
80 @lockutils.synchronized('test_accounts_io', external=True)
81 def remove_hash(self, hash):
82 hash_path = os.path.join(self.accounts_dir, hash)
83 if not os.path.isfile(hash_path):
84 LOG.warning('Expected an account lock file %s to remove, but '
85 'one did not exist')
86 else:
87 os.remove(hash_path)
88 if not os.listdir(self.accounts_dir):
89 os.rmdir(self.accounts_dir)
90
91 def get_hash(self, creds):
92 for hash in self.hash_dict:
93 # NOTE(mtreinish) Assuming with v3 that username, tenant, password
94 # is unique enough
95 cred_dict = {
96 'username': creds.username,
97 'tenant_name': creds.tenant_name,
98 'password': creds.password
99 }
100 if self.hash_dict[hash] == cred_dict:
101 return hash
102 raise AttributeError('Invalid credentials %s' % creds)
103
104 def remove_credentials(self, creds):
105 hash = self.get_hash(creds)
106 self.remove_hash(hash, self.accounts_dir)
107
108 def get_primary_creds(self):
109 if self.credentials.get('primary'):
110 return self.credentials.get('primary')
111 creds = self._get_creds()
112 primary_credential = auth.get_credentials(**creds)
113 self.credentials['primary'] = primary_credential
114 return primary_credential
115
116 def get_alt_creds(self):
117 if self.credentials.get('alt'):
118 return self.credentials.get('alt')
119 creds = self._get_creds()
120 alt_credential = auth.get_credentials(**creds)
121 self.credentials['alt'] = alt_credential
122 return alt_credential
123
124 def clear_isolated_creds(self):
125 for creds in self.credentials.values():
126 self.remove_credentials(creds)
127
128 def get_admin_creds(self):
129 msg = ('If admin credentials are available tenant_isolation should be'
130 ' used instead')
131 raise NotImplementedError(msg)