Revision a3d99af0
b/snf-cyclades-app/synnefo/api/floating_ips.py | ||
---|---|---|
40 | 40 |
from snf_django.lib.api import faults, utils |
41 | 41 |
from synnefo.api import util |
42 | 42 |
from synnefo import quotas |
43 |
from synnefo.db.models import Network, FloatingIP |
|
43 |
from synnefo.db.models import Network, FloatingIP, NetworkInterface
|
|
44 | 44 |
|
45 | 45 |
|
46 | 46 |
from logging import getLogger |
... | ... | |
137 | 137 |
except Network.DoesNotExist: |
138 | 138 |
raise faults.ItemNotFound("Pool '%s' does not exist." % pool) |
139 | 139 |
|
140 |
address = req.get("address", None) |
|
141 |
machine = None |
|
140 | 142 |
try: |
141 |
address = util.get_network_free_address(network) |
|
143 |
if address is None: |
|
144 |
address = util.get_network_free_address(network) # Get X-Lock |
|
145 |
else: |
|
146 |
if FloatingIP.objects.filter(network=network, |
|
147 |
ipv4=address).exists(): |
|
148 |
msg = "Floating IP '%s' is reserved" % address |
|
149 |
raise faults.Conflict(msg) |
|
150 |
pool = network.get_pool() # Gets X-Lock |
|
151 |
if not pool.contains(address): |
|
152 |
raise faults.BadRequest("Invalid address") |
|
153 |
if not pool.is_available(address): |
|
154 |
try: |
|
155 |
network.nics.get(ipv4=address, |
|
156 |
machine__userid=userid) |
|
157 |
except NetworkInterface.DoesNotExist: |
|
158 |
msg = "Address '%s' is already in use" % address |
|
159 |
raise faults.Conflict(msg) |
|
160 |
pool.reserve(address) |
|
161 |
pool.save() |
|
142 | 162 |
floating_ip = FloatingIP.objects.create(ipv4=address, network=network, |
143 |
userid=userid) |
|
163 |
userid=userid, machine=machine)
|
|
144 | 164 |
quotas.issue_and_accept_commission(floating_ip) |
145 | 165 |
except: |
146 | 166 |
transaction.rollback() |
b/snf-cyclades-app/synnefo/api/test/floating_ips.py | ||
---|---|---|
108 | 108 |
response = self.post(URL, "test_user", json.dumps(request), "json") |
109 | 109 |
self.assertEqual(response.status_code, 413) |
110 | 110 |
|
111 |
def test_reserve_with_address(self): |
|
112 |
net = NetworkFactory(userid="test_user", subnet="192.168.2.0/24", |
|
113 |
gateway=None, public=True) |
|
114 |
request = {'pool': net.id, "address": "192.168.2.10"} |
|
115 |
with mocked_quotaholder(): |
|
116 |
response = self.post(URL, "test_user", json.dumps(request), "json") |
|
117 |
self.assertSuccess(response) |
|
118 |
self.assertEqual(json.loads(response.content)["floating_ip"], |
|
119 |
{"instance_id": None, "ip": "192.168.2.10", |
|
120 |
"fixed_ip": None, "id": "1", "pool": "1"}) |
|
121 |
|
|
122 |
# Already reserved |
|
123 |
FloatingIPFactory(network=net, ipv4="192.168.2.3") |
|
124 |
request = {'pool': net.id, "address": "192.168.2.3"} |
|
125 |
with mocked_quotaholder(): |
|
126 |
response = self.post(URL, "test_user", json.dumps(request), "json") |
|
127 |
self.assertFault(response, 409, "conflict") |
|
128 |
|
|
129 |
# Already used |
|
130 |
pool = net.get_pool() |
|
131 |
pool.reserve("192.168.2.5") |
|
132 |
pool.save() |
|
133 |
# ..by another_user |
|
134 |
nic = NetworkInterfaceFactory(network=net, ipv4="192.168.2.5", |
|
135 |
machine__userid="test2") |
|
136 |
request = {'pool': net.id, "address": "192.168.2.5"} |
|
137 |
with mocked_quotaholder(): |
|
138 |
response = self.post(URL, "test_user", json.dumps(request), "json") |
|
139 |
self.assertFault(response, 409, "conflict") |
|
140 |
# ..and by him |
|
141 |
nic.delete() |
|
142 |
NetworkInterfaceFactory(network=net, ipv4="192.168.2.5", |
|
143 |
machine__userid="test_user") |
|
144 |
request = {'pool': net.id, "address": "192.168.2.5"} |
|
145 |
with mocked_quotaholder(): |
|
146 |
response = self.post(URL, "test_user", json.dumps(request), "json") |
|
147 |
self.assertSuccess(response) |
|
148 |
|
|
149 |
# Address out of pool |
|
150 |
request = {'pool': net.id, "address": "192.168.3.5"} |
|
151 |
with mocked_quotaholder(): |
|
152 |
response = self.post(URL, "test_user", json.dumps(request), "json") |
|
153 |
self.assertBadRequest(response) |
|
154 |
|
|
111 | 155 |
def test_release_in_use(self): |
112 | 156 |
ip = FloatingIPFactory() |
113 | 157 |
vm = ip.machine |
b/snf-cyclades-app/synnefo/db/pools/__init__.py | ||
---|---|---|
264 | 264 |
|
265 | 265 |
def index_to_value(self, index): |
266 | 266 |
return str(self.net[index]) |
267 |
|
|
268 |
def contains(self, address): |
|
269 |
addr = ipaddr.IPAddress(address) |
|
270 |
return addr in self.net |
b/snf-cyclades-app/synnefo/db/pools/tests.py | ||
---|---|---|
220 | 220 |
self.assertEqual(pool.is_available('192.168.2.255'), False) |
221 | 221 |
self.assertEqual(pool.count_available(), 253) |
222 | 222 |
self.assertEqual(pool.get(), '192.168.2.2') |
223 |
self.assertTrue(pool.contains("192.168.2.10")) |
|
224 |
self.assertFalse(pool.contains("192.168.3.10")) |
|
223 | 225 |
|
224 | 226 |
def test_auto_reservations_2(self): |
225 | 227 |
obj = DummyObject(0) |
Also available in: Unified diff