Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / tests / floating_ips.py @ b9364b15

History | View | Annotate | Download (18.1 kB)

1 acda838e Christos Stavrakakis
# Copyright 2012 GRNET S.A. All rights reserved.
2 acda838e Christos Stavrakakis
#
3 acda838e Christos Stavrakakis
# Redistribution and use in source and binary forms, with or
4 acda838e Christos Stavrakakis
# without modification, are permitted provided that the following
5 acda838e Christos Stavrakakis
# conditions are met:
6 acda838e Christos Stavrakakis
#
7 acda838e Christos Stavrakakis
#   1. Redistributions of source code must retain the above
8 acda838e Christos Stavrakakis
#      copyright notice, this list of conditions and the following
9 acda838e Christos Stavrakakis
#      disclaimer.
10 acda838e Christos Stavrakakis
#
11 acda838e Christos Stavrakakis
#   2. Redistributions in binary form must reproduce the above
12 acda838e Christos Stavrakakis
#      copyright notice, this list of conditions and the following
13 acda838e Christos Stavrakakis
#      disclaimer in the documentation and/or other materials
14 acda838e Christos Stavrakakis
#      provided with the distribution.
15 acda838e Christos Stavrakakis
#
16 acda838e Christos Stavrakakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 acda838e Christos Stavrakakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 acda838e Christos Stavrakakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 acda838e Christos Stavrakakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 acda838e Christos Stavrakakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 acda838e Christos Stavrakakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 acda838e Christos Stavrakakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 acda838e Christos Stavrakakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 acda838e Christos Stavrakakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 acda838e Christos Stavrakakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 acda838e Christos Stavrakakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 acda838e Christos Stavrakakis
# POSSIBILITY OF SUCH DAMAGE.
28 acda838e Christos Stavrakakis
#
29 acda838e Christos Stavrakakis
# The views and conclusions contained in the software and
30 acda838e Christos Stavrakakis
# documentation are those of the authors and should not be
31 acda838e Christos Stavrakakis
# interpreted as representing official policies, either expressed
32 acda838e Christos Stavrakakis
# or implied, of GRNET S.A.
33 acda838e Christos Stavrakakis
34 e4f484da Marios Kogias
from django.utils import simplejson as json
35 acda838e Christos Stavrakakis
from snf_django.utils.testing import BaseAPITest, mocked_quotaholder
36 326c3ec8 Christos Stavrakakis
from synnefo.db.models import IPAddress
37 fde2c1f7 Christos Stavrakakis
from synnefo.db import models_factory as mf
38 fde2c1f7 Christos Stavrakakis
from synnefo.db.models_factory import (NetworkFactory,
39 fde2c1f7 Christos Stavrakakis
                                       VirtualMachineFactory)
40 e4f484da Marios Kogias
41 b9364b15 Marios Kogias
from mock import patch, Mock
42 9115d567 Christos Stavrakakis
from functools import partial
43 acda838e Christos Stavrakakis
44 2cd55da6 Christos Stavrakakis
from synnefo.cyclades_settings import cyclades_services
45 2cd55da6 Christos Stavrakakis
from synnefo.lib.services import get_service_path
46 2cd55da6 Christos Stavrakakis
from synnefo.lib import join_urls
47 acda838e Christos Stavrakakis
48 2cd55da6 Christos Stavrakakis
49 2cd55da6 Christos Stavrakakis
compute_path = get_service_path(cyclades_services, "compute", version="v2.0")
50 e4f484da Marios Kogias
URL = join_urls(compute_path, "floatingips")
51 2cd55da6 Christos Stavrakakis
NETWORKS_URL = join_urls(compute_path, "networks")
52 2cd55da6 Christos Stavrakakis
SERVERS_URL = join_urls(compute_path, "servers")
53 acda838e Christos Stavrakakis
54 92d2d1ce Christos Stavrakakis
55 92d2d1ce Christos Stavrakakis
floating_ips = IPAddress.objects.filter(floating_ip=True)
56 92d2d1ce Christos Stavrakakis
FloatingIPPoolFactory = partial(NetworkFactory, public=True, deleted=False,
57 9115d567 Christos Stavrakakis
                                floating_ip_pool=True)
58 9115d567 Christos Stavrakakis
59 acda838e Christos Stavrakakis
60 92d2d1ce Christos Stavrakakis
class FloatingIPAPITest(BaseAPITest):
61 fde2c1f7 Christos Stavrakakis
    def setUp(self):
62 fde2c1f7 Christos Stavrakakis
        self.pool = mf.NetworkWithSubnetFactory(floating_ip_pool=True,
63 fde2c1f7 Christos Stavrakakis
                                                public=True,
64 fde2c1f7 Christos Stavrakakis
                                                subnet__cidr="192.168.2.0/24",
65 fde2c1f7 Christos Stavrakakis
                                                subnet__gateway="192.168.2.1")
66 fde2c1f7 Christos Stavrakakis
67 acda838e Christos Stavrakakis
    def test_no_floating_ip(self):
68 acda838e Christos Stavrakakis
        response = self.get(URL)
69 acda838e Christos Stavrakakis
        self.assertSuccess(response)
70 acda838e Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ips"], [])
71 acda838e Christos Stavrakakis
72 acda838e Christos Stavrakakis
    def test_list_ips(self):
73 fde2c1f7 Christos Stavrakakis
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True)
74 acda838e Christos Stavrakakis
        with mocked_quotaholder():
75 acda838e Christos Stavrakakis
            response = self.get(URL, "user1")
76 acda838e Christos Stavrakakis
        self.assertSuccess(response)
77 acda838e Christos Stavrakakis
        api_ip = json.loads(response.content)["floating_ips"][0]
78 acda838e Christos Stavrakakis
        self.assertEqual(api_ip,
79 fde2c1f7 Christos Stavrakakis
                         {"instance_id": str(ip.nic.machine_id),
80 e4f484da Marios Kogias
                          "floating_ip_address": ip.address,
81 e4f484da Marios Kogias
                          "fixed_ip_address": None,
82 fde2c1f7 Christos Stavrakakis
                          "id": str(ip.id),
83 e4f484da Marios Kogias
                          "port_id": str(ip.nic.id),
84 e4f484da Marios Kogias
                          "floating_network_id": str(ip.network_id)})
85 acda838e Christos Stavrakakis
86 acda838e Christos Stavrakakis
    def test_get_ip(self):
87 fde2c1f7 Christos Stavrakakis
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True)
88 acda838e Christos Stavrakakis
        with mocked_quotaholder():
89 acda838e Christos Stavrakakis
            response = self.get(URL + "/%s" % ip.id, "user1")
90 acda838e Christos Stavrakakis
        self.assertSuccess(response)
91 acda838e Christos Stavrakakis
        api_ip = json.loads(response.content)["floating_ip"]
92 acda838e Christos Stavrakakis
        self.assertEqual(api_ip,
93 fde2c1f7 Christos Stavrakakis
                         {"instance_id": str(ip.nic.machine_id),
94 e4f484da Marios Kogias
                          "floating_ip_address": ip.address,
95 e4f484da Marios Kogias
                          "fixed_ip_address": None,
96 fde2c1f7 Christos Stavrakakis
                          "id": str(ip.id),
97 e4f484da Marios Kogias
                          "port_id": str(ip.nic.id),
98 e4f484da Marios Kogias
                          "floating_network_id": str(ip.network_id)})
99 acda838e Christos Stavrakakis
100 acda838e Christos Stavrakakis
    def test_wrong_user(self):
101 fde2c1f7 Christos Stavrakakis
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True)
102 fde2c1f7 Christos Stavrakakis
        response = self.delete(URL + "/%s" % ip.id, "user2")
103 acda838e Christos Stavrakakis
        self.assertItemNotFound(response)
104 acda838e Christos Stavrakakis
105 acda838e Christos Stavrakakis
    def test_deleted_ip(self):
106 fde2c1f7 Christos Stavrakakis
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True,
107 fde2c1f7 Christos Stavrakakis
                                   deleted=True)
108 fde2c1f7 Christos Stavrakakis
        response = self.delete(URL + "/%s" % ip.id, "user1")
109 acda838e Christos Stavrakakis
        self.assertItemNotFound(response)
110 acda838e Christos Stavrakakis
111 acda838e Christos Stavrakakis
    def test_reserve(self):
112 e4f484da Marios Kogias
        request = {"floatingip": {
113 e4f484da Marios Kogias
            "floating_network_id": self.pool.id}
114 e4f484da Marios Kogias
            }
115 acda838e Christos Stavrakakis
        with mocked_quotaholder():
116 acda838e Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
117 acda838e Christos Stavrakakis
        self.assertSuccess(response)
118 e4f484da Marios Kogias
        api_ip = json.loads(response.content, encoding="utf-8")["floating_ip"]
119 92d2d1ce Christos Stavrakakis
        ip = floating_ips.get()
120 fde2c1f7 Christos Stavrakakis
        self.assertEqual(ip.address, "192.168.2.2")
121 fde2c1f7 Christos Stavrakakis
        self.assertEqual(ip.nic, None)
122 fde2c1f7 Christos Stavrakakis
        self.assertEqual(ip.network, self.pool)
123 e4f484da Marios Kogias
        self.assertEqual(api_ip,
124 e4f484da Marios Kogias
                         {"instance_id": None,
125 e4f484da Marios Kogias
                          "floating_ip_address": "192.168.2.2",
126 e4f484da Marios Kogias
                          "fixed_ip_address": None,
127 e4f484da Marios Kogias
                          "id": str(ip.id),
128 e4f484da Marios Kogias
                          "port_id": None,
129 e4f484da Marios Kogias
                          "floating_network_id": str(self.pool.id)})
130 acda838e Christos Stavrakakis
131 9e8be4fb Christos Stavrakakis
    def test_reserve_no_pool(self):
132 e4f484da Marios Kogias
        # Network is not a floating IP pool
133 e4f484da Marios Kogias
        pool2 = mf.NetworkWithSubnetFactory(floating_ip_pool=False,
134 e4f484da Marios Kogias
                                            public=True,
135 e4f484da Marios Kogias
                                            subnet__cidr="192.168.2.0/24",
136 e4f484da Marios Kogias
                                            subnet__gateway="192.168.2.1")
137 e4f484da Marios Kogias
        request = {"floatingip": {
138 e4f484da Marios Kogias
            'floating_network_id': pool2.id}
139 e4f484da Marios Kogias
            }
140 e4f484da Marios Kogias
        response = self.post(URL, "test_user", json.dumps(request), "json")
141 e4f484da Marios Kogias
        self.assertEqual(response.status_code, 404)
142 fde2c1f7 Christos Stavrakakis
143 9e8be4fb Christos Stavrakakis
        # Full network
144 0711e5aa Christos Stavrakakis
        net = mf.NetworkWithSubnetFactory(floating_ip_pool=True,
145 0711e5aa Christos Stavrakakis
                                          public=True,
146 0711e5aa Christos Stavrakakis
                                          subnet__cidr="192.168.2.0/31",
147 0711e5aa Christos Stavrakakis
                                          subnet__gateway="192.168.2.1",
148 0711e5aa Christos Stavrakakis
                                          subnet__pool__size=0)
149 e4f484da Marios Kogias
        request = {"floatingip": {
150 e4f484da Marios Kogias
            'floating_network_id': net.id}
151 e4f484da Marios Kogias
            }
152 fde2c1f7 Christos Stavrakakis
        response = self.post(URL, "test_user", json.dumps(request), "json")
153 fde2c1f7 Christos Stavrakakis
        self.assertConflict(response)
154 acda838e Christos Stavrakakis
155 a3d99af0 Christos Stavrakakis
    def test_reserve_with_address(self):
156 e4f484da Marios Kogias
        request = {"floatingip": {
157 e4f484da Marios Kogias
            "floating_network_id": self.pool.id,
158 e4f484da Marios Kogias
            "floating_ip_address": "192.168.2.10"}
159 e4f484da Marios Kogias
            }
160 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
161 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
162 a3d99af0 Christos Stavrakakis
        self.assertSuccess(response)
163 92d2d1ce Christos Stavrakakis
        ip = floating_ips.get()
164 a3d99af0 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip"],
165 e4f484da Marios Kogias
                         {"instance_id": None,
166 e4f484da Marios Kogias
                          "floating_ip_address": "192.168.2.10",
167 e4f484da Marios Kogias
                          "fixed_ip_address": None,
168 e4f484da Marios Kogias
                          "id": str(ip.id),
169 e4f484da Marios Kogias
                          "port_id": None,
170 e4f484da Marios Kogias
                          "floating_network_id": str(self.pool.id)})
171 a3d99af0 Christos Stavrakakis
172 a3d99af0 Christos Stavrakakis
        # Already reserved
173 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
174 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
175 a3d99af0 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
176 a3d99af0 Christos Stavrakakis
177 fde2c1f7 Christos Stavrakakis
        # Used by instance
178 fde2c1f7 Christos Stavrakakis
        self.pool.reserve_address("192.168.2.20")
179 e4f484da Marios Kogias
        request = {"floatingip": {
180 e4f484da Marios Kogias
            "floating_network_id": self.pool.id,
181 e4f484da Marios Kogias
            "floating_ip_address": "192.168.2.20"}
182 e4f484da Marios Kogias
            }
183 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
184 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
185 a3d99af0 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
186 a3d99af0 Christos Stavrakakis
187 a3d99af0 Christos Stavrakakis
        # Address out of pool
188 e4f484da Marios Kogias
        request = {"floatingip": {
189 e4f484da Marios Kogias
            "floating_network_id": self.pool.id,
190 e4f484da Marios Kogias
            "floating_ip_address": "192.168.3.5"}
191 e4f484da Marios Kogias
            }
192 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
193 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
194 a3d99af0 Christos Stavrakakis
        self.assertBadRequest(response)
195 a3d99af0 Christos Stavrakakis
196 e4f484da Marios Kogias
    @patch("synnefo.db.models.get_rapi_client")
197 e4f484da Marios Kogias
    def test_reserve_and_connect(self, mrapi):
198 e4f484da Marios Kogias
        vm = mf.VirtualMachineFactory(userid="test_user")
199 e4f484da Marios Kogias
        request = {"floatingip": {
200 e4f484da Marios Kogias
            "floating_network_id": self.pool.id,
201 e4f484da Marios Kogias
            "floating_ip_address": "192.168.2.12",
202 e4f484da Marios Kogias
            "device_id": vm.id}
203 e4f484da Marios Kogias
            }
204 e4f484da Marios Kogias
        response = self.post(URL, "test_user", json.dumps(request), "json")
205 e4f484da Marios Kogias
        ip = floating_ips.get()
206 e4f484da Marios Kogias
        api_ip = json.loads(response.content, "utf-8")["floating_ip"]
207 e4f484da Marios Kogias
        self.assertEqual(api_ip,
208 e4f484da Marios Kogias
                         {"instance_id": str(vm.id),
209 e4f484da Marios Kogias
                          "floating_ip_address": "192.168.2.12",
210 e4f484da Marios Kogias
                          "fixed_ip_address": None,
211 e4f484da Marios Kogias
                          "id": str(ip.id),
212 e4f484da Marios Kogias
                          "port_id": str(vm.nics.all()[0].id),
213 e4f484da Marios Kogias
                          "floating_network_id": str(self.pool.id)})
214 e4f484da Marios Kogias
215 e4f484da Marios Kogias
    @patch("synnefo.db.models.get_rapi_client")
216 e4f484da Marios Kogias
    def test_update_attach(self, mrapi):
217 e4f484da Marios Kogias
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True, nic=None)
218 e4f484da Marios Kogias
        vm = mf.VirtualMachineFactory(userid="user1")
219 e4f484da Marios Kogias
        request = {"floatingip": {
220 e4f484da Marios Kogias
            "device_id": vm.id}
221 e4f484da Marios Kogias
            }
222 e4f484da Marios Kogias
        with mocked_quotaholder():
223 e4f484da Marios Kogias
            response = self.put(URL + "/%s" % ip.id, "user1",
224 e4f484da Marios Kogias
                                json.dumps(request), "json")
225 e4f484da Marios Kogias
        self.assertEqual(response.status_code, 202)
226 e4f484da Marios Kogias
227 e4f484da Marios Kogias
    def test_update_attach_conflict(self):
228 e4f484da Marios Kogias
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True)
229 e4f484da Marios Kogias
        vm = mf.VirtualMachineFactory(userid="user1")
230 e4f484da Marios Kogias
        request = {"floatingip": {
231 e4f484da Marios Kogias
            "device_id": vm.id}
232 e4f484da Marios Kogias
            }
233 e4f484da Marios Kogias
        with mocked_quotaholder():
234 e4f484da Marios Kogias
            response = self.put(URL + "/%s" % ip.id, "user1",
235 e4f484da Marios Kogias
                                json.dumps(request), "json")
236 e4f484da Marios Kogias
        self.assertEqual(response.status_code, 409)
237 e4f484da Marios Kogias
238 e4f484da Marios Kogias
    @patch("synnefo.db.models.get_rapi_client")
239 e4f484da Marios Kogias
    def test_update_dettach(self, mrapi):
240 e4f484da Marios Kogias
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True)
241 e4f484da Marios Kogias
        request = {"floatingip": {
242 e4f484da Marios Kogias
            "device_id": None}
243 e4f484da Marios Kogias
            }
244 e4f484da Marios Kogias
        mrapi().ModifyInstance.return_value = 42
245 e4f484da Marios Kogias
        with mocked_quotaholder():
246 e4f484da Marios Kogias
            response = self.put(URL + "/%s" % ip.id, "user1",
247 e4f484da Marios Kogias
                                json.dumps(request), "json")
248 e4f484da Marios Kogias
        self.assertEqual(response.status_code, 202)
249 e4f484da Marios Kogias
250 e4f484da Marios Kogias
    def test_update_dettach_unassociated(self):
251 e4f484da Marios Kogias
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True, nic=None)
252 e4f484da Marios Kogias
        request = {"floatingip": {}}
253 e4f484da Marios Kogias
        with mocked_quotaholder():
254 e4f484da Marios Kogias
            response = self.put(URL + "/%s" % ip.id, "user1",
255 e4f484da Marios Kogias
                                json.dumps(request), "json")
256 e4f484da Marios Kogias
        self.assertEqual(response.status_code, 400)
257 e4f484da Marios Kogias
258 acda838e Christos Stavrakakis
    def test_release_in_use(self):
259 fde2c1f7 Christos Stavrakakis
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True)
260 b9364b15 Marios Kogias
        vm = mf.VirtualMachineFactory(userid="user1")
261 b9364b15 Marios Kogias
        request = {"floatingip": {
262 b9364b15 Marios Kogias
            "device_id": vm.id}
263 b9364b15 Marios Kogias
            }
264 a95c82a9 Christos Stavrakakis
        with mocked_quotaholder():
265 b9364b15 Marios Kogias
            response = self.put(URL + "/%s" % ip.id, "user1",
266 b9364b15 Marios Kogias
                                json.dumps(request), "json")
267 b9364b15 Marios Kogias
        self.assertEqual(response.status_code, 409)
268 b9364b15 Marios Kogias
269 b9364b15 Marios Kogias
    @patch("synnefo.db.models.get_rapi_client")
270 b9364b15 Marios Kogias
    def test_update_dettach(self, mrapi):
271 b9364b15 Marios Kogias
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True)
272 b9364b15 Marios Kogias
        request = {"floatingip": {
273 b9364b15 Marios Kogias
            "device_id": None}
274 b9364b15 Marios Kogias
            }
275 b9364b15 Marios Kogias
        mrapi().ModifyInstance.return_value = 42
276 b9364b15 Marios Kogias
        with mocked_quotaholder():
277 b9364b15 Marios Kogias
            response = self.put(URL + "/%s" % ip.id, "user1",
278 b9364b15 Marios Kogias
                                json.dumps(request), "json")
279 b9364b15 Marios Kogias
        print response.content
280 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
281 b9364b15 Marios Kogias
282 b9364b15 Marios Kogias
    def test_update_dettach_unassociated(self):
283 b9364b15 Marios Kogias
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True, nic=None)
284 b9364b15 Marios Kogias
        request = {"floatingip": {}}
285 b9364b15 Marios Kogias
        with mocked_quotaholder():
286 b9364b15 Marios Kogias
            response = self.put(URL + "/%s" % ip.id, "user1",
287 b9364b15 Marios Kogias
                                json.dumps(request), "json")
288 b9364b15 Marios Kogias
        self.assertEqual(response.status_code, 400)
289 b9364b15 Marios Kogias
290 b9364b15 Marios Kogias
    def test_release_in_use(self):
291 b9364b15 Marios Kogias
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True)
292 b9364b15 Marios Kogias
        vm = ip.nic.machine
293 acda838e Christos Stavrakakis
        with mocked_quotaholder():
294 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, ip.userid)
295 acda838e Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
296 acda838e Christos Stavrakakis
297 acda838e Christos Stavrakakis
    def test_release(self):
298 fde2c1f7 Christos Stavrakakis
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True, nic=None)
299 acda838e Christos Stavrakakis
        with mocked_quotaholder():
300 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, ip.userid)
301 acda838e Christos Stavrakakis
        self.assertSuccess(response)
302 92d2d1ce Christos Stavrakakis
        ips_after = floating_ips.filter(id=ip.id)
303 acda838e Christos Stavrakakis
        self.assertEqual(len(ips_after), 0)
304 b9364b15 Marios Kogias
305 e57893cd Christos Stavrakakis
    @patch("synnefo.logic.backend", Mock())
306 e57893cd Christos Stavrakakis
    def test_delete_network_with_floating_ips(self):
307 fde2c1f7 Christos Stavrakakis
        ip = mf.IPv4AddressFactory(userid="user1", floating_ip=True,
308 fde2c1f7 Christos Stavrakakis
                                   network=self.pool, nic=None)
309 fde2c1f7 Christos Stavrakakis
        # Mark the network as non-pubic to not get 403
310 fde2c1f7 Christos Stavrakakis
        network = ip.network
311 fde2c1f7 Christos Stavrakakis
        network.public = False
312 fde2c1f7 Christos Stavrakakis
        network.save()
313 e57893cd Christos Stavrakakis
        # Can not remove network with floating IPs
314 e57893cd Christos Stavrakakis
        with mocked_quotaholder():
315 fde2c1f7 Christos Stavrakakis
            response = self.delete(NETWORKS_URL + "/%s" % self.pool.id,
316 fde2c1f7 Christos Stavrakakis
                                   self.pool.userid)
317 fde2c1f7 Christos Stavrakakis
        self.assertConflict(response)
318 e57893cd Christos Stavrakakis
        # But we can with only deleted Floating Ips
319 e57893cd Christos Stavrakakis
        ip.deleted = True
320 e57893cd Christos Stavrakakis
        ip.save()
321 e57893cd Christos Stavrakakis
        with mocked_quotaholder():
322 fde2c1f7 Christos Stavrakakis
            response = self.delete(NETWORKS_URL + "/%s" % self.pool.id,
323 fde2c1f7 Christos Stavrakakis
                                   self.pool.userid)
324 e57893cd Christos Stavrakakis
        self.assertSuccess(response)
325 e57893cd Christos Stavrakakis
326 b9364b15 Marios Kogias
'''
327 2cd55da6 Christos Stavrakakis
POOLS_URL = join_urls(compute_path, "os-floating-ip-pools")
328 7d368e73 Christos Stavrakakis

329 7d368e73 Christos Stavrakakis

330 92d2d1ce Christos Stavrakakis
class FloatingIPPoolsAPITest(BaseAPITest):
331 7d368e73 Christos Stavrakakis
    def test_no_pool(self):
332 7d368e73 Christos Stavrakakis
        response = self.get(POOLS_URL)
333 7d368e73 Christos Stavrakakis
        self.assertSuccess(response)
334 7d368e73 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip_pools"], [])
335 7d368e73 Christos Stavrakakis

336 7d368e73 Christos Stavrakakis
    def test_list_pools(self):
337 fde2c1f7 Christos Stavrakakis
        net = mf.NetworkWithSubnetFactory(floating_ip_pool=True,
338 fde2c1f7 Christos Stavrakakis
                                          public=True,
339 fde2c1f7 Christos Stavrakakis
                                          subnet__cidr="192.168.2.0/30",
340 0711e5aa Christos Stavrakakis
                                          subnet__gateway="192.168.2.1",
341 0711e5aa Christos Stavrakakis
                                          subnet__pool__size=1,
342 0711e5aa Christos Stavrakakis
                                          subnet__pool__offset=1)
343 fde2c1f7 Christos Stavrakakis
        mf.NetworkWithSubnetFactory(public=True, deleted=True)
344 fde2c1f7 Christos Stavrakakis
        mf.NetworkWithSubnetFactory(public=False, deleted=False)
345 fde2c1f7 Christos Stavrakakis
        mf.NetworkWithSubnetFactory(public=True, floating_ip_pool=False)
346 7d368e73 Christos Stavrakakis
        response = self.get(POOLS_URL)
347 7d368e73 Christos Stavrakakis
        self.assertSuccess(response)
348 7d368e73 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip_pools"],
349 0711e5aa Christos Stavrakakis
                         [{"name": str(net.id), "size": 1, "free": 1}])
350 a95c82a9 Christos Stavrakakis

351 a95c82a9 Christos Stavrakakis

352 92d2d1ce Christos Stavrakakis
class FloatingIPActionsTest(BaseAPITest):
353 a95c82a9 Christos Stavrakakis
    def setUp(self):
354 fde2c1f7 Christos Stavrakakis
        self.vm = VirtualMachineFactory()
355 fde2c1f7 Christos Stavrakakis
        self.vm.operstate = "ACTIVE"
356 fde2c1f7 Christos Stavrakakis
        self.vm.save()
357 a95c82a9 Christos Stavrakakis

358 a95c82a9 Christos Stavrakakis
    def test_bad_request(self):
359 2cd55da6 Christos Stavrakakis
        url = SERVERS_URL + "/%s/action" % self.vm.id
360 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps({}), "json")
361 a95c82a9 Christos Stavrakakis
        self.assertBadRequest(response)
362 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid,
363 a95c82a9 Christos Stavrakakis
                             json.dumps({"addFloatingIp": {}}),
364 a95c82a9 Christos Stavrakakis
                             "json")
365 a95c82a9 Christos Stavrakakis
        self.assertBadRequest(response)
366 a95c82a9 Christos Stavrakakis

367 a95c82a9 Christos Stavrakakis
    @patch('synnefo.logic.rapi_pool.GanetiRapiClient')
368 a95c82a9 Christos Stavrakakis
    def test_add_floating_ip(self, mock):
369 a95c82a9 Christos Stavrakakis
        # Not exists
370 2cd55da6 Christos Stavrakakis
        url = SERVERS_URL + "/%s/action" % self.vm.id
371 a95c82a9 Christos Stavrakakis
        request = {"addFloatingIp": {"address": "10.0.0.1"}}
372 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
373 a95c82a9 Christos Stavrakakis
        self.assertItemNotFound(response)
374 a95c82a9 Christos Stavrakakis
        # In use
375 fde2c1f7 Christos Stavrakakis
        ip = mf.IPv4AddressFactory(floating_ip=True, userid=self.vm.userid)
376 fde2c1f7 Christos Stavrakakis
        request = {"addFloatingIp": {"address": ip.address}}
377 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
378 fde2c1f7 Christos Stavrakakis
        self.assertConflict(response)
379 a95c82a9 Christos Stavrakakis
        # Success
380 fde2c1f7 Christos Stavrakakis
        ip = mf.IPv4AddressFactory(floating_ip=True, nic=None,
381 fde2c1f7 Christos Stavrakakis
                                   userid=self.vm.userid)
382 fde2c1f7 Christos Stavrakakis
        request = {"addFloatingIp": {"address": ip.address}}
383 f8675683 Christos Stavrakakis
        mock().ModifyInstance.return_value = 1
384 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
385 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
386 fde2c1f7 Christos Stavrakakis
        ip_after = floating_ips.get(id=ip.id)
387 fde2c1f7 Christos Stavrakakis
        self.assertEqual(ip_after.nic.machine, self.vm)
388 fde2c1f7 Christos Stavrakakis
        nic = self.vm.nics.get()
389 c4ed6248 Christos Stavrakakis
        nic.state = "ACTIVE"
390 c4ed6248 Christos Stavrakakis
        nic.save()
391 78c165cf Christos Stavrakakis
        response = self.get(SERVERS_URL + "/%s" % self.vm.id,
392 78c165cf Christos Stavrakakis
                            self.vm.userid)
393 78c165cf Christos Stavrakakis
        self.assertSuccess(response)
394 78c165cf Christos Stavrakakis
        nic = json.loads(response.content)["server"]["attachments"][0]
395 78c165cf Christos Stavrakakis
        self.assertEqual(nic["OS-EXT-IPS:type"], "floating")
396 a95c82a9 Christos Stavrakakis

397 a95c82a9 Christos Stavrakakis
    @patch('synnefo.logic.rapi_pool.GanetiRapiClient')
398 a95c82a9 Christos Stavrakakis
    def test_remove_floating_ip(self, mock):
399 a95c82a9 Christos Stavrakakis
        # Not exists
400 2cd55da6 Christos Stavrakakis
        url = SERVERS_URL + "/%s/action" % self.vm.id
401 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": "10.0.0.1"}}
402 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
403 fde2c1f7 Christos Stavrakakis
        self.assertBadRequest(response)
404 a95c82a9 Christos Stavrakakis
        # Not In Use
405 fde2c1f7 Christos Stavrakakis
        ip = mf.IPv4AddressFactory(floating_ip=True, nic=None,
406 fde2c1f7 Christos Stavrakakis
                                   userid=self.vm.userid)
407 fde2c1f7 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": ip.address}}
408 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
409 fde2c1f7 Christos Stavrakakis
        self.assertBadRequest(response)
410 a95c82a9 Christos Stavrakakis
        # Success
411 fde2c1f7 Christos Stavrakakis
        ip = mf.IPv4AddressFactory(floating_ip=True,
412 fde2c1f7 Christos Stavrakakis
                                   userid=self.vm.userid, nic__machine=self.vm)
413 fde2c1f7 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": ip.address}}
414 f8675683 Christos Stavrakakis
        mock().ModifyInstance.return_value = 2
415 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
416 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
417 a95c82a9 Christos Stavrakakis
        # Yet used. Wait for the callbacks
418 fde2c1f7 Christos Stavrakakis
        ip_after = floating_ips.get(id=ip.id)
419 fde2c1f7 Christos Stavrakakis
        self.assertEqual(ip_after.nic.machine, self.vm)
420 e4f484da Marios Kogias
'''