blob: b587ee04e95377eb80331a191e1272d564138a76 [file] [log] [blame]
Daryl Wallecke5b83d42011-11-10 14:39:02 -06001from storm import exceptions
2from storm.common import rest_client
3import json
4import storm.config
5import time
6
7
8class ServersClient(object):
9
Jay Pipes7f757632011-12-02 15:53:32 -050010 def __init__(self, config, username, key, auth_url, tenant_name=None):
11 self.config = config
12 self.client = rest_client.RestClient(config, username, key,
Daryl Wallecke5b83d42011-11-10 14:39:02 -060013 auth_url, tenant_name)
Daryl Wallecke5b83d42011-11-10 14:39:02 -060014 self.build_interval = self.config.nova.build_interval
15 self.build_timeout = self.config.nova.build_timeout
16 self.headers = {'Content-Type': 'application/json',
17 'Accept': 'application/json'}
18
19 def create_server(self, name, image_ref, flavor_ref, meta=None,
20 personality=None, accessIPv4=None, accessIPv6=None,
21 adminPass=None):
22 """
23 Creates an instance of a server.
24 name: The name of the server.
25 image_ref: The reference to the image used to build the server.
26 flavor_ref: The flavor used to build the server.
27 adminPass: Sets the initial root password.
28 meta: A dictionary of values to be used as metadata.
29 personality: A list of dictionaries for files to be injected into
30 the server.
31 accessIPv4: The IPv4 access address for the server.
32 accessIPv6: The IPv6 access address for the server.
33 """
34
35 post_body = {
36 'name': name,
37 'imageRef': image_ref,
38 'flavorRef': flavor_ref,
39 }
40
41 if meta != None:
42 post_body['metadata'] = meta
43
44 if personality != None:
45 post_body['personality'] = personality
46
47 if adminPass != None:
48 post_body['adminPass'] = adminPass
49
50 if accessIPv4 != None:
51 post_body['accessIPv4'] = accessIPv4
52
53 if accessIPv6 != None:
54 post_body['accessIPv6'] = accessIPv6
55
56 post_body = json.dumps({'server': post_body})
57 resp, body = self.client.post('servers', post_body, self.headers)
58 body = json.loads(body)
59 return resp, body['server']
60
61 def update_server(self, server_id, name=None, meta=None, accessIPv4=None,
62 accessIPv6=None):
63 """
64 Updates the properties of an existing server.
65 server_id: The id of an existing server.
66 name: The name of the server.
67 personality: A list of files to be injected into the server.
68 accessIPv4: The IPv4 access address for the server.
69 accessIPv6: The IPv6 access address for the server.
70 """
71
72 post_body = {}
73
74 if meta != None:
75 post_body['metadata'] = meta
76
77 if name != None:
78 post_body['name'] = name
79
80 if accessIPv4 != None:
81 post_body['accessIPv4'] = accessIPv4
82
83 if accessIPv6 != None:
84 post_body['accessIPv6'] = accessIPv6
85
86 post_body = json.dumps({'server': post_body})
87 resp, body = self.client.put("servers/%s" % str(server_id),
88 post_body, self.headers)
89 body = json.loads(body)
90 return resp, body['server']
91
92 def get_server(self, server_id):
93 """Returns the details of an existing server"""
94 resp, body = self.client.get("servers/%s" % str(server_id))
95 body = json.loads(body)
96 return resp, body['server']
97
98 def delete_server(self, server_id):
99 """Deletes the given server"""
100 return self.client.delete("servers/%s" % str(server_id))
101
102 def list_servers(self, params=None):
103 """Lists all servers for a user"""
104
105 url = 'servers'
106 if params != None:
107 param_list = []
108 for param, value in params.iteritems():
109 param_list.append("%s=%s&" % (param, value))
110
111 url = "servers?" + "".join(param_list)
112
113 resp, body = self.client.get(url)
114 body = json.loads(body)
115 return resp, body
116
117 def list_servers_with_detail(self, params=None):
118 """Lists all servers in detail for a user"""
119
120 url = 'servers/detail'
121 if params != None:
122 param_list = []
123 for param, value in params.iteritems():
124 param_list.append("%s=%s&" % (param, value))
125
126 url = "servers/detail?" + "".join(param_list)
127
128 resp, body = self.client.get(url)
129 body = json.loads(body)
130 return resp, body
131
132 def wait_for_server_status(self, server_id, status):
133 """Waits for a server to reach a given status"""
134 resp, body = self.get_server(server_id)
135 server_status = body['status']
136 start = int(time.time())
137
138 while(server_status != status):
139 time.sleep(self.build_interval)
140 resp, body = self.get_server(server_id)
141 server_status = body['status']
142
143 if(server_status == 'ERROR'):
144 raise exceptions.BuildErrorException
145
146 if (int(time.time()) - start >= self.build_timeout):
147 raise exceptions.TimeoutException
148
149 def list_addresses(self, server_id):
150 """Lists all addresses for a server"""
151 resp, body = self.client.get("servers/%s/ips" % str(server_id))
152 body = json.loads(body)
153 return resp, body['addresses']
154
155 def list_addresses_by_network(self, server_id, network_id):
156 """Lists all addresses of a specific network type for a server"""
157 resp, body = self.client.get("servers/%s/ips/%s" %
158 (str(server_id), network_id))
159 body = json.loads(body)
160 return resp, body
161
162 def change_password(self, server_id, password):
163 """Changes the root password for the server"""
164 post_body = {
165 'changePassword': {
166 'adminPass': password,
167 }
168 }
169
170 post_body = json.dumps(post_body)
171 return self.client.post('servers/%s/action' % str(server_id),
172 post_body, self.headers)
173
174 def reboot(self, server_id, reboot_type):
175 """Reboots a server"""
176 post_body = {
177 'reboot': {
178 'type': reboot_type,
179 }
180 }
181
182 post_body = json.dumps(post_body)
183 return self.client.post('servers/%s/action' % str(server_id),
184 post_body, self.headers)
185
186 def rebuild(self, server_id, image_ref, name=None, meta=None,
187 personality=None, adminPass=None):
188 """Rebuilds a server with a new image"""
189 post_body = {
190 'imageRef': image_ref,
191 }
192
193 if name != None:
194 post_body['name'] = name
195
196 if adminPass != None:
197 post_body['adminPass'] = adminPass
198
199 if meta != None:
200 post_body['metadata'] = meta
201
202 if personality != None:
203 post_body['personality'] = personality
204
205 post_body = json.dumps({'rebuild': post_body})
206 resp, body = self.client.post('servers/%s/action' %
207 str(server_id), post_body,
208 self.headers)
209 body = json.loads(body)
210 return resp, body
211
212 def resize(self, server_id, flavor_ref):
213 """Changes the flavor of a server."""
214 post_body = {
215 'resize': {
216 'flavorRef': flavor_ref,
217 }
218 }
219
220 post_body = json.dumps(post_body)
221 resp, body = self.client.post('servers/%s/action' %
222 str(server_id), post_body, self.headers)
223 return resp, body
224
225 def confirm_resize(self, server_id):
226 """Confirms the flavor change for a server"""
227 post_body = {
228 'confirmResize': null
229 }
230
231 post_body = json.dumps(post_body)
232 resp, body = self.client.post('servers/%s/action' %
233 str(server_id), post_body, self.headers)
234 return resp, body
235
236 def revert_resize(self, server_id):
237 """Reverts a server back to its original flavor"""
238 post_body = {
239 'revertResize': null
240 }
241
242 post_body = json.dumps(post_body)
243 resp, body = self.client.post('servers/%s/action' %
244 str(server_id), post_body, self.headers)
245 return resp, body
246
247 def create_image(self, server_id, image_name):
248 """Creates an image of the given server"""
249 post_body = {
250 'createImage': {
251 'name': image_name,
252 }
253 }
254
255 post_body = json.dumps(post_body)
256 resp, body = self.client.post('servers/%s/action' %
257 str(server_id), post_body, self.headers)
258 body = json.loads(body)
259 return resp, body
Daryl Walleck73a9e7a2011-11-15 17:43:31 -0600260
261 def list_server_metadata(self, server_id):
262 resp, body = self.client.get("servers/%s/metadata" % str(server_id))
263 body = json.loads(body)
264 return resp, body['metadata']
265
266 def set_server_metadata(self, server_id, meta):
267 post_body = json.dumps({'metadata': meta})
268 resp, body = self.client.put('servers/%s/metadata' %
269 str(server_id), post_body, self.headers)
270 body = json.loads(body)
271 return resp, body['metadata']
272
273 def update_server_metadata(self, server_id, meta):
274 post_body = json.dumps({'metadata': meta})
275 resp, body = self.client.post('servers/%s/metadata' %
276 str(server_id), post_body, self.headers)
277 body = json.loads(body)
278 return resp, body['metadata']
279
280 def get_server_metadata_item(self, server_id, key):
281 resp, body = self.client.get("servers/%s/metadata/%s" %
282 (str(server_id), key))
283 body = json.loads(body)
284 return resp, body['meta']
285
286 def set_server_metadata_item(self, server_id, key, meta):
287 post_body = json.dumps({'meta': meta})
Daryl Walleck416af922011-11-22 22:28:33 -0600288 resp, body = self.client.put('servers/%s/metadata/%s' %
Daryl Walleck73a9e7a2011-11-15 17:43:31 -0600289 (str(server_id), key),
290 post_body, self.headers)
291 body = json.loads(body)
292 return resp, body['meta']
293
294 def delete_server_metadata_item(self, server_id, key):
295 resp, body = self.client.delete("servers/%s/metadata/%s" %
296 (str(server_id), key))
297 return resp, body