Revision 4edfc376
b/snf-cyclades-app/synnefo/api/floating_ips.py | ||
---|---|---|
143 | 143 |
userid = request.user_uniq |
144 | 144 |
|
145 | 145 |
# the network_pool is a mandatory field |
146 |
network_pool = api.utils.get_attribute(floating_ip_dict, |
|
147 |
"floating_network_id", |
|
148 |
required=True) |
|
149 |
address = api.utils.get_attribute(floating_ip_dict, "floating_ip_address", |
|
150 |
required=False) |
|
151 |
|
|
152 |
try: |
|
153 |
network_id = int(network_pool) |
|
154 |
except ValueError: |
|
155 |
raise faults.BadRequest("Invalid networkd ID.") |
|
156 |
network = util.get_network(network_id, userid, for_update=True, |
|
157 |
non_deleted=True) |
|
158 |
|
|
159 |
if not network.floating_ip_pool: |
|
160 |
# Check that it is a floating IP pool |
|
161 |
raise faults.ItemNotFound("Floating IP pool %s does not exist." % |
|
162 |
network_id) |
|
163 |
|
|
164 |
# Allocate the floating IP |
|
165 |
floating_ip = util.allocate_ip(network, userid, address=address, |
|
166 |
floating_ip=True) |
|
146 |
network_id = api.utils.get_attribute(floating_ip_dict, |
|
147 |
"floating_network_id", |
|
148 |
required=False) |
|
149 |
if network_id is None: |
|
150 |
floating_ip = util.allocate_public_ip(userid, floating_ip=True) |
|
151 |
else: |
|
152 |
try: |
|
153 |
network_id = int(network_id) |
|
154 |
except ValueError: |
|
155 |
raise faults.BadRequest("Invalid networkd ID.") |
|
156 |
|
|
157 |
network = util.get_network(network_id, userid, for_update=True, |
|
158 |
non_deleted=True) |
|
159 |
if not network.floating_ip_pool: |
|
160 |
# TODO: Maybe 409 ?? |
|
161 |
# Check that it is a floating IP pool |
|
162 |
raise faults.ItemNotFound("Floating IP pool %s does not exist." % |
|
163 |
network_id) |
|
164 |
|
|
165 |
address = api.utils.get_attribute(floating_ip_dict, |
|
166 |
"floating_ip_address", |
|
167 |
required=False) |
|
168 |
|
|
169 |
# Allocate the floating IP |
|
170 |
floating_ip = util.allocate_ip(network, userid, address=address, |
|
171 |
floating_ip=True) |
|
172 |
|
|
167 | 173 |
# Issue commission (quotas) |
168 | 174 |
quotas.issue_and_accept_commission(floating_ip) |
169 | 175 |
transaction.commit() |
b/snf-cyclades-app/synnefo/api/tests/floating_ips.py | ||
---|---|---|
33 | 33 |
|
34 | 34 |
from django.utils import simplejson as json |
35 | 35 |
from snf_django.utils.testing import BaseAPITest, mocked_quotaholder |
36 |
from synnefo.db.models import IPAddress |
|
36 |
from synnefo.db.models import IPAddress, Network
|
|
37 | 37 |
from synnefo.db import models_factory as mf |
38 |
from synnefo.db.models_factory import (NetworkFactory, |
|
39 |
VirtualMachineFactory) |
|
40 | 38 |
|
41 | 39 |
from mock import patch, Mock |
42 |
from functools import partial |
|
43 | 40 |
|
44 | 41 |
from synnefo.cyclades_settings import cyclades_services |
45 | 42 |
from synnefo.lib.services import get_service_path |
... | ... | |
53 | 50 |
|
54 | 51 |
|
55 | 52 |
floating_ips = IPAddress.objects.filter(floating_ip=True) |
56 |
FloatingIPPoolFactory = partial(NetworkFactory, public=True, deleted=False, |
|
57 |
floating_ip_pool=True) |
|
58 | 53 |
|
59 | 54 |
|
60 | 55 |
class FloatingIPAPITest(BaseAPITest): |
... | ... | |
128 | 123 |
"port_id": None, |
129 | 124 |
"floating_network_id": str(self.pool.id)}) |
130 | 125 |
|
126 |
def test_reserve_empty_body(self): |
|
127 |
"""Test reserve FIP without specifying network.""" |
|
128 |
request = {"floatingip": {}} |
|
129 |
# delete all pools.. |
|
130 |
Network.objects.all().delete() |
|
131 |
# CASE: no floating IP pool |
|
132 |
with mocked_quotaholder(): |
|
133 |
response = self.post(URL, "test_user", json.dumps(request), "json") |
|
134 |
self.assertConflict(response) |
|
135 |
# CASE: Full floating IP pool |
|
136 |
mf.NetworkWithSubnetFactory(floating_ip_pool=True, public=True, |
|
137 |
subnet__pool__size=0) |
|
138 |
with mocked_quotaholder(): |
|
139 |
response = self.post(URL, "test_user", json.dumps(request), "json") |
|
140 |
self.assertConflict(response) |
|
141 |
# CASE: Available floating IP pool |
|
142 |
p1 = mf.NetworkWithSubnetFactory(floating_ip_pool=True, public=True, |
|
143 |
subnet__cidr="192.168.2.0/30", |
|
144 |
subnet__pool__size=1) |
|
145 |
with mocked_quotaholder(): |
|
146 |
response = self.post(URL, "test_user", json.dumps(request), "json") |
|
147 |
self.assertSuccess(response) |
|
148 |
floating_ip = json.loads(response.content)["floatingip"] |
|
149 |
db_fip = IPAddress.objects.get(id=floating_ip["id"]) |
|
150 |
self.assertEqual(db_fip.address, floating_ip["floating_ip_address"]) |
|
151 |
self.assertTrue(db_fip.floating_ip) |
|
152 |
# Test that address is reserved |
|
153 |
ip_pool = p1.get_ip_pools()[0] |
|
154 |
self.assertFalse(ip_pool.is_available(db_fip.address)) |
|
155 |
|
|
131 | 156 |
def test_reserve_no_pool(self): |
132 | 157 |
# Network is not a floating IP pool |
133 | 158 |
pool2 = mf.NetworkWithSubnetFactory(floating_ip_pool=False, |
b/snf-cyclades-app/synnefo/api/util.py | ||
---|---|---|
358 | 358 |
log_msg += " Backend: %s" % backend |
359 | 359 |
log.error(log_msg) |
360 | 360 |
exception_msg = "Can not allocate a %s IP address." % ip_type |
361 |
raise faults.ServiceUnavailable(exception_msg) |
|
361 |
if floating_ip: |
|
362 |
raise faults.Conflict(exception_msg) |
|
363 |
else: |
|
364 |
raise faults.ServiceUnavailable(exception_msg) |
|
362 | 365 |
|
363 | 366 |
|
364 | 367 |
def backend_has_free_public_ip(backend): |
Also available in: Unified diff