Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (14.8 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 acda838e Christos Stavrakakis
import json
35 acda838e Christos Stavrakakis
36 acda838e Christos Stavrakakis
from snf_django.utils.testing import BaseAPITest, mocked_quotaholder
37 acda838e Christos Stavrakakis
from synnefo.db.models import FloatingIP
38 a95c82a9 Christos Stavrakakis
from synnefo.db.models_factory import (FloatingIPFactory, NetworkFactory,
39 a95c82a9 Christos Stavrakakis
                                       VirtualMachineFactory,
40 9e8be4fb Christos Stavrakakis
                                       NetworkInterfaceFactory,
41 9e8be4fb Christos Stavrakakis
                                       BackendNetworkFactory)
42 e57893cd Christos Stavrakakis
from mock import patch, Mock
43 9115d567 Christos Stavrakakis
from functools import partial
44 acda838e Christos Stavrakakis
45 2cd55da6 Christos Stavrakakis
from synnefo.cyclades_settings import cyclades_services
46 2cd55da6 Christos Stavrakakis
from synnefo.lib.services import get_service_path
47 2cd55da6 Christos Stavrakakis
from synnefo.lib import join_urls
48 acda838e Christos Stavrakakis
49 2cd55da6 Christos Stavrakakis
50 2cd55da6 Christos Stavrakakis
compute_path = get_service_path(cyclades_services, "compute", version="v2.0")
51 2cd55da6 Christos Stavrakakis
URL = join_urls(compute_path, "os-floating-ips")
52 2cd55da6 Christos Stavrakakis
NETWORKS_URL = join_urls(compute_path, "networks")
53 2cd55da6 Christos Stavrakakis
SERVERS_URL = join_urls(compute_path, "servers")
54 acda838e Christos Stavrakakis
55 9115d567 Christos Stavrakakis
FloatingIPPoolFactory = partial(NetworkFactory, public=True, deleted=False,
56 9115d567 Christos Stavrakakis
                                floating_ip_pool=True)
57 9115d567 Christos Stavrakakis
58 acda838e Christos Stavrakakis
59 acda838e Christos Stavrakakis
class FloatingIPAPITest(BaseAPITest):
60 acda838e Christos Stavrakakis
    def test_no_floating_ip(self):
61 acda838e Christos Stavrakakis
        response = self.get(URL)
62 acda838e Christos Stavrakakis
        self.assertSuccess(response)
63 acda838e Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ips"], [])
64 acda838e Christos Stavrakakis
65 acda838e Christos Stavrakakis
    def test_list_ips(self):
66 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1")
67 acda838e Christos Stavrakakis
        FloatingIPFactory(userid="user1", deleted=True)
68 acda838e Christos Stavrakakis
        with mocked_quotaholder():
69 acda838e Christos Stavrakakis
            response = self.get(URL, "user1")
70 acda838e Christos Stavrakakis
        self.assertSuccess(response)
71 acda838e Christos Stavrakakis
        api_ip = json.loads(response.content)["floating_ips"][0]
72 acda838e Christos Stavrakakis
        self.assertEqual(api_ip,
73 acda838e Christos Stavrakakis
                         {"instance_id": str(ip.machine.id), "ip": ip.ipv4,
74 acda838e Christos Stavrakakis
                          "fixed_ip": None, "id": str(ip.id),  "pool":
75 acda838e Christos Stavrakakis
                          str(ip.network.id)})
76 acda838e Christos Stavrakakis
77 acda838e Christos Stavrakakis
    def test_get_ip(self):
78 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1")
79 acda838e Christos Stavrakakis
        with mocked_quotaholder():
80 acda838e Christos Stavrakakis
            response = self.get(URL + "/%s" % ip.id, "user1")
81 acda838e Christos Stavrakakis
        self.assertSuccess(response)
82 acda838e Christos Stavrakakis
        api_ip = json.loads(response.content)["floating_ip"]
83 acda838e Christos Stavrakakis
        self.assertEqual(api_ip,
84 acda838e Christos Stavrakakis
                         {"instance_id": str(ip.machine.id), "ip": ip.ipv4,
85 acda838e Christos Stavrakakis
                          "fixed_ip": None, "id": str(ip.id),  "pool":
86 acda838e Christos Stavrakakis
                          str(ip.network.id)})
87 acda838e Christos Stavrakakis
88 acda838e Christos Stavrakakis
    def test_wrong_user(self):
89 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1")
90 acda838e Christos Stavrakakis
        with mocked_quotaholder():
91 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, "user2")
92 acda838e Christos Stavrakakis
        self.assertItemNotFound(response)
93 acda838e Christos Stavrakakis
94 acda838e Christos Stavrakakis
    def test_deleted_ip(self):
95 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1", deleted=True)
96 acda838e Christos Stavrakakis
        with mocked_quotaholder():
97 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, "user1")
98 acda838e Christos Stavrakakis
        self.assertItemNotFound(response)
99 acda838e Christos Stavrakakis
100 acda838e Christos Stavrakakis
    def test_reserve(self):
101 9115d567 Christos Stavrakakis
        net = FloatingIPPoolFactory(userid="test_user",
102 9115d567 Christos Stavrakakis
                                    subnet="192.168.2.0/24",
103 9115d567 Christos Stavrakakis
                                    gateway=None)
104 acda838e Christos Stavrakakis
        request = {'pool': net.id}
105 acda838e Christos Stavrakakis
        with mocked_quotaholder():
106 acda838e Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
107 acda838e Christos Stavrakakis
        self.assertSuccess(response)
108 acda838e Christos Stavrakakis
        ip = FloatingIP.objects.get()
109 acda838e Christos Stavrakakis
        self.assertEqual(ip.ipv4, "192.168.2.1")
110 acda838e Christos Stavrakakis
        self.assertEqual(ip.machine, None)
111 acda838e Christos Stavrakakis
        self.assertEqual(ip.network, net)
112 acda838e Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip"],
113 acda838e Christos Stavrakakis
                         {"instance_id": None, "ip": "192.168.2.1",
114 9582e68e Christos Stavrakakis
                          "fixed_ip": None, "id": str(ip.id),
115 9582e68e Christos Stavrakakis
                          "pool": str(net.id)})
116 acda838e Christos Stavrakakis
117 9e8be4fb Christos Stavrakakis
    def test_reserve_no_pool(self):
118 9e8be4fb Christos Stavrakakis
        # No networks
119 9e8be4fb Christos Stavrakakis
        with mocked_quotaholder():
120 9e8be4fb Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps({}), "json")
121 9e8be4fb Christos Stavrakakis
        self.assertFault(response, 413, "overLimit")
122 9e8be4fb Christos Stavrakakis
        # Full network
123 9115d567 Christos Stavrakakis
        FloatingIPPoolFactory(userid="test_user",
124 9115d567 Christos Stavrakakis
                              subnet="192.168.2.0/32",
125 9115d567 Christos Stavrakakis
                              gateway=None)
126 9e8be4fb Christos Stavrakakis
        with mocked_quotaholder():
127 9e8be4fb Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps({}), "json")
128 9e8be4fb Christos Stavrakakis
        self.assertFault(response, 413, "overLimit")
129 9e8be4fb Christos Stavrakakis
        # Success
130 9115d567 Christos Stavrakakis
        net2 = FloatingIPPoolFactory(userid="test_user",
131 9115d567 Christos Stavrakakis
                                     subnet="192.168.2.0/24",
132 9115d567 Christos Stavrakakis
                                     gateway=None)
133 9e8be4fb Christos Stavrakakis
        with mocked_quotaholder():
134 9e8be4fb Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps({}), "json")
135 9115d567 Christos Stavrakakis
        self.assertSuccess(response)
136 9582e68e Christos Stavrakakis
        ip = FloatingIP.objects.get()
137 9e8be4fb Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip"],
138 9e8be4fb Christos Stavrakakis
                         {"instance_id": None, "ip": "192.168.2.1",
139 9582e68e Christos Stavrakakis
                          "fixed_ip": None, "id": str(ip.id),
140 9582e68e Christos Stavrakakis
                          "pool": str(net2.id)})
141 9e8be4fb Christos Stavrakakis
142 acda838e Christos Stavrakakis
    def test_reserve_full(self):
143 9115d567 Christos Stavrakakis
        net = FloatingIPPoolFactory(userid="test_user",
144 9115d567 Christos Stavrakakis
                                    subnet="192.168.2.0/32")
145 acda838e Christos Stavrakakis
        request = {'pool': net.id}
146 acda838e Christos Stavrakakis
        with mocked_quotaholder():
147 acda838e Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
148 acda838e Christos Stavrakakis
        self.assertEqual(response.status_code, 413)
149 acda838e Christos Stavrakakis
150 a3d99af0 Christos Stavrakakis
    def test_reserve_with_address(self):
151 9115d567 Christos Stavrakakis
        net = FloatingIPPoolFactory(userid="test_user",
152 9115d567 Christos Stavrakakis
                                    subnet="192.168.2.0/24")
153 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.10"}
154 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
155 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
156 a3d99af0 Christos Stavrakakis
        self.assertSuccess(response)
157 9582e68e Christos Stavrakakis
        ip = FloatingIP.objects.get()
158 a3d99af0 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip"],
159 a3d99af0 Christos Stavrakakis
                         {"instance_id": None, "ip": "192.168.2.10",
160 9582e68e Christos Stavrakakis
                          "fixed_ip": None, "id": str(ip.id), "pool":
161 9582e68e Christos Stavrakakis
                          str(net.id)})
162 a3d99af0 Christos Stavrakakis
163 a3d99af0 Christos Stavrakakis
        # Already reserved
164 a3d99af0 Christos Stavrakakis
        FloatingIPFactory(network=net, ipv4="192.168.2.3")
165 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.3"}
166 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
167 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
168 a3d99af0 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
169 a3d99af0 Christos Stavrakakis
170 a3d99af0 Christos Stavrakakis
        # Already used
171 a3d99af0 Christos Stavrakakis
        pool = net.get_pool()
172 a3d99af0 Christos Stavrakakis
        pool.reserve("192.168.2.5")
173 a3d99af0 Christos Stavrakakis
        pool.save()
174 a3d99af0 Christos Stavrakakis
        # ..by another_user
175 a3d99af0 Christos Stavrakakis
        nic = NetworkInterfaceFactory(network=net, ipv4="192.168.2.5",
176 a3d99af0 Christos Stavrakakis
                                      machine__userid="test2")
177 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.5"}
178 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
179 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
180 a3d99af0 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
181 a3d99af0 Christos Stavrakakis
        # ..and by him
182 a3d99af0 Christos Stavrakakis
        nic.delete()
183 a3d99af0 Christos Stavrakakis
        NetworkInterfaceFactory(network=net, ipv4="192.168.2.5",
184 a3d99af0 Christos Stavrakakis
                                machine__userid="test_user")
185 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.5"}
186 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
187 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
188 a3d99af0 Christos Stavrakakis
        self.assertSuccess(response)
189 a3d99af0 Christos Stavrakakis
190 a3d99af0 Christos Stavrakakis
        # Address out of pool
191 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.3.5"}
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 acda838e Christos Stavrakakis
    def test_release_in_use(self):
197 acda838e Christos Stavrakakis
        ip = FloatingIPFactory()
198 a95c82a9 Christos Stavrakakis
        vm = ip.machine
199 a95c82a9 Christos Stavrakakis
        vm.operstate = "ACTIVE"
200 a95c82a9 Christos Stavrakakis
        vm.userid = ip.userid
201 a95c82a9 Christos Stavrakakis
        vm.save()
202 a95c82a9 Christos Stavrakakis
        vm.nics.create(index=0, ipv4=ip.ipv4, network=ip.network,
203 a95c82a9 Christos Stavrakakis
                       state="ACTIVE")
204 a95c82a9 Christos Stavrakakis
        with mocked_quotaholder():
205 a95c82a9 Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, ip.userid)
206 a95c82a9 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
207 a95c82a9 Christos Stavrakakis
        # Also send a notification to remove the NIC and assert that FIP is in
208 a95c82a9 Christos Stavrakakis
        # use until notification from ganeti arrives
209 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": ip.ipv4}}
210 2cd55da6 Christos Stavrakakis
        url = SERVERS_URL + "/%s/action" % vm.id
211 a95c82a9 Christos Stavrakakis
        with patch('synnefo.logic.rapi_pool.GanetiRapiClient') as c:
212 a95c82a9 Christos Stavrakakis
            c().ModifyInstance.return_value = 10
213 a95c82a9 Christos Stavrakakis
            response = self.post(url, vm.userid, json.dumps(request),
214 a95c82a9 Christos Stavrakakis
                                 "json")
215 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
216 acda838e Christos Stavrakakis
        with mocked_quotaholder():
217 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, ip.userid)
218 acda838e Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
219 acda838e Christos Stavrakakis
220 acda838e Christos Stavrakakis
    def test_release(self):
221 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(machine=None)
222 acda838e Christos Stavrakakis
        with mocked_quotaholder():
223 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, ip.userid)
224 acda838e Christos Stavrakakis
        self.assertSuccess(response)
225 acda838e Christos Stavrakakis
        ips_after = FloatingIP.objects.filter(id=ip.id)
226 acda838e Christos Stavrakakis
        self.assertEqual(len(ips_after), 0)
227 7d368e73 Christos Stavrakakis
228 e57893cd Christos Stavrakakis
    @patch("synnefo.logic.backend", Mock())
229 e57893cd Christos Stavrakakis
    def test_delete_network_with_floating_ips(self):
230 9e8be4fb Christos Stavrakakis
        ip = FloatingIPFactory(machine=None, network__flavor="IP_LESS_ROUTED")
231 e57893cd Christos Stavrakakis
        net = ip.network
232 e57893cd Christos Stavrakakis
        # Can not remove network with floating IPs
233 e57893cd Christos Stavrakakis
        with mocked_quotaholder():
234 2cd55da6 Christos Stavrakakis
            response = self.delete(NETWORKS_URL + "/%s" % net.id,
235 e57893cd Christos Stavrakakis
                                   net.userid)
236 e57893cd Christos Stavrakakis
        self.assertFault(response, 421, "networkInUse")
237 e57893cd Christos Stavrakakis
        # But we can with only deleted Floating Ips
238 e57893cd Christos Stavrakakis
        ip.deleted = True
239 e57893cd Christos Stavrakakis
        ip.save()
240 e57893cd Christos Stavrakakis
        with mocked_quotaholder():
241 2cd55da6 Christos Stavrakakis
            response = self.delete(NETWORKS_URL + "/%s" % net.id,
242 e57893cd Christos Stavrakakis
                                   net.userid)
243 e57893cd Christos Stavrakakis
        self.assertSuccess(response)
244 e57893cd Christos Stavrakakis
245 7d368e73 Christos Stavrakakis
246 2cd55da6 Christos Stavrakakis
POOLS_URL = join_urls(compute_path, "os-floating-ip-pools")
247 7d368e73 Christos Stavrakakis
248 7d368e73 Christos Stavrakakis
249 7d368e73 Christos Stavrakakis
class FloatingIPPoolsAPITest(BaseAPITest):
250 7d368e73 Christos Stavrakakis
    def test_no_pool(self):
251 7d368e73 Christos Stavrakakis
        response = self.get(POOLS_URL)
252 7d368e73 Christos Stavrakakis
        self.assertSuccess(response)
253 7d368e73 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip_pools"], [])
254 7d368e73 Christos Stavrakakis
255 7d368e73 Christos Stavrakakis
    def test_list_pools(self):
256 0ace35e4 Christos Stavrakakis
        net = FloatingIPPoolFactory(subnet="192.168.0.0/30",
257 0ace35e4 Christos Stavrakakis
                                    gateway="192.168.0.1")
258 7d368e73 Christos Stavrakakis
        NetworkFactory(public=True, deleted=True)
259 7d368e73 Christos Stavrakakis
        NetworkFactory(public=False, deleted=False)
260 9115d567 Christos Stavrakakis
        NetworkFactory(public=True, deleted=False)
261 7d368e73 Christos Stavrakakis
        response = self.get(POOLS_URL)
262 7d368e73 Christos Stavrakakis
        self.assertSuccess(response)
263 7d368e73 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip_pools"],
264 0ace35e4 Christos Stavrakakis
                         [{"name": str(net.id), "size": 4, "free": 1}])
265 a95c82a9 Christos Stavrakakis
266 a95c82a9 Christos Stavrakakis
267 a95c82a9 Christos Stavrakakis
class FloatingIPActionsTest(BaseAPITest):
268 a95c82a9 Christos Stavrakakis
    def setUp(self):
269 a95c82a9 Christos Stavrakakis
        vm = VirtualMachineFactory()
270 a95c82a9 Christos Stavrakakis
        vm.operstate = "ACTIVE"
271 a95c82a9 Christos Stavrakakis
        vm.save()
272 a95c82a9 Christos Stavrakakis
        self.vm = vm
273 a95c82a9 Christos Stavrakakis
274 a95c82a9 Christos Stavrakakis
    def test_bad_request(self):
275 2cd55da6 Christos Stavrakakis
        url = SERVERS_URL + "/%s/action" % self.vm.id
276 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps({}), "json")
277 a95c82a9 Christos Stavrakakis
        self.assertBadRequest(response)
278 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid,
279 a95c82a9 Christos Stavrakakis
                             json.dumps({"addFloatingIp": {}}),
280 a95c82a9 Christos Stavrakakis
                             "json")
281 a95c82a9 Christos Stavrakakis
        self.assertBadRequest(response)
282 a95c82a9 Christos Stavrakakis
283 a95c82a9 Christos Stavrakakis
    @patch('synnefo.logic.rapi_pool.GanetiRapiClient')
284 a95c82a9 Christos Stavrakakis
    def test_add_floating_ip(self, mock):
285 a95c82a9 Christos Stavrakakis
        # Not exists
286 2cd55da6 Christos Stavrakakis
        url = SERVERS_URL + "/%s/action" % self.vm.id
287 a95c82a9 Christos Stavrakakis
        request = {"addFloatingIp": {"address": "10.0.0.1"}}
288 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
289 a95c82a9 Christos Stavrakakis
        self.assertItemNotFound(response)
290 a95c82a9 Christos Stavrakakis
        # In use
291 a95c82a9 Christos Stavrakakis
        vm1 = VirtualMachineFactory()
292 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=vm1)
293 9e8be4fb Christos Stavrakakis
        BackendNetworkFactory(network=ip1.network, backend=vm1.backend,
294 9e8be4fb Christos Stavrakakis
                              operstate='ACTIVE')
295 a95c82a9 Christos Stavrakakis
        request = {"addFloatingIp": {"address": ip1.ipv4}}
296 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
297 a95c82a9 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
298 a95c82a9 Christos Stavrakakis
        # Success
299 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=None)
300 9e8be4fb Christos Stavrakakis
        BackendNetworkFactory(network=ip1.network, backend=self.vm.backend,
301 9e8be4fb Christos Stavrakakis
                              operstate='ACTIVE')
302 a95c82a9 Christos Stavrakakis
        request = {"addFloatingIp": {"address": ip1.ipv4}}
303 f8675683 Christos Stavrakakis
        mock().ModifyInstance.return_value = 1
304 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
305 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
306 a95c82a9 Christos Stavrakakis
        ip1_after = FloatingIP.objects.get(id=ip1.id)
307 a95c82a9 Christos Stavrakakis
        self.assertEqual(ip1_after.machine, self.vm)
308 a95c82a9 Christos Stavrakakis
        self.assertTrue(ip1_after.in_use())
309 c4ed6248 Christos Stavrakakis
        nic = self.vm.nics.get(ipv4=ip1_after.ipv4)
310 c4ed6248 Christos Stavrakakis
        nic.state = "ACTIVE"
311 c4ed6248 Christos Stavrakakis
        nic.save()
312 78c165cf Christos Stavrakakis
        response = self.get(SERVERS_URL + "/%s" % self.vm.id,
313 78c165cf Christos Stavrakakis
                            self.vm.userid)
314 78c165cf Christos Stavrakakis
        self.assertSuccess(response)
315 78c165cf Christos Stavrakakis
        nic = json.loads(response.content)["server"]["attachments"][0]
316 78c165cf Christos Stavrakakis
        self.assertEqual(nic["OS-EXT-IPS:type"], "floating")
317 a95c82a9 Christos Stavrakakis
318 a95c82a9 Christos Stavrakakis
    @patch('synnefo.logic.rapi_pool.GanetiRapiClient')
319 a95c82a9 Christos Stavrakakis
    def test_remove_floating_ip(self, mock):
320 a95c82a9 Christos Stavrakakis
        # Not exists
321 2cd55da6 Christos Stavrakakis
        url = SERVERS_URL + "/%s/action" % self.vm.id
322 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": "10.0.0.1"}}
323 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
324 a95c82a9 Christos Stavrakakis
        self.assertItemNotFound(response)
325 a95c82a9 Christos Stavrakakis
        # Not In Use
326 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=None)
327 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": ip1.ipv4}}
328 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
329 a95c82a9 Christos Stavrakakis
        self.assertItemNotFound(response)
330 a95c82a9 Christos Stavrakakis
        # Success
331 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=self.vm)
332 a95c82a9 Christos Stavrakakis
        NetworkInterfaceFactory(machine=self.vm, ipv4=ip1.ipv4)
333 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": ip1.ipv4}}
334 f8675683 Christos Stavrakakis
        mock().ModifyInstance.return_value = 2
335 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
336 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
337 a95c82a9 Christos Stavrakakis
        # Yet used. Wait for the callbacks
338 a95c82a9 Christos Stavrakakis
        ip1_after = FloatingIP.objects.get(id=ip1.id)
339 a95c82a9 Christos Stavrakakis
        self.assertEqual(ip1_after.machine, self.vm)
340 a95c82a9 Christos Stavrakakis
        self.assertTrue(ip1_after.in_use())