blob: 170e5230d6c2219d2bb1fb66213477b4933c7b26 [file] [log] [blame]
Daryl Walleck1465d612011-11-02 02:22:15 -05001import json
Jay Pipes7f757632011-12-02 15:53:32 -05002
3import httplib2
4
5from storm import exceptions
Daryl Walleck1465d612011-11-02 02:22:15 -05006import storm.config
7
8
9class RestClient(object):
10
Jay Pipes7f757632011-12-02 15:53:32 -050011 def __init__(self, config, user, key, auth_url, tenant_name=None):
12 self.config = config
Daryl Walleck1465d612011-11-02 02:22:15 -050013 if self.config.env.authentication == 'keystone_v2':
14 self.token, self.base_url = self.keystone_v2_auth(user,
15 key,
16 auth_url,
17 tenant_name)
18 else:
19 self.token, self.base_url = self.basic_auth(user,
20 key,
21 auth_url)
22
23 def basic_auth(self, user, api_key, auth_url):
24 """
25 Provides authentication for the target API
26 """
27
28 params = {}
29 params['headers'] = {'User-Agent': 'Test-Client', 'X-Auth-User': user,
30 'X-Auth-Key': api_key}
31
32 self.http_obj = httplib2.Http()
33 resp, body = self.http_obj.request(auth_url, 'GET', **params)
34 try:
35 return resp['x-auth-token'], resp['x-server-management-url']
36 except:
37 raise
38
39 def keystone_v2_auth(self, user, api_key, auth_url, tenant_name):
40 """
41 Provides authentication via Keystone 2.0
42 """
43
44 creds = {'auth': {
45 'passwordCredentials': {
46 'username': user,
47 'password': api_key,
48 },
49 'tenantName': tenant_name
50 }
51 }
52
53 self.http_obj = httplib2.Http()
54 headers = {'Content-Type': 'application/json'}
55 body = json.dumps(creds)
56 resp, body = self.http_obj.request(auth_url, 'POST',
57 headers=headers, body=body)
58
Jay Pipes7f757632011-12-02 15:53:32 -050059 if resp.status == 200:
60 try:
61 auth_data = json.loads(body)['access']
62 token = auth_data['token']['id']
63 endpoints = auth_data['serviceCatalog'][0]['endpoints']
64 mgmt_url = endpoints[0]['publicURL']
Daryl Walleck1465d612011-11-02 02:22:15 -050065
Jay Pipes7f757632011-12-02 15:53:32 -050066 #TODO (dwalleck): This is a horrible stopgap.
67 #Need to join strings more cleanly
68 temp = mgmt_url.rsplit('/')
69 service_url = temp[0] + '//' + temp[2] + '/' + temp[3] + '/'
70 management_url = service_url + tenant_name
71 return token, management_url
72 except Exception, e:
73 print "Failed to authenticate user: %s" % e
74 raise
75 elif resp.status == 401:
76 raise exceptions.AuthenticationFailure(user=user, password=api_key)
Daryl Walleck1465d612011-11-02 02:22:15 -050077
78 def post(self, url, body, headers):
79 return self.request('POST', url, headers, body)
80
81 def get(self, url):
82 return self.request('GET', url)
83
84 def delete(self, url):
85 return self.request('DELETE', url)
86
87 def put(self, url, body, headers):
88 return self.request('PUT', url, headers, body)
89
90 def request(self, method, url, headers=None, body=None):
Daryl Wallecke5b83d42011-11-10 14:39:02 -060091 """A simple HTTP request interface."""
Daryl Walleck1465d612011-11-02 02:22:15 -050092
93 self.http_obj = httplib2.Http()
94 if headers == None:
95 headers = {}
96 headers['X-Auth-Token'] = self.token
97
98 req_url = "%s/%s" % (self.base_url, url)
99 resp, body = self.http_obj.request(req_url, method,
100 headers=headers, body=body)
Daryl Walleckadea1fa2011-11-15 18:36:39 -0600101 if resp.status == 400:
102 body = json.loads(body)
103 raise exceptions.BadRequest(body['badRequest']['message'])
104
Daryl Walleck1465d612011-11-02 02:22:15 -0500105 return resp, body