Revision eb647cfe kamaki/clients/cyclades/__init__.py
b/kamaki/clients/cyclades/__init__.py | ||
---|---|---|
61 | 61 |
{"network": <network_uuid>}, |
62 | 62 |
{"network": <network_uuid>, "fixed_ip": address}, |
63 | 63 |
{"port": <port_id>}, ...] |
64 |
ATTENTION: Empty list is different to None. None means ' do not |
|
65 |
mention it', empty list means 'automatically get an ip' |
|
64 | 66 |
|
65 | 67 |
:returns: a dict with the new virtual server details |
66 | 68 |
|
... | ... | |
76 | 78 |
|
77 | 79 |
return super(CycladesClient, self).create_server( |
78 | 80 |
name, flavor_id, image_id, |
79 |
metadata=metadata, personality=personality) |
|
81 |
metadata=metadata, personality=personality, networks=networks)
|
|
80 | 82 |
|
81 | 83 |
def start_server(self, server_id): |
82 | 84 |
"""Submit a startup request |
... | ... | |
157 | 159 |
r = self.servers_stats_get(server_id) |
158 | 160 |
return r.json['stats'] |
159 | 161 |
|
160 |
def list_networks(self, detail=False): |
|
161 |
""" |
|
162 |
:param detail: (bool) |
|
163 |
|
|
164 |
:returns: (list) id,name if not detail else full info per network |
|
165 |
""" |
|
166 |
detail = 'detail' if detail else '' |
|
167 |
r = self.networks_get(command=detail) |
|
168 |
return r.json['networks'] |
|
169 |
|
|
170 |
def list_network_nics(self, network_id): |
|
171 |
""" |
|
172 |
:param network_id: integer (str or int) |
|
173 |
|
|
174 |
:returns: (list) |
|
175 |
""" |
|
176 |
r = self.networks_get(network_id=network_id) |
|
177 |
return r.json['network']['attachments'] |
|
178 |
|
|
179 |
def create_network( |
|
180 |
self, name, |
|
181 |
cidr=None, gateway=None, type=None, dhcp=False): |
|
182 |
""" |
|
183 |
:param name: (str) |
|
184 |
|
|
185 |
:param cidr: (str) |
|
186 |
|
|
187 |
:param geteway: (str) |
|
188 |
|
|
189 |
:param type: (str) if None, will use MAC_FILTERED as default |
|
190 |
Valid values: CUSTOM, IP_LESS_ROUTED, MAC_FILTERED, PHYSICAL_VLAN |
|
191 |
|
|
192 |
:param dhcp: (bool) |
|
193 |
|
|
194 |
:returns: (dict) network detailed info |
|
195 |
""" |
|
196 |
net = dict(name=name) |
|
197 |
if cidr: |
|
198 |
net['cidr'] = cidr |
|
199 |
if gateway: |
|
200 |
net['gateway'] = gateway |
|
201 |
net['type'] = type or 'MAC_FILTERED' |
|
202 |
net['dhcp'] = True if dhcp else False |
|
203 |
req = dict(network=net) |
|
204 |
r = self.networks_post(json_data=req, success=202) |
|
205 |
return r.json['network'] |
|
206 |
|
|
207 |
def get_network_details(self, network_id): |
|
208 |
""" |
|
209 |
:param network_id: integer (str or int) |
|
210 |
|
|
211 |
:returns: (dict) |
|
212 |
""" |
|
213 |
r = self.networks_get(network_id=network_id) |
|
214 |
return r.json['network'] |
|
215 |
|
|
216 |
def update_network_name(self, network_id, new_name): |
|
217 |
""" |
|
218 |
:param network_id: integer (str or int) |
|
219 |
|
|
220 |
:param new_name: (str) |
|
221 |
|
|
222 |
:returns: (dict) response headers |
|
223 |
""" |
|
224 |
req = {'network': {'name': new_name}} |
|
225 |
r = self.networks_put(network_id=network_id, json_data=req) |
|
226 |
return r.headers |
|
227 |
|
|
228 |
def delete_network(self, network_id): |
|
229 |
""" |
|
230 |
:param network_id: integer (str or int) |
|
231 |
|
|
232 |
:returns: (dict) response headers |
|
233 |
|
|
234 |
:raises ClientError: 421 Network in use |
|
235 |
""" |
|
236 |
try: |
|
237 |
r = self.networks_delete(network_id) |
|
238 |
return r.headers |
|
239 |
except ClientError as err: |
|
240 |
if err.status == 421: |
|
241 |
err.details = [ |
|
242 |
'Network may be still connected to at least one server'] |
|
243 |
raise |
|
244 |
|
|
245 |
def connect_server(self, server_id, network_id): |
|
246 |
""" Connect a server to a network |
|
247 |
|
|
248 |
:param server_id: integer (str or int) |
|
249 |
|
|
250 |
:param network_id: integer (str or int) |
|
251 |
|
|
252 |
:returns: (dict) response headers |
|
253 |
""" |
|
254 |
req = {'add': {'serverRef': server_id}} |
|
255 |
r = self.networks_post(network_id, 'action', json_data=req) |
|
256 |
return r.headers |
|
257 |
|
|
258 |
def disconnect_server(self, server_id, nic_id): |
|
259 |
""" |
|
260 |
:param server_id: integer (str or int) |
|
261 |
|
|
262 |
:param nic_id: (str) |
|
263 |
|
|
264 |
:returns: (int) the number of nics disconnected |
|
265 |
""" |
|
266 |
vm_nets = self.list_server_nics(server_id) |
|
267 |
num_of_disconnections = 0 |
|
268 |
for (nic_id, network_id) in [( |
|
269 |
net['id'], |
|
270 |
net['network_id']) for net in vm_nets if nic_id == net['id']]: |
|
271 |
req = {'remove': {'attachment': '%s' % nic_id}} |
|
272 |
self.networks_post(network_id, 'action', json_data=req) |
|
273 |
num_of_disconnections += 1 |
|
274 |
return num_of_disconnections |
|
275 |
|
|
276 |
def disconnect_network_nics(self, netid): |
|
277 |
""" |
|
278 |
:param netid: integer (str or int) |
|
279 |
""" |
|
280 |
for nic in self.list_network_nics(netid): |
|
281 |
req = dict(remove=dict(attachment=nic)) |
|
282 |
self.networks_post(netid, 'action', json_data=req) |
|
283 |
|
|
284 | 162 |
def wait_server( |
285 | 163 |
self, server_id, |
286 | 164 |
current_status='BUILD', |
... | ... | |
308 | 186 |
return self._wait( |
309 | 187 |
server_id, current_status, get_status, delay, max_wait, wait_cb) |
310 | 188 |
|
311 |
def wait_network( |
|
312 |
self, net_id, |
|
313 |
current_status='PENDING', delay=1, max_wait=100, wait_cb=None): |
|
314 |
"""Wait for network while its status is current_status |
|
315 |
|
|
316 |
:param net_id: integer (str or int) |
|
317 |
|
|
318 |
:param current_status: (str) PENDING | ACTIVE | DELETED |
|
319 |
|
|
320 |
:param delay: time interval between retries |
|
321 |
|
|
322 |
:max_wait: (int) timeout in secconds |
|
323 |
|
|
324 |
:param wait_cb: if set a progressbar is used to show progress |
|
325 |
|
|
326 |
:returns: (str) the new mode if succesfull, (bool) False if timed out |
|
327 |
""" |
|
328 |
|
|
329 |
def get_status(self, net_id): |
|
330 |
r = self.get_network_details(net_id) |
|
331 |
return r['status'], None |
|
332 |
|
|
333 |
return self._wait( |
|
334 |
net_id, current_status, get_status, delay, max_wait, wait_cb) |
|
335 |
|
|
336 | 189 |
def wait_firewall( |
337 | 190 |
self, server_id, |
338 | 191 |
current_status='DISABLED', delay=1, max_wait=100, wait_cb=None): |
... | ... | |
358 | 211 |
server_id, current_status, get_status, delay, max_wait, wait_cb) |
359 | 212 |
|
360 | 213 |
|
361 |
class CycladesNetworkClient(NetworkClient, Waiter):
|
|
214 |
class CycladesNetworkClient(NetworkClient): |
|
362 | 215 |
"""Cyclades Network API extentions""" |
363 | 216 |
|
364 | 217 |
network_types = ( |
... | ... | |
379 | 232 |
return r.json['network'] |
380 | 233 |
|
381 | 234 |
def create_port( |
382 |
self, network_id, device_id, |
|
383 |
security_groups=None, name=None, fixed_ips=None): |
|
384 |
port = dict(network_id=network_id, device_id=device_id) |
|
235 |
self, network_id, |
|
236 |
device_id=None, security_groups=None, name=None, fixed_ips=None): |
|
237 |
port = dict(network_id=network_id) |
|
238 |
if device_id: |
|
239 |
port['device_id'] = device_id |
|
385 | 240 |
if security_groups: |
386 | 241 |
port['security_groups'] = security_groups |
387 | 242 |
if name: |
388 | 243 |
port['name'] = name |
389 |
for fixed_ip in fixed_ips: |
|
244 |
for fixed_ip in fixed_ips or []:
|
|
390 | 245 |
diff = set(['subnet_id', 'ip_address']).difference(fixed_ip) |
391 | 246 |
if diff: |
392 | 247 |
raise ValueError( |
... | ... | |
396 | 251 |
r = self.ports_post(json_data=dict(port=port), success=201) |
397 | 252 |
return r.json['port'] |
398 | 253 |
|
399 |
def wait_network(
|
|
400 |
self, net_id,
|
|
401 |
current_status='PENDING', delay=1, max_wait=100, wait_cb=None):
|
|
254 |
def create_floatingip(self, floating_network_id, floating_ip_address=''):
|
|
255 |
return super(CycladesNetworkClient, self).create_floatingip(
|
|
256 |
floating_network_id, floating_ip_address=floating_ip_address)
|
|
402 | 257 |
|
403 |
def get_status(self, net_id): |
|
404 |
r = self.get_network_details(net_id) |
|
405 |
return r['status'], None |
|
406 |
|
|
407 |
return self._wait( |
|
408 |
net_id, current_status, get_status, delay, max_wait, wait_cb) |
|
409 |
|
|
410 |
def wait_port( |
|
411 |
self, port_id, |
|
412 |
current_status='PENDING', delay=1, max_wait=100, wait_cb=None): |
|
413 |
|
|
414 |
def get_status(self, net_id): |
|
415 |
r = self.get_port_details(port_id) |
|
416 |
return r['status'], None |
|
417 |
|
|
418 |
return self._wait( |
|
419 |
port_id, current_status, get_status, delay, max_wait, wait_cb) |
|
258 |
def update_floatingip(self, floating_network_id, floating_ip_address=''): |
|
259 |
"""To nullify something optional, use None""" |
|
260 |
return super(CycladesNetworkClient, self).update_floatingip( |
|
261 |
floating_network_id, floating_ip_address=floating_ip_address) |
Also available in: Unified diff