blob: 6ff6d56479f7a624221b3f6a25a428a5d954175c [file] [log] [blame]
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +05301# Copyright 2013 OpenStack Foundation
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000016import json
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053017
18from lxml import etree
19
vponomaryov960eeb42014-02-22 18:25:25 +020020from tempest.common import rest_client
Matthew Treinish684d8992014-01-30 16:27:40 +000021from tempest import config
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000022from tempest import exceptions
Haiwei Xuaad85db2014-03-05 05:17:39 +090023from tempest.services.compute.xml import common
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053024
Matthew Treinish684d8992014-01-30 16:27:40 +000025CONF = config.CONF
26
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053027XMLNS = "http://docs.openstack.org/identity/api/v3"
28
29
vponomaryov960eeb42014-02-22 18:25:25 +020030class IdentityV3ClientXML(rest_client.RestClient):
31 TYPE = "xml"
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053032
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000033 def __init__(self, auth_provider):
34 super(IdentityV3ClientXML, self).__init__(auth_provider)
Matthew Treinish684d8992014-01-30 16:27:40 +000035 self.service = CONF.identity.catalog_type
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053036 self.endpoint_url = 'adminURL'
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000037 self.api_version = "v3"
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053038
39 def _parse_projects(self, node):
40 array = []
41 for child in node.getchildren():
42 tag_list = child.tag.split('}', 1)
43 if tag_list[1] == "project":
Haiwei Xuaad85db2014-03-05 05:17:39 +090044 array.append(common.xml_to_json(child))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053045 return array
46
nayna-patel4df72dc2013-05-29 10:27:24 +000047 def _parse_domains(self, node):
48 array = []
49 for child in node.getchildren():
50 tag_list = child.tag.split('}', 1)
51 if tag_list[1] == "domain":
Haiwei Xuaad85db2014-03-05 05:17:39 +090052 array.append(common.xml_to_json(child))
nayna-patel4df72dc2013-05-29 10:27:24 +000053 return array
54
Zhi Kun Liue8136f02014-01-07 18:56:28 +080055 def _parse_group_users(self, node):
56 array = []
57 for child in node.getchildren():
58 tag_list = child.tag.split('}', 1)
59 if tag_list[1] == "user":
Haiwei Xuaad85db2014-03-05 05:17:39 +090060 array.append(common.xml_to_json(child))
Zhi Kun Liue8136f02014-01-07 18:56:28 +080061 return array
62
nayna-patel755d8142013-07-16 06:45:34 +000063 def _parse_roles(self, node):
64 array = []
65 for child in node.getchildren():
66 tag_list = child.tag.split('}', 1)
67 if tag_list[1] == "role":
Haiwei Xuaad85db2014-03-05 05:17:39 +090068 array.append(common.xml_to_json(child))
nayna-patel755d8142013-07-16 06:45:34 +000069 return array
70
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053071 def _parse_array(self, node):
72 array = []
73 for child in node.getchildren():
Haiwei Xuaad85db2014-03-05 05:17:39 +090074 array.append(common.xml_to_json(child))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053075 return array
76
77 def _parse_body(self, body):
Haiwei Xuaad85db2014-03-05 05:17:39 +090078 _json = common.xml_to_json(body)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000079 return _json
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053080
81 def create_user(self, user_name, **kwargs):
82 """Creates a user."""
83 password = kwargs.get('password', None)
84 email = kwargs.get('email', None)
85 en = kwargs.get('enabled', 'true')
86 project_id = kwargs.get('project_id', None)
87 description = kwargs.get('description', None)
88 domain_id = kwargs.get('domain_id', 'default')
Haiwei Xuaad85db2014-03-05 05:17:39 +090089 post_body = common.Element("user",
90 xmlns=XMLNS,
91 name=user_name,
92 password=password,
93 description=description,
94 email=email,
95 enabled=str(en).lower(),
96 project_id=project_id,
97 domain_id=domain_id)
98 resp, body = self.post('users', str(common.Document(post_body)))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053099 body = self._parse_body(etree.fromstring(body))
100 return resp, body
101
102 def update_user(self, user_id, name, **kwargs):
103 """Updates a user."""
nayna-patel755d8142013-07-16 06:45:34 +0000104 resp, body = self.get_user(user_id)
105 email = kwargs.get('email', body['email'])
106 en = kwargs.get('enabled', body['enabled'])
107 project_id = kwargs.get('project_id', body['project_id'])
108 description = kwargs.get('description', body['description'])
109 domain_id = kwargs.get('domain_id', body['domain_id'])
Haiwei Xuaad85db2014-03-05 05:17:39 +0900110 update_user = common.Element("user",
111 xmlns=XMLNS,
112 name=name,
113 email=email,
114 project_id=project_id,
115 domain_id=domain_id,
116 description=description,
117 enabled=str(en).lower())
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530118 resp, body = self.patch('users/%s' % user_id,
Haiwei Xuaad85db2014-03-05 05:17:39 +0900119 str(common.Document(update_user)))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530120 body = self._parse_body(etree.fromstring(body))
121 return resp, body
122
123 def list_user_projects(self, user_id):
124 """Lists the projects on which a user has roles assigned."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200125 resp, body = self.get('users/%s/projects' % user_id)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530126 body = self._parse_projects(etree.fromstring(body))
127 return resp, body
128
129 def get_users(self):
130 """Get the list of users."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200131 resp, body = self.get("users")
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530132 body = self._parse_array(etree.fromstring(body))
133 return resp, body
134
135 def get_user(self, user_id):
136 """GET a user."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200137 resp, body = self.get("users/%s" % user_id)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530138 body = self._parse_body(etree.fromstring(body))
139 return resp, body
140
141 def delete_user(self, user_id):
142 """Deletes a User."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200143 resp, body = self.delete("users/%s" % user_id)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530144 return resp, body
145
146 def create_project(self, name, **kwargs):
147 """Creates a project."""
148 description = kwargs.get('description', None)
149 en = kwargs.get('enabled', 'true')
150 domain_id = kwargs.get('domain_id', 'default')
Haiwei Xuaad85db2014-03-05 05:17:39 +0900151 post_body = common.Element("project",
152 xmlns=XMLNS,
153 description=description,
154 domain_id=domain_id,
155 enabled=str(en).lower(),
156 name=name)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530157 resp, body = self.post('projects',
Haiwei Xuaad85db2014-03-05 05:17:39 +0900158 str(common.Document(post_body)))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530159 body = self._parse_body(etree.fromstring(body))
160 return resp, body
161
Nayna Patele6331362013-08-12 06:59:48 +0000162 def list_projects(self):
163 """Get the list of projects."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200164 resp, body = self.get("projects")
Nayna Patele6331362013-08-12 06:59:48 +0000165 body = self._parse_projects(etree.fromstring(body))
166 return resp, body
167
168 def update_project(self, project_id, **kwargs):
169 """Updates a Project."""
170 resp, body = self.get_project(project_id)
171 name = kwargs.get('name', body['name'])
172 desc = kwargs.get('description', body['description'])
173 en = kwargs.get('enabled', body['enabled'])
174 domain_id = kwargs.get('domain_id', body['domain_id'])
Haiwei Xuaad85db2014-03-05 05:17:39 +0900175 post_body = common.Element("project",
176 xmlns=XMLNS,
177 name=name,
178 description=desc,
179 enabled=str(en).lower(),
180 domain_id=domain_id)
Nayna Patele6331362013-08-12 06:59:48 +0000181 resp, body = self.patch('projects/%s' % project_id,
Haiwei Xuaad85db2014-03-05 05:17:39 +0900182 str(common.Document(post_body)))
Nayna Patele6331362013-08-12 06:59:48 +0000183 body = self._parse_body(etree.fromstring(body))
184 return resp, body
185
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530186 def get_project(self, project_id):
187 """GET a Project."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200188 resp, body = self.get("projects/%s" % project_id)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530189 body = self._parse_body(etree.fromstring(body))
190 return resp, body
191
192 def delete_project(self, project_id):
193 """Delete a project."""
194 resp, body = self.delete('projects/%s' % str(project_id))
195 return resp, body
196
197 def create_role(self, name):
198 """Create a Role."""
Haiwei Xuaad85db2014-03-05 05:17:39 +0900199 post_body = common.Element("role",
200 xmlns=XMLNS,
201 name=name)
202 resp, body = self.post('roles', str(common.Document(post_body)))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530203 body = self._parse_body(etree.fromstring(body))
204 return resp, body
205
206 def get_role(self, role_id):
207 """GET a Role."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200208 resp, body = self.get('roles/%s' % str(role_id))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530209 body = self._parse_body(etree.fromstring(body))
210 return resp, body
211
nayna-patel755d8142013-07-16 06:45:34 +0000212 def update_role(self, name, role_id):
213 """Updates a Role."""
Haiwei Xuaad85db2014-03-05 05:17:39 +0900214 post_body = common.Element("role",
215 xmlns=XMLNS,
216 name=name)
nayna-patel755d8142013-07-16 06:45:34 +0000217 resp, body = self.patch('roles/%s' % str(role_id),
Haiwei Xuaad85db2014-03-05 05:17:39 +0900218 str(common.Document(post_body)))
nayna-patel755d8142013-07-16 06:45:34 +0000219 body = self._parse_body(etree.fromstring(body))
220 return resp, body
221
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530222 def delete_role(self, role_id):
223 """Delete a role."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200224 resp, body = self.delete('roles/%s' % str(role_id))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530225 return resp, body
226
227 def assign_user_role(self, project_id, user_id, role_id):
228 """Add roles to a user on a tenant."""
229 resp, body = self.put('projects/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200230 (project_id, user_id, role_id), '')
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530231 return resp, body
nayna-patel4df72dc2013-05-29 10:27:24 +0000232
233 def create_domain(self, name, **kwargs):
234 """Creates a domain."""
235 description = kwargs.get('description', None)
236 en = kwargs.get('enabled', True)
Haiwei Xuaad85db2014-03-05 05:17:39 +0900237 post_body = common.Element("domain",
238 xmlns=XMLNS,
239 name=name,
240 description=description,
241 enabled=str(en).lower())
242 resp, body = self.post('domains', str(common.Document(post_body)))
nayna-patel4df72dc2013-05-29 10:27:24 +0000243 body = self._parse_body(etree.fromstring(body))
244 return resp, body
245
246 def list_domains(self):
247 """Get the list of domains."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200248 resp, body = self.get("domains")
nayna-patel4df72dc2013-05-29 10:27:24 +0000249 body = self._parse_domains(etree.fromstring(body))
250 return resp, body
251
252 def delete_domain(self, domain_id):
253 """Delete a domain."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200254 resp, body = self.delete('domains/%s' % domain_id)
nayna-patel4df72dc2013-05-29 10:27:24 +0000255 return resp, body
256
257 def update_domain(self, domain_id, **kwargs):
258 """Updates a domain."""
259 resp, body = self.get_domain(domain_id)
260 description = kwargs.get('description', body['description'])
261 en = kwargs.get('enabled', body['enabled'])
262 name = kwargs.get('name', body['name'])
Haiwei Xuaad85db2014-03-05 05:17:39 +0900263 post_body = common.Element("domain",
264 xmlns=XMLNS,
265 name=name,
266 description=description,
267 enabled=str(en).lower())
nayna-patel4df72dc2013-05-29 10:27:24 +0000268 resp, body = self.patch('domains/%s' % domain_id,
Haiwei Xuaad85db2014-03-05 05:17:39 +0900269 str(common.Document(post_body)))
nayna-patel4df72dc2013-05-29 10:27:24 +0000270 body = self._parse_body(etree.fromstring(body))
271 return resp, body
272
273 def get_domain(self, domain_id):
274 """Get Domain details."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200275 resp, body = self.get('domains/%s' % domain_id)
nayna-patel4df72dc2013-05-29 10:27:24 +0000276 body = self._parse_body(etree.fromstring(body))
277 return resp, body
nayna-patelb35f7232013-06-28 07:08:44 +0000278
279 def get_token(self, resp_token):
280 """GET a Token Details."""
281 headers = {'Content-Type': 'application/xml',
282 'Accept': 'application/xml',
283 'X-Subject-Token': resp_token}
284 resp, body = self.get("auth/tokens", headers=headers)
285 body = self._parse_body(etree.fromstring(body))
286 return resp, body
287
288 def delete_token(self, resp_token):
289 """Delete a Given Token."""
290 headers = {'X-Subject-Token': resp_token}
291 resp, body = self.delete("auth/tokens", headers=headers)
292 return resp, body
293
nayna-patel755d8142013-07-16 06:45:34 +0000294 def create_group(self, name, **kwargs):
295 """Creates a group."""
296 description = kwargs.get('description', None)
297 domain_id = kwargs.get('domain_id', 'default')
298 project_id = kwargs.get('project_id', None)
Haiwei Xuaad85db2014-03-05 05:17:39 +0900299 post_body = common.Element("group",
300 xmlns=XMLNS,
301 name=name,
302 description=description,
303 domain_id=domain_id,
304 project_id=project_id)
305 resp, body = self.post('groups', str(common.Document(post_body)))
nayna-patel755d8142013-07-16 06:45:34 +0000306 body = self._parse_body(etree.fromstring(body))
307 return resp, body
308
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800309 def get_group(self, group_id):
310 """Get group details."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200311 resp, body = self.get('groups/%s' % group_id)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800312 body = self._parse_body(etree.fromstring(body))
313 return resp, body
314
315 def update_group(self, group_id, **kwargs):
316 """Updates a group."""
317 resp, body = self.get_group(group_id)
318 name = kwargs.get('name', body['name'])
319 description = kwargs.get('description', body['description'])
Haiwei Xuaad85db2014-03-05 05:17:39 +0900320 post_body = common.Element("group",
321 xmlns=XMLNS,
322 name=name,
323 description=description)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800324 resp, body = self.patch('groups/%s' % group_id,
Haiwei Xuaad85db2014-03-05 05:17:39 +0900325 str(common.Document(post_body)))
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800326 body = self._parse_body(etree.fromstring(body))
327 return resp, body
328
nayna-patel755d8142013-07-16 06:45:34 +0000329 def delete_group(self, group_id):
330 """Delete a group."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200331 resp, body = self.delete('groups/%s' % group_id)
nayna-patel755d8142013-07-16 06:45:34 +0000332 return resp, body
333
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800334 def add_group_user(self, group_id, user_id):
335 """Add user into group."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200336 resp, body = self.put('groups/%s/users/%s' % (group_id, user_id), '')
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800337 return resp, body
338
339 def list_group_users(self, group_id):
340 """List users in group."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200341 resp, body = self.get('groups/%s/users' % group_id)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800342 body = self._parse_group_users(etree.fromstring(body))
343 return resp, body
344
345 def delete_group_user(self, group_id, user_id):
346 """Delete user in group."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200347 resp, body = self.delete('groups/%s/users/%s' % (group_id, user_id))
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800348 return resp, body
349
nayna-patel755d8142013-07-16 06:45:34 +0000350 def assign_user_role_on_project(self, project_id, user_id, role_id):
351 """Add roles to a user on a project."""
352 resp, body = self.put('projects/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200353 (project_id, user_id, role_id), '')
nayna-patel755d8142013-07-16 06:45:34 +0000354 return resp, body
355
356 def assign_user_role_on_domain(self, domain_id, user_id, role_id):
357 """Add roles to a user on a domain."""
358 resp, body = self.put('domains/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200359 (domain_id, user_id, role_id), '')
nayna-patel755d8142013-07-16 06:45:34 +0000360 return resp, body
361
362 def list_user_roles_on_project(self, project_id, user_id):
363 """list roles of a user on a project."""
364 resp, body = self.get('projects/%s/users/%s/roles' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200365 (project_id, user_id))
nayna-patel755d8142013-07-16 06:45:34 +0000366 body = self._parse_roles(etree.fromstring(body))
367 return resp, body
368
369 def list_user_roles_on_domain(self, domain_id, user_id):
370 """list roles of a user on a domain."""
371 resp, body = self.get('domains/%s/users/%s/roles' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200372 (domain_id, user_id))
nayna-patel755d8142013-07-16 06:45:34 +0000373 body = self._parse_roles(etree.fromstring(body))
374 return resp, body
375
376 def revoke_role_from_user_on_project(self, project_id, user_id, role_id):
377 """Delete role of a user on a project."""
378 resp, body = self.delete('projects/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200379 (project_id, user_id, role_id))
nayna-patel755d8142013-07-16 06:45:34 +0000380 return resp, body
381
382 def revoke_role_from_user_on_domain(self, domain_id, user_id, role_id):
383 """Delete role of a user on a domain."""
384 resp, body = self.delete('domains/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200385 (domain_id, user_id, role_id))
nayna-patel755d8142013-07-16 06:45:34 +0000386 return resp, body
387
388 def assign_group_role_on_project(self, project_id, group_id, role_id):
389 """Add roles to a user on a project."""
390 resp, body = self.put('projects/%s/groups/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200391 (project_id, group_id, role_id), '')
nayna-patel755d8142013-07-16 06:45:34 +0000392 return resp, body
393
394 def assign_group_role_on_domain(self, domain_id, group_id, role_id):
395 """Add roles to a user on a domain."""
396 resp, body = self.put('domains/%s/groups/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200397 (domain_id, group_id, role_id), '')
nayna-patel755d8142013-07-16 06:45:34 +0000398 return resp, body
399
400 def list_group_roles_on_project(self, project_id, group_id):
401 """list roles of a user on a project."""
402 resp, body = self.get('projects/%s/groups/%s/roles' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200403 (project_id, group_id))
nayna-patel755d8142013-07-16 06:45:34 +0000404 body = self._parse_roles(etree.fromstring(body))
405 return resp, body
406
407 def list_group_roles_on_domain(self, domain_id, group_id):
408 """list roles of a user on a domain."""
409 resp, body = self.get('domains/%s/groups/%s/roles' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200410 (domain_id, group_id))
nayna-patel755d8142013-07-16 06:45:34 +0000411 body = self._parse_roles(etree.fromstring(body))
412 return resp, body
413
414 def revoke_role_from_group_on_project(self, project_id, group_id, role_id):
415 """Delete role of a user on a project."""
416 resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200417 (project_id, group_id, role_id))
nayna-patel755d8142013-07-16 06:45:34 +0000418 return resp, body
419
420 def revoke_role_from_group_on_domain(self, domain_id, group_id, role_id):
421 """Delete role of a user on a domain."""
422 resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200423 (domain_id, group_id, role_id))
nayna-patel755d8142013-07-16 06:45:34 +0000424 return resp, body
425
nayna-patelb35f7232013-06-28 07:08:44 +0000426
vponomaryov960eeb42014-02-22 18:25:25 +0200427class V3TokenClientXML(rest_client.RestClient):
428 TYPE = "xml"
nayna-patelb35f7232013-06-28 07:08:44 +0000429
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000430 def __init__(self):
431 super(V3TokenClientXML, self).__init__(None)
432 auth_url = CONF.identity.uri_v3
Matthew Treinishdb2c5972014-01-31 22:18:59 +0000433 if not auth_url and CONF.identity_feature_enabled.api_v3:
434 raise exceptions.InvalidConfiguration('you must specify a v3 uri '
435 'if using the v3 identity '
436 'api')
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000437 if 'auth/tokens' not in auth_url:
438 auth_url = auth_url.rstrip('/') + '/auth/tokens'
nayna-patelb35f7232013-06-28 07:08:44 +0000439
440 self.auth_url = auth_url
nayna-patelb35f7232013-06-28 07:08:44 +0000441
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000442 def auth(self, user, password, tenant=None, user_type='id', domain=None):
443 """
444 :param user: user id or name, as specified in user_type
445
446 Accepts different combinations of credentials. Restrictions:
447 - tenant and domain are only name (no id)
448 - user domain and tenant domain are assumed identical
449 Sample sample valid combinations:
450 - user_id, password
451 - username, password, domain
452 - username, password, tenant, domain
453 Validation is left to the server side.
454 """
455 if user_type == 'id':
Haiwei Xuaad85db2014-03-05 05:17:39 +0900456 _user = common.Element('user', id=user, password=password)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000457 else:
Haiwei Xuaad85db2014-03-05 05:17:39 +0900458 _user = common.Element('user', name=user, password=password)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000459 if domain is not None:
Haiwei Xuaad85db2014-03-05 05:17:39 +0900460 _domain = common.Element('domain', name=domain)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000461 _user.append(_domain)
462
Haiwei Xuaad85db2014-03-05 05:17:39 +0900463 password = common.Element('password')
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000464 password.append(_user)
nayna-patelb35f7232013-06-28 07:08:44 +0000465
Haiwei Xuaad85db2014-03-05 05:17:39 +0900466 method = common.Element('method')
467 method.append(common.Text('password'))
468 methods = common.Element('methods')
nayna-patelb35f7232013-06-28 07:08:44 +0000469 methods.append(method)
Haiwei Xuaad85db2014-03-05 05:17:39 +0900470 identity = common.Element('identity')
nayna-patelb35f7232013-06-28 07:08:44 +0000471 identity.append(methods)
472 identity.append(password)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000473
Haiwei Xuaad85db2014-03-05 05:17:39 +0900474 auth = common.Element('auth')
nayna-patelb35f7232013-06-28 07:08:44 +0000475 auth.append(identity)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000476
477 if tenant is not None:
Haiwei Xuaad85db2014-03-05 05:17:39 +0900478 project = common.Element('project', name=tenant)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000479 project.append(_domain)
Haiwei Xuaad85db2014-03-05 05:17:39 +0900480 scope = common.Element('scope')
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000481 scope.append(project)
482 auth.append(scope)
483
Haiwei Xuaad85db2014-03-05 05:17:39 +0900484 resp, body = self.post(self.auth_url, body=str(common.Document(auth)))
nayna-patelb35f7232013-06-28 07:08:44 +0000485 return resp, body
486
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000487 def request(self, method, url, headers=None, body=None):
488 """A simple HTTP request interface."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200489 if headers is None:
490 # Always accept 'json', for xml token client too.
491 # Because XML response is not easily
492 # converted to the corresponding JSON one
493 headers = self.get_headers(accept_type="json")
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000494 self._log_request(method, url, headers, body)
495 resp, resp_body = self.http_obj.request(url, method,
496 headers=headers, body=body)
497 self._log_response(resp, resp_body)
498
499 if resp.status in [401, 403]:
500 resp_body = json.loads(resp_body)
501 raise exceptions.Unauthorized(resp_body['error']['message'])
502 elif resp.status not in [200, 201, 204]:
503 raise exceptions.IdentityError(
504 'Unexpected status code {0}'.format(resp.status))
505
506 return resp, json.loads(resp_body)
507
508 def get_token(self, user, password, tenant, domain='Default',
509 auth_data=False):
510 """
511 :param user: username
512 Returns (token id, token data) for supplied credentials
513 """
514 resp, body = self.auth(user, password, tenant, user_type='name',
515 domain=domain)
516
517 token = resp.get('x-subject-token')
518 if auth_data:
519 return token, body['token']
520 else:
521 return token