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