Revision b19653d1
b/api/networks.py | ||
---|---|---|
13 | 13 |
urlpatterns = patterns('synnefo.api.networks', |
14 | 14 |
(r'^(?:/|.json|.xml)?$', 'demux'), |
15 | 15 |
(r'^/detail(?:.json|.xml)?$', 'list_networks', {'detail': True}), |
16 |
(r'^/(\w+)(?:.json|.xml)?$', 'network_demux'),
|
|
17 |
(r'^/(\w+)/action(?:.json|.xml)?$', 'network_action'),
|
|
16 |
(r'^/(\d+)(?:.json|.xml)?$', 'network_demux'),
|
|
17 |
(r'^/(\d+)/action(?:.json|.xml)?$', 'network_action'),
|
|
18 | 18 |
) |
19 | 19 |
|
20 | 20 |
|
... | ... | |
26 | 26 |
else: |
27 | 27 |
return method_not_allowed(request) |
28 | 28 |
|
29 |
def network_demux(request, network): |
|
29 |
def network_demux(request, network_id):
|
|
30 | 30 |
if request.method == 'GET': |
31 |
return get_network_details(request, network) |
|
31 |
return get_network_details(request, network_id)
|
|
32 | 32 |
elif request.method == 'PUT': |
33 |
return update_network_name(request, network) |
|
33 |
return update_network_name(request, network_id)
|
|
34 | 34 |
elif request.method == 'DELETE': |
35 |
return delete_network(request, network) |
|
35 |
return delete_network(request, network_id)
|
|
36 | 36 |
else: |
37 | 37 |
return method_not_allowed(request) |
38 | 38 |
|
39 | 39 |
|
40 | 40 |
def network_to_dict(network, detail=True): |
41 |
d = {'name': network.name} |
|
41 |
d = {'id': network.id, 'name': network.name}
|
|
42 | 42 |
if detail: |
43 | 43 |
d['servers'] = {'values': [vm.id for vm in network.machines.all()]} |
44 | 44 |
return d |
... | ... | |
96 | 96 |
except (KeyError, ValueError): |
97 | 97 |
raise BadRequest('Malformed request.') |
98 | 98 |
|
99 |
network, created = Network.objects.get_or_create(name=name, owner=request.user) |
|
100 |
if not created: |
|
101 |
raise BadRequest('Network already exists.') |
|
99 |
network = Network.objects.create(name=name, owner=request.user) |
|
102 | 100 |
networkdict = network_to_dict(network) |
103 | 101 |
return render_network(request, networkdict, status=202) |
104 | 102 |
|
105 | 103 |
@api_method('GET') |
106 |
def get_network_details(request, network): |
|
104 |
def get_network_details(request, network_id):
|
|
107 | 105 |
# Normal Response Codes: 200, 203 |
108 | 106 |
# Error Response Codes: computeFault (400, 500), |
109 | 107 |
# serviceUnavailable (503), |
... | ... | |
112 | 110 |
# itemNotFound (404), |
113 | 111 |
# overLimit (413) |
114 | 112 |
|
115 |
net = get_network(network, request.user) |
|
113 |
net = get_network(network_id, request.user)
|
|
116 | 114 |
netdict = network_to_dict(net) |
117 | 115 |
return render_network(request, netdict) |
118 | 116 |
|
119 | 117 |
@api_method('PUT') |
120 |
def update_network_name(request, network): |
|
118 |
def update_network_name(request, network_id):
|
|
121 | 119 |
# Normal Response Code: 204 |
122 | 120 |
# Error Response Codes: computeFault (400, 500), |
123 | 121 |
# serviceUnavailable (503), |
... | ... | |
134 | 132 |
except (TypeError, KeyError): |
135 | 133 |
raise BadRequest('Malformed request.') |
136 | 134 |
|
137 |
net = get_network(network, request.user) |
|
135 |
net = get_network(network_id, request.user)
|
|
138 | 136 |
net.name = name |
139 | 137 |
net.save() |
140 | 138 |
return HttpResponse(status=204) |
141 | 139 |
|
142 | 140 |
@api_method('DELETE') |
143 |
def delete_network(request, network): |
|
141 |
def delete_network(request, network_id):
|
|
144 | 142 |
# Normal Response Code: 204 |
145 | 143 |
# Error Response Codes: computeFault (400, 500), |
146 | 144 |
# serviceUnavailable (503), |
... | ... | |
149 | 147 |
# unauthorized (401), |
150 | 148 |
# overLimit (413) |
151 | 149 |
|
152 |
net = get_network(network, request.user) |
|
150 |
net = get_network(network_id, request.user)
|
|
153 | 151 |
net.delete() |
154 | 152 |
return HttpResponse(status=204) |
155 | 153 |
|
156 | 154 |
@api_method('POST') |
157 |
def network_action(request, network): |
|
158 |
net = get_network(network, request.user) |
|
155 |
def network_action(request, network_id):
|
|
156 |
net = get_network(network_id, request.user)
|
|
159 | 157 |
req = get_request_dict(request) |
160 | 158 |
if len(req) != 1: |
161 | 159 |
raise BadRequest('Malformed request.') |
b/api/servers.py | ||
---|---|---|
94 | 94 |
d['metadata'] = {'values': metadata} |
95 | 95 |
|
96 | 96 |
addresses = [address_to_dict(vm.ipfour, vm.ipsix)] |
97 |
addresses.extend({'id': network.name, 'values': []} for network in vm.network_set.all())
|
|
97 |
addresses.extend({'id': str(network.id), 'values': []} for network in vm.network_set.all())
|
|
98 | 98 |
d['addresses'] = {'values': addresses} |
99 | 99 |
return d |
100 | 100 |
|
b/api/tests.py | ||
---|---|---|
503 | 503 |
self.assertEqual(reply.keys(), ['network']) |
504 | 504 |
return reply |
505 | 505 |
|
506 |
def get_network_details(self, name):
|
|
507 |
path = '/api/v1.1/networks/%s' % name
|
|
506 |
def get_network_details(self, network_id):
|
|
507 |
path = '/api/v1.1/networks/%d' % network_id
|
|
508 | 508 |
response = self.client.get(path) |
509 | 509 |
self.assertEqual(response.status_code, 200) |
510 | 510 |
reply = json.loads(response.content) |
511 | 511 |
self.assertEqual(reply.keys(), ['network']) |
512 | 512 |
return reply['network'] |
513 | 513 |
|
514 |
def update_network_name(self, name, new_name):
|
|
515 |
path = '/api/v1.1/networks/%s' % name
|
|
514 |
def update_network_name(self, network_id, new_name):
|
|
515 |
path = '/api/v1.1/networks/%d' % network_id
|
|
516 | 516 |
data = json.dumps({'network': {'name': new_name}}) |
517 | 517 |
response = self.client.put(path, data, content_type='application/json') |
518 | 518 |
self.assertEqual(response.status_code, 204) |
519 | 519 |
|
520 |
def delete_network(self, name):
|
|
521 |
path = '/api/v1.1/networks/%s' % name
|
|
520 |
def delete_network(self, network_id):
|
|
521 |
path = '/api/v1.1/networks/%d' % network_id
|
|
522 | 522 |
response = self.client.delete(path) |
523 | 523 |
self.assertEqual(response.status_code, 204) |
524 | 524 |
|
525 |
def add_to_network(self, network_name, server_id):
|
|
526 |
path = '/api/v1.1/networks/%s/action' % network_name
|
|
525 |
def add_to_network(self, network_id, server_id):
|
|
526 |
path = '/api/v1.1/networks/%d/action' % network_id
|
|
527 | 527 |
data = json.dumps({'add': {'serverRef': server_id}}) |
528 | 528 |
response = self.client.post(path, data, content_type='application/json') |
529 | 529 |
self.assertEqual(response.status_code, 202) |
530 | 530 |
|
531 |
def remove_from_network(self, network_name, server_id):
|
|
532 |
path = '/api/v1.1/networks/%s/action' % network_name
|
|
531 |
def remove_from_network(self, network_id, server_id):
|
|
532 |
path = '/api/v1.1/networks/%d/action' % network_id
|
|
533 | 533 |
data = json.dumps({'remove': {'serverRef': server_id}}) |
534 | 534 |
response = self.client.post(path, data, content_type='application/json') |
535 | 535 |
self.assertEqual(response.status_code, 202) |
... | ... | |
823 | 823 |
def test_list_networks(self): |
824 | 824 |
networks = self.list_networks() |
825 | 825 |
for net in Network.objects.all(): |
826 |
popdict(networks, name=net.name) |
|
826 |
network = popdict(networks, id=net.id) |
|
827 |
self.assertEqual(network['name'], net.name) |
|
827 | 828 |
self.assertEqual(networks, []) |
828 | 829 |
|
829 | 830 |
def test_list_networks_detail(self): |
830 | 831 |
networks = self.list_networks(detail=True) |
831 | 832 |
for net in Network.objects.all(): |
832 |
network = popdict(networks, name=net.name) |
|
833 |
network = popdict(networks, id=net.id) |
|
834 |
self.assertEqual(network['name'], net.name) |
|
833 | 835 |
machines = set(vm.id for vm in net.machines.all()) |
834 | 836 |
self.assertEqual(set(network['servers']['values']), machines) |
835 | 837 |
self.assertEqual(networks, []) |
... | ... | |
852 | 854 |
def test_get_network_details(self): |
853 | 855 |
servers = VirtualMachine.objects.all() |
854 | 856 |
network = Network.objects.all()[0] |
855 |
name = network.name |
|
856 | 857 |
|
857 |
net = self.get_network_details(name) |
|
858 |
net = self.get_network_details(network.id) |
|
859 |
self.assertEqual(net['name'], network.name) |
|
858 | 860 |
self.assertEqual(net['servers']['values'], []) |
859 | 861 |
|
860 | 862 |
server_id = choice(servers).id |
861 |
self.add_to_network(name, server_id) |
|
862 |
net = self.get_network_details(name) |
|
863 |
self.add_to_network(network.id, server_id) |
|
864 |
net = self.get_network_details(network.id) |
|
865 |
self.assertEqual(net['name'], network.name) |
|
863 | 866 |
self.assertEqual(net['servers']['values'], [server_id]) |
864 | 867 |
|
865 | 868 |
|
... | ... | |
869 | 872 |
def test_update_network_name(self): |
870 | 873 |
networks = self.list_networks(detail=True) |
871 | 874 |
network = choice(networks) |
872 |
name = network['name']
|
|
873 |
new_name = name + '_2'
|
|
874 |
self.update_network_name(name, new_name)
|
|
875 |
network_id = network['id']
|
|
876 |
new_name = network['name'] + '_2'
|
|
877 |
self.update_network_name(network_id, new_name)
|
|
875 | 878 |
|
876 | 879 |
network['name'] = new_name |
877 |
self.assertEqual(self.get_network_details(new_name), network) |
|
878 |
|
|
879 |
response = self.client.get('/api/v1.1/networks/' + name) |
|
880 |
self.assertItemNotFound(response) |
|
880 |
self.assertEqual(self.get_network_details(network_id), network) |
|
881 | 881 |
|
882 | 882 |
|
883 | 883 |
class DeleteNetwork(BaseTestCase): |
... | ... | |
886 | 886 |
def test_delete_network(self): |
887 | 887 |
networks = self.list_networks() |
888 | 888 |
network = choice(networks) |
889 |
name = network['name']
|
|
890 |
self.delete_network(name)
|
|
889 |
network_id = network['id']
|
|
890 |
self.delete_network(network_id)
|
|
891 | 891 |
|
892 |
response = self.client.get('/api/v1.1/networks/' + name)
|
|
892 |
response = self.client.get('/api/v1.1/networks/%d' % network_id)
|
|
893 | 893 |
self.assertItemNotFound(response) |
894 | 894 |
|
895 | 895 |
networks.remove(network) |
... | ... | |
903 | 903 |
def test_add_remove_server(self): |
904 | 904 |
server_ids = [vm.id for vm in VirtualMachine.objects.all()] |
905 | 905 |
network = self.list_networks(detail=True)[0] |
906 |
name = network['name']
|
|
906 |
network_id = network['id']
|
|
907 | 907 |
|
908 | 908 |
to_add = set(sample(server_ids, 10)) |
909 | 909 |
for server_id in to_add: |
910 |
self.add_to_network(name, server_id)
|
|
911 |
net = self.get_network_details(name)
|
|
910 |
self.add_to_network(network_id, server_id)
|
|
911 |
net = self.get_network_details(network_id)
|
|
912 | 912 |
self.assertTrue(server_id in net['servers']['values']) |
913 | 913 |
|
914 |
net = self.get_network_details(name)
|
|
914 |
net = self.get_network_details(network_id)
|
|
915 | 915 |
self.assertEqual(set(net['servers']['values']), to_add) |
916 | 916 |
|
917 | 917 |
to_remove = set(sample(to_add, 5)) |
918 | 918 |
for server_id in to_remove: |
919 |
self.remove_from_network(name, server_id)
|
|
920 |
net = self.get_network_details(name)
|
|
919 |
self.remove_from_network(network_id, server_id)
|
|
920 |
net = self.get_network_details(network_id)
|
|
921 | 921 |
self.assertTrue(server_id not in net['servers']['values']) |
922 | 922 |
|
923 |
net = self.get_network_details(name)
|
|
923 |
net = self.get_network_details(network_id)
|
|
924 | 924 |
self.assertEqual(set(net['servers']['values']), to_add - to_remove) |
b/api/util.py | ||
---|---|---|
116 | 116 |
except Flavor.DoesNotExist: |
117 | 117 |
raise ItemNotFound('Flavor not found.') |
118 | 118 |
|
119 |
def get_network(network, owner): |
|
119 |
def get_network(network_id, owner):
|
|
120 | 120 |
"""Return a Network instance or raise ItemNotFound.""" |
121 | 121 |
|
122 | 122 |
try: |
123 |
return Network.objects.get(name=network, owner=owner)
|
|
123 |
return Network.objects.get(id=network_id, owner=owner)
|
|
124 | 124 |
except ValueError: |
125 |
raise BadRequest('Invalid network name.')
|
|
125 |
raise BadRequest('Invalid network ID.')
|
|
126 | 126 |
except Network.DoesNotExist: |
127 | 127 |
raise ItemNotFound('Network not found.') |
128 | 128 |
|
b/tools/cloud | ||
---|---|---|
336 | 336 |
print_dict(image) |
337 | 337 |
|
338 | 338 |
else: |
339 |
print '%3d %s' % (id, name)
|
|
339 |
print '%3d %s' % (id, name) |
|
340 | 340 |
|
341 | 341 |
|
342 | 342 |
@command_name('imginfo') |
... | ... | |
485 | 485 |
reply = self.http_get(path) |
486 | 486 |
|
487 | 487 |
for network in reply['networks']['values']: |
488 |
id = network.pop('id') |
|
488 | 489 |
name = network.pop('name') |
489 | 490 |
if self.detail: |
490 |
servers = network['servers']['values'] |
|
491 |
print '%s: %s' % (name, ', '.join(str(server_id) for server_id in servers)) |
|
491 |
print '%d %s' % (id, name) |
|
492 |
print_dict(network) |
|
493 |
|
|
492 | 494 |
else: |
493 |
print name
|
|
495 |
print '%3d %s' % (id, name)
|
|
494 | 496 |
|
495 | 497 |
|
496 | 498 |
@command_name('createnet') |
... | ... | |
509 | 511 |
@command_name('netinfo') |
510 | 512 |
class GetNetworkDetails(Command): |
511 | 513 |
description = 'get network details' |
512 |
syntax = '<network>' |
|
514 |
syntax = '<network id>'
|
|
513 | 515 |
|
514 |
def execute(self, network): |
|
515 |
path = '/api/%s/networks/%s' % (self.api, network)
|
|
516 |
def execute(self, network_id):
|
|
517 |
path = '/api/%s/networks/%d' % (self.api, int(network_id))
|
|
516 | 518 |
reply = self.http_get(path) |
517 | 519 |
net = reply['network'] |
518 |
name = net.pop('name')
|
|
520 |
name = net.pop('id')
|
|
519 | 521 |
print_dict(net) |
520 | 522 |
|
521 | 523 |
|
522 | 524 |
@command_name('renamenet') |
523 | 525 |
class UpdateNetworkName(Command): |
524 | 526 |
description = 'update network name' |
525 |
syntax = '<network> <new name>' |
|
527 |
syntax = '<network_id> <new name>'
|
|
526 | 528 |
|
527 |
def execute(self, network, name): |
|
528 |
path = '/api/%s/networks/%s' % (self.api, network)
|
|
529 |
def execute(self, network_id, name):
|
|
530 |
path = '/api/%s/networks/%d' % (self.api, int(network_id))
|
|
529 | 531 |
body = json.dumps({'network': {'name': name}}) |
530 | 532 |
self.http_put(path, body) |
531 | 533 |
|
... | ... | |
533 | 535 |
@command_name('deletenet') |
534 | 536 |
class DeleteNetwork(Command): |
535 | 537 |
description = 'delete network' |
536 |
syntax = '<network>' |
|
538 |
syntax = '<network id>'
|
|
537 | 539 |
|
538 |
def execute(self, network): |
|
539 |
path = '/api/%s/networks/%s' % (self.api, network)
|
|
540 |
def execute(self, network_id):
|
|
541 |
path = '/api/%s/networks/%d' % (self.api, int(network_id))
|
|
540 | 542 |
self.http_delete(path) |
541 | 543 |
|
542 | 544 |
|
543 | 545 |
@command_name('addnet') |
544 | 546 |
class AddNetwork(Command): |
545 | 547 |
description = 'add server to a network' |
546 |
syntax = '<server id> <network>' |
|
548 |
syntax = '<server id> <network id>'
|
|
547 | 549 |
|
548 |
def execute(self, server_id, network): |
|
549 |
path = '/api/%s/networks/%s/action' % (self.api, network)
|
|
550 |
def execute(self, server_id, network_id):
|
|
551 |
path = '/api/%s/networks/%d/action' % (self.api, int(network_id))
|
|
550 | 552 |
body = json.dumps({'add': {'serverRef': server_id}}) |
551 | 553 |
self.http_post(path, body, expected_status=202) |
552 | 554 |
|
... | ... | |
554 | 556 |
@command_name('removenet') |
555 | 557 |
class RemoveNetwork(Command): |
556 | 558 |
description = 'remove server from a network' |
557 |
syntax = '<server id> <network>' |
|
559 |
syntax = '<server id> <network id>'
|
|
558 | 560 |
|
559 |
def execute(self, server_id, network): |
|
560 |
path = '/api/%s/networks/%s/action' % (self.api, network)
|
|
561 |
def execute(self, server_id, network_id):
|
|
562 |
path = '/api/%s/networks/%s/action' % (self.api, int(network_id))
|
|
561 | 563 |
body = json.dumps({'remove': {'serverRef': server_id}}) |
562 | 564 |
self.http_post(path, body, expected_status=202) |
563 | 565 |
|
Also available in: Unified diff