Skip to content

Commit b1eeaa4

Browse files
author
Tim Simpson
committed
Changing Reddwarf client to use its own request function.
* Nova client changed in a way that broke our client, so copying the code from there is necessary. * Adding InstanceStatus class with the status strings. * Moved the Dbaas and ReddwarfHTTPClient into their own module. * Changed exceptions module to check Nova's exception map after first looking in Reddwarf's.
1 parent 2dc5d02 commit b1eeaa4

File tree

5 files changed

+170
-103
lines changed

5 files changed

+170
-103
lines changed

reddwarfclient/__init__.py

Lines changed: 2 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -13,106 +13,6 @@
1313
# License for the specific language governing permissions and limitations
1414
# under the License.
1515

16-
import time
17-
import urlparse
18-
19-
try:
20-
import json
21-
except ImportError:
22-
import simplejson as json
23-
24-
25-
from novaclient.client import HTTPClient
26-
from novaclient.v1_1.client import Client
27-
28-
29-
# To write this test from an end user perspective, we have to create a client
30-
# similar to the CloudServers one.
31-
# For now we will work on it here.
32-
33-
34-
class ReddwarfHTTPClient(HTTPClient):
35-
"""
36-
Class for overriding the HTTP authenticate call and making it specific to
37-
reddwarf
38-
"""
39-
40-
def __init__(self, user, apikey, tenant, auth_url, service_name,
41-
service_type=None, service_url=None, timeout=None):
42-
super(ReddwarfHTTPClient, self).__init__(user, apikey, tenant,
43-
auth_url,
44-
service_type=service_type,
45-
timeout=timeout)
46-
self.api_key = apikey
47-
self.tenant = tenant
48-
self.service = service_name
49-
self.management_url = service_url
50-
51-
52-
def _get_token(self, path, req_body):
53-
"""Set the management url and auth token"""
54-
token_url = urlparse.urljoin(self.auth_url, path)
55-
resp, body = self.request(token_url, "POST", body=req_body)
56-
if 'access' in body:
57-
if not self.management_url:
58-
# Assume the new Keystone lite:
59-
catalog = body['access']['serviceCatalog']
60-
for service in catalog:
61-
if service['name'] == self.service:
62-
self.management_url = service['adminURL']
63-
self.auth_token = body['access']['token']['id']
64-
else:
65-
# Assume pre-Keystone Light:
66-
try:
67-
if not self.management_url:
68-
self.management_url = body['auth']['serviceCatalog'] \
69-
[self.service][0]['publicURL']
70-
self.auth_token = body['auth']['token']['id']
71-
except KeyError:
72-
raise NotImplementedError("Service: %s is not available"
73-
% self.service)
74-
75-
76-
class Dbaas(Client):
77-
"""
78-
Top-level object to access the Rackspace Database as a Service API.
79-
80-
Create an instance with your creds::
81-
82-
>>> red = Dbaas(USERNAME, API_KEY, TENANT, AUTH_URL, SERVICE_NAME,
83-
SERVICE_URL)
84-
85-
Then call methods on its managers::
86-
87-
>>> red.instances.list()
88-
...
89-
>>> red.flavors.list()
90-
...
91-
92-
&c.
93-
"""
94-
95-
def __init__(self, username, api_key, tenant=None, auth_url=None,
96-
service_type='reddwarf', service_name='Reddwarf Service',
97-
service_url=None):
98-
super(Dbaas, self).__init__(self, username, api_key, tenant, auth_url)
99-
self.client = ReddwarfHTTPClient(username, api_key, tenant, auth_url,
100-
service_type=service_type,
101-
service_name=service_name,
102-
service_url=service_url)
103-
self.versions = Versions(self)
104-
self.databases = Databases(self)
105-
self.flavors = Flavors(self)
106-
self.instances = Instances(self)
107-
self.users = Users(self)
108-
self.root = Root(self)
109-
self.hosts = Hosts(self)
110-
self.storage = StorageInfo(self)
111-
self.management = Management(self)
112-
self.accounts = Accounts(self)
113-
self.configs = Configs(self)
114-
self.diagnostics = Interrogator(self)
115-
11616

11717
from reddwarfclient.accounts import Accounts
11818
from reddwarfclient.config import Configs
@@ -126,3 +26,5 @@ def __init__(self, username, api_key, tenant=None, auth_url=None,
12626
from reddwarfclient.users import Users
12727
from reddwarfclient.versions import Versions
12828
from reddwarfclient.diagnostics import Interrogator
29+
from reddwarfclient.client import Dbaas
30+
from reddwarfclient.client import ReddwarfHTTPClient

reddwarfclient/client.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Copyright (c) 2011 OpenStack, LLC.
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+
16+
import time
17+
import urlparse
18+
19+
try:
20+
import json
21+
except ImportError:
22+
import simplejson as json
23+
24+
25+
from novaclient.client import HTTPClient
26+
from novaclient.v1_1.client import Client
27+
28+
from reddwarfclient import exceptions
29+
30+
class ReddwarfHTTPClient(HTTPClient):
31+
"""
32+
Class for overriding the HTTP authenticate call and making it specific to
33+
reddwarf
34+
"""
35+
36+
def __init__(self, user, apikey, tenant, auth_url, service_name,
37+
service_type=None, service_url=None, timeout=None):
38+
super(ReddwarfHTTPClient, self).__init__(user, apikey, tenant,
39+
auth_url,
40+
service_type=service_type,
41+
timeout=timeout)
42+
self.api_key = apikey
43+
self.tenant = tenant
44+
self.service = service_name
45+
self.management_url = service_url
46+
47+
48+
def _get_token(self, path, req_body):
49+
"""Set the management url and auth token"""
50+
token_url = urlparse.urljoin(self.auth_url, path)
51+
resp, body = self.request(token_url, "POST", body=req_body)
52+
if 'access' in body:
53+
if not self.management_url:
54+
# Assume the new Keystone lite:
55+
catalog = body['access']['serviceCatalog']
56+
for service in catalog:
57+
if service['name'] == self.service:
58+
self.management_url = service['adminURL']
59+
self.auth_token = body['access']['token']['id']
60+
else:
61+
# Assume pre-Keystone Light:
62+
try:
63+
if not self.management_url:
64+
self.management_url = body['auth']['serviceCatalog'] \
65+
[self.service][0]['publicURL']
66+
self.auth_token = body['auth']['token']['id']
67+
except KeyError:
68+
raise NotImplementedError("Service: %s is not available"
69+
% self.service)
70+
71+
def request(self, *args, **kwargs):
72+
#TODO(tim.simpson): Copy and pasted from novaclient, since we raise
73+
# extra exception subclasses not raised there.
74+
kwargs.setdefault('headers', kwargs.get('headers', {}))
75+
kwargs['headers']['User-Agent'] = self.USER_AGENT
76+
kwargs['headers']['Accept'] = 'application/json'
77+
if 'body' in kwargs:
78+
kwargs['headers']['Content-Type'] = 'application/json'
79+
kwargs['body'] = json.dumps(kwargs['body'])
80+
81+
resp, body = super(HTTPClient, self).request(*args, **kwargs)
82+
83+
self.http_log(args, kwargs, resp, body)
84+
85+
if body:
86+
try:
87+
body = json.loads(body)
88+
except ValueError:
89+
pass
90+
else:
91+
body = None
92+
93+
if resp.status in (400, 401, 403, 404, 408, 409, 413, 500, 501):
94+
raise exceptions.from_response(resp, body)
95+
96+
return resp, body
97+
98+
99+
class Dbaas(Client):
100+
"""
101+
Top-level object to access the Rackspace Database as a Service API.
102+
103+
Create an instance with your creds::
104+
105+
>>> red = Dbaas(USERNAME, API_KEY, TENANT, AUTH_URL, SERVICE_NAME,
106+
SERVICE_URL)
107+
108+
Then call methods on its managers::
109+
110+
>>> red.instances.list()
111+
...
112+
>>> red.flavors.list()
113+
...
114+
115+
&c.
116+
"""
117+
118+
def __init__(self, username, api_key, tenant=None, auth_url=None,
119+
service_type='reddwarf', service_name='Reddwarf Service',
120+
service_url=None):
121+
from reddwarfclient.versions import Versions
122+
from reddwarfclient.databases import Databases
123+
from reddwarfclient.flavors import Flavors
124+
from reddwarfclient.instances import Instances
125+
from reddwarfclient.users import Users
126+
from reddwarfclient.root import Root
127+
from reddwarfclient.hosts import Hosts
128+
from reddwarfclient.storage import StorageInfo
129+
from reddwarfclient.management import Management
130+
from reddwarfclient.accounts import Accounts
131+
from reddwarfclient.config import Configs
132+
from reddwarfclient.diagnostics import Interrogator
133+
134+
super(Dbaas, self).__init__(self, username, api_key, tenant, auth_url)
135+
self.client = ReddwarfHTTPClient(username, api_key, tenant, auth_url,
136+
service_type=service_type,
137+
service_name=service_name,
138+
service_url=service_url)
139+
self.versions = Versions(self)
140+
self.databases = Databases(self)
141+
self.flavors = Flavors(self)
142+
self.instances = Instances(self)
143+
self.users = Users(self)
144+
self.root = Root(self)
145+
self.hosts = Hosts(self)
146+
self.storage = StorageInfo(self)
147+
self.management = Management(self)
148+
self.accounts = Accounts(self)
149+
self.configs = Configs(self)
150+
self.diagnostics = Interrogator(self)
151+
152+

reddwarfclient/common.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
import pickle
1717
import sys
1818

19-
20-
from reddwarfclient import Dbaas
19+
from reddwarfclient.client import Dbaas
2120
import exceptions
2221

2322

reddwarfclient/exceptions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ def from_response(response, body):
3737
if resp.status != 200:
3838
raise exception_from_response(resp, body)
3939
"""
40-
cls = _code_map.get(response.status, exceptions.ClientException)
40+
cls = _code_map.get(response.status, None)
41+
if not cls:
42+
cls = exceptions._code_map.get(response.status,
43+
exceptions.ClientException)
4144
if body:
4245
message = "n/a"
4346
details = "n/a"

reddwarfclient/instances.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,14 @@ def restart(self, instance_id):
147147
"""
148148
body = {'restart': {}}
149149
self._action(instance_id, body)
150+
151+
152+
class InstanceStatus(object):
153+
154+
ACTIVE = "ACTIVE"
155+
BLOCKED = "BLOCKED"
156+
BUILD = "BUILD"
157+
FAILED = "FAILED"
158+
REBOOT = "REBOOT"
159+
RESIZE = "RESIZE"
160+
SHUTDOWN = "SHUTDOWN"

0 commit comments

Comments
 (0)