Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / tests / servers.py @ 92d2d1ce

History | View | Annotate | Download (35.8 kB)

1 039e3e61 Christos Stavrakakis
# Copyright 2012 GRNET S.A. All rights reserved.
2 039e3e61 Christos Stavrakakis
#
3 039e3e61 Christos Stavrakakis
# Redistribution and use in source and binary forms, with or
4 039e3e61 Christos Stavrakakis
# without modification, are permitted provided that the following
5 039e3e61 Christos Stavrakakis
# conditions are met:
6 039e3e61 Christos Stavrakakis
#
7 039e3e61 Christos Stavrakakis
#   1. Redistributions of source code must retain the above
8 039e3e61 Christos Stavrakakis
#      copyright notice, this list of conditions and the following
9 039e3e61 Christos Stavrakakis
#      disclaimer.
10 039e3e61 Christos Stavrakakis
#
11 039e3e61 Christos Stavrakakis
#   2. Redistributions in binary form must reproduce the above
12 039e3e61 Christos Stavrakakis
#      copyright notice, this list of conditions and the following
13 039e3e61 Christos Stavrakakis
#      disclaimer in the documentation and/or other materials
14 039e3e61 Christos Stavrakakis
#      provided with the distribution.
15 039e3e61 Christos Stavrakakis
#
16 039e3e61 Christos Stavrakakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 039e3e61 Christos Stavrakakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 039e3e61 Christos Stavrakakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 039e3e61 Christos Stavrakakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 039e3e61 Christos Stavrakakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 039e3e61 Christos Stavrakakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 039e3e61 Christos Stavrakakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 039e3e61 Christos Stavrakakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 039e3e61 Christos Stavrakakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 039e3e61 Christos Stavrakakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 039e3e61 Christos Stavrakakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 039e3e61 Christos Stavrakakis
# POSSIBILITY OF SUCH DAMAGE.
28 039e3e61 Christos Stavrakakis
#
29 039e3e61 Christos Stavrakakis
# The views and conclusions contained in the software and
30 039e3e61 Christos Stavrakakis
# documentation are those of the authors and should not be
31 039e3e61 Christos Stavrakakis
# interpreted as representing official policies, either expressed
32 039e3e61 Christos Stavrakakis
# or implied, of GRNET S.A.
33 039e3e61 Christos Stavrakakis
34 039e3e61 Christos Stavrakakis
import json
35 cb66110b Christos Stavrakakis
from copy import deepcopy
36 039e3e61 Christos Stavrakakis
37 41a7fae7 Christos Stavrakakis
from snf_django.utils.testing import (BaseAPITest, mocked_quotaholder,
38 41a7fae7 Christos Stavrakakis
                                      override_settings)
39 816d7588 Christos Stavrakakis
from synnefo.db.models import (VirtualMachine, VirtualMachineMetadata,
40 326c3ec8 Christos Stavrakakis
                               IPAddress)
41 039e3e61 Christos Stavrakakis
from synnefo.db import models_factory as mfactory
42 039e3e61 Christos Stavrakakis
from synnefo.logic.utils import get_rsapi_state
43 a26e5a4d Georgios D. Tsoukalas
from synnefo.cyclades_settings import cyclades_services
44 a26e5a4d Georgios D. Tsoukalas
from synnefo.lib.services import get_service_path
45 a26e5a4d Georgios D. Tsoukalas
from synnefo.lib import join_urls
46 7e82ac17 Christos Stavrakakis
from django.conf import settings
47 f2080d16 Christos Stavrakakis
from synnefo.logic.rapi import GanetiApiError
48 039e3e61 Christos Stavrakakis
49 816d7588 Christos Stavrakakis
from mock import patch, Mock
50 039e3e61 Christos Stavrakakis
51 039e3e61 Christos Stavrakakis
52 a26e5a4d Georgios D. Tsoukalas
class ComputeAPITest(BaseAPITest):
53 2cd55da6 Christos Stavrakakis
    def __init__(self, *args, **kwargs):
54 2cd55da6 Christos Stavrakakis
        super(ComputeAPITest, self).__init__(*args, **kwargs)
55 a26e5a4d Georgios D. Tsoukalas
        self.compute_path = get_service_path(cyclades_services, 'compute',
56 a26e5a4d Georgios D. Tsoukalas
                                             version='v2.0')
57 41a7fae7 Christos Stavrakakis
58 a26e5a4d Georgios D. Tsoukalas
    def myget(self, path, *args, **kwargs):
59 a26e5a4d Georgios D. Tsoukalas
        path = join_urls(self.compute_path, path)
60 a26e5a4d Georgios D. Tsoukalas
        return self.get(path, *args, **kwargs)
61 a26e5a4d Georgios D. Tsoukalas
62 a26e5a4d Georgios D. Tsoukalas
    def myput(self, path, *args, **kwargs):
63 a26e5a4d Georgios D. Tsoukalas
        path = join_urls(self.compute_path, path)
64 a26e5a4d Georgios D. Tsoukalas
        return self.put(path, *args, **kwargs)
65 a26e5a4d Georgios D. Tsoukalas
66 a26e5a4d Georgios D. Tsoukalas
    def mypost(self, path, *args, **kwargs):
67 a26e5a4d Georgios D. Tsoukalas
        path = join_urls(self.compute_path, path)
68 a26e5a4d Georgios D. Tsoukalas
        return self.post(path, *args, **kwargs)
69 a26e5a4d Georgios D. Tsoukalas
70 a26e5a4d Georgios D. Tsoukalas
    def mydelete(self, path, *args, **kwargs):
71 a26e5a4d Georgios D. Tsoukalas
        path = join_urls(self.compute_path, path)
72 a26e5a4d Georgios D. Tsoukalas
        return self.delete(path, *args, **kwargs)
73 a26e5a4d Georgios D. Tsoukalas
74 a26e5a4d Georgios D. Tsoukalas
75 a26e5a4d Georgios D. Tsoukalas
class ServerAPITest(ComputeAPITest):
76 039e3e61 Christos Stavrakakis
    def setUp(self):
77 039e3e61 Christos Stavrakakis
        self.user1 = 'user1'
78 039e3e61 Christos Stavrakakis
        self.user2 = 'user2'
79 039e3e61 Christos Stavrakakis
        self.vm1 = mfactory.VirtualMachineFactory(userid=self.user1)
80 039e3e61 Christos Stavrakakis
        self.vm2 = mfactory.VirtualMachineFactory(userid=self.user2)
81 039e3e61 Christos Stavrakakis
        self.vm3 = mfactory.VirtualMachineFactory(deleted=True,
82 039e3e61 Christos Stavrakakis
                                                  userid=self.user1)
83 039e3e61 Christos Stavrakakis
        self.vm4 = mfactory.VirtualMachineFactory(userid=self.user2)
84 039e3e61 Christos Stavrakakis
85 039e3e61 Christos Stavrakakis
    def test_server_list_1(self):
86 039e3e61 Christos Stavrakakis
        """Test if the expected list of servers is returned."""
87 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers')
88 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
89 2d04422f Christos Stavrakakis
        servers = json.loads(response.content)['servers']
90 039e3e61 Christos Stavrakakis
        self.assertEqual(servers, [])
91 039e3e61 Christos Stavrakakis
92 039e3e61 Christos Stavrakakis
    def test_server_list_2(self):
93 039e3e61 Christos Stavrakakis
        """Test if the expected list of servers is returned."""
94 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers', self.user1)
95 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
96 2d04422f Christos Stavrakakis
        servers = json.loads(response.content)['servers']
97 039e3e61 Christos Stavrakakis
        db_server = self.vm1
98 1b696c26 Christos Stavrakakis
        server = servers[0]
99 1b696c26 Christos Stavrakakis
        self.assertEqual(server["name"], db_server.name)
100 1b696c26 Christos Stavrakakis
        self.assertEqual(server["id"], db_server.id)
101 039e3e61 Christos Stavrakakis
102 039e3e61 Christos Stavrakakis
    def test_server_list_detail(self):
103 039e3e61 Christos Stavrakakis
        """Test if the servers list details are returned."""
104 039e3e61 Christos Stavrakakis
        user = self.user2
105 039e3e61 Christos Stavrakakis
        user_vms = {self.vm2.id: self.vm2,
106 039e3e61 Christos Stavrakakis
                    self.vm4.id: self.vm4}
107 039e3e61 Christos Stavrakakis
108 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/detail', user)
109 2d04422f Christos Stavrakakis
        servers = json.loads(response.content)['servers']
110 039e3e61 Christos Stavrakakis
        self.assertEqual(len(servers), len(user_vms))
111 039e3e61 Christos Stavrakakis
        for api_vm in servers:
112 039e3e61 Christos Stavrakakis
            db_vm = user_vms[api_vm['id']]
113 1b696c26 Christos Stavrakakis
            self.assertEqual(api_vm['flavor']["id"], db_vm.flavor.id)
114 039e3e61 Christos Stavrakakis
            self.assertEqual(api_vm['hostId'], db_vm.hostid)
115 039e3e61 Christos Stavrakakis
            self.assertEqual(api_vm['id'], db_vm.id)
116 1b696c26 Christos Stavrakakis
            self.assertEqual(api_vm['image']["id"], db_vm.imageid)
117 039e3e61 Christos Stavrakakis
            self.assertEqual(api_vm['name'], db_vm.name)
118 039e3e61 Christos Stavrakakis
            self.assertEqual(api_vm['status'], get_rsapi_state(db_vm))
119 039e3e61 Christos Stavrakakis
            self.assertSuccess(response)
120 039e3e61 Christos Stavrakakis
121 039e3e61 Christos Stavrakakis
    def test_server_detail(self):
122 039e3e61 Christos Stavrakakis
        """Test if a server details are returned."""
123 039e3e61 Christos Stavrakakis
        db_vm = self.vm2
124 039e3e61 Christos Stavrakakis
        user = self.vm2.userid
125 92d2d1ce Christos Stavrakakis
        ip4 = mfactory.IPv4AddressFactory(nic__machine=self.vm2)
126 92d2d1ce Christos Stavrakakis
        nic = ip4.nic
127 92d2d1ce Christos Stavrakakis
        net = ip4.network
128 92d2d1ce Christos Stavrakakis
        ip6 = mfactory.IPv6AddressFactory(nic=nic, network=net)
129 92d2d1ce Christos Stavrakakis
        nic.mac = "aa:00:11:22:33:44"
130 92d2d1ce Christos Stavrakakis
        nic.save()
131 039e3e61 Christos Stavrakakis
132 039e3e61 Christos Stavrakakis
        db_vm_meta = mfactory.VirtualMachineMetadataFactory(vm=db_vm)
133 039e3e61 Christos Stavrakakis
134 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d' % db_vm.id, user)
135 039e3e61 Christos Stavrakakis
        server = json.loads(response.content)['server']
136 039e3e61 Christos Stavrakakis
137 1b696c26 Christos Stavrakakis
        self.assertEqual(server['flavor']["id"], db_vm.flavor.id)
138 039e3e61 Christos Stavrakakis
        self.assertEqual(server['hostId'], db_vm.hostid)
139 039e3e61 Christos Stavrakakis
        self.assertEqual(server['id'], db_vm.id)
140 1b696c26 Christos Stavrakakis
        self.assertEqual(server['image']["id"], db_vm.imageid)
141 039e3e61 Christos Stavrakakis
        self.assertEqual(server['name'], db_vm.name)
142 039e3e61 Christos Stavrakakis
        self.assertEqual(server['status'], get_rsapi_state(db_vm))
143 2d04422f Christos Stavrakakis
        api_nic = server['attachments'][0]
144 039e3e61 Christos Stavrakakis
        self.assertEqual(api_nic['network_id'], str(net.id))
145 039e3e61 Christos Stavrakakis
        self.assertEqual(api_nic['mac_address'], nic.mac)
146 039e3e61 Christos Stavrakakis
        self.assertEqual(api_nic['firewallProfile'], nic.firewall_profile)
147 92d2d1ce Christos Stavrakakis
        self.assertEqual(api_nic['ipv4'], ip4.address)
148 92d2d1ce Christos Stavrakakis
        self.assertEqual(api_nic['ipv6'], ip6.address)
149 e368ad39 Christos Stavrakakis
        self.assertEqual(api_nic['OS-EXT-IPS:type'], "fixed")
150 c988fcca Christos Stavrakakis
        self.assertEqual(api_nic['id'], nic.id)
151 1f638a85 Christos Stavrakakis
        api_address = server["addresses"]
152 e368ad39 Christos Stavrakakis
        self.assertEqual(api_address[str(net.id)], [
153 92d2d1ce Christos Stavrakakis
            {"version": 4, "addr": ip4.address, "OS-EXT-IPS:type": "fixed"},
154 92d2d1ce Christos Stavrakakis
            {"version": 6, "addr": ip6.address, "OS-EXT-IPS:type": "fixed"}
155 e368ad39 Christos Stavrakakis
        ])
156 039e3e61 Christos Stavrakakis
157 2d04422f Christos Stavrakakis
        metadata = server['metadata']
158 039e3e61 Christos Stavrakakis
        self.assertEqual(len(metadata), 1)
159 039e3e61 Christos Stavrakakis
        self.assertEqual(metadata[db_vm_meta.meta_key], db_vm_meta.meta_value)
160 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
161 039e3e61 Christos Stavrakakis
162 7e82ac17 Christos Stavrakakis
    def test_server_fqdn(self):
163 7e82ac17 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
164 7e82ac17 Christos Stavrakakis
        with override_settings(settings,
165 7e82ac17 Christos Stavrakakis
                               CYCLADES_SERVERS_FQDN="vm.example.org"):
166 7e82ac17 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
167 7e82ac17 Christos Stavrakakis
            server = json.loads(response.content)['server']
168 7e82ac17 Christos Stavrakakis
            self.assertEqual(server["SNF:fqdn"], "vm.example.org")
169 e368ad39 Christos Stavrakakis
        with override_settings(settings, CYCLADES_SERVERS_FQDN=
170 e368ad39 Christos Stavrakakis
                               "snf-%(id)s.vm.example.org"):
171 7e82ac17 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
172 7e82ac17 Christos Stavrakakis
            server = json.loads(response.content)['server']
173 e368ad39 Christos Stavrakakis
            self.assertEqual(server["SNF:fqdn"],
174 e368ad39 Christos Stavrakakis
                             "snf-%d.vm.example.org" % vm.id)
175 7e82ac17 Christos Stavrakakis
        with override_settings(settings,
176 e368ad39 Christos Stavrakakis
                               CYCLADES_SERVERS_FQDN=
177 e368ad39 Christos Stavrakakis
                               "snf-%(id)s.vm-%(id)s.example.org"):
178 7e82ac17 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
179 7e82ac17 Christos Stavrakakis
            server = json.loads(response.content)['server']
180 7e82ac17 Christos Stavrakakis
            self.assertEqual(server["SNF:fqdn"], "snf-%d.vm-%d.example.org" %
181 7e82ac17 Christos Stavrakakis
                             (vm.id, vm.id))
182 7e82ac17 Christos Stavrakakis
        # No setting, no NICs
183 7e82ac17 Christos Stavrakakis
        with override_settings(settings,
184 7e82ac17 Christos Stavrakakis
                               CYCLADES_SERVERS_FQDN=None):
185 7e82ac17 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
186 7e82ac17 Christos Stavrakakis
            server = json.loads(response.content)['server']
187 7e82ac17 Christos Stavrakakis
            self.assertEqual(server["SNF:fqdn"], "")
188 7e82ac17 Christos Stavrakakis
189 7e82ac17 Christos Stavrakakis
        # IPv6 NIC
190 92d2d1ce Christos Stavrakakis
        ipv6_address = mfactory.IPv6AddressFactory(nic__machine=vm,
191 92d2d1ce Christos Stavrakakis
                                                   network__public=True)
192 7e82ac17 Christos Stavrakakis
        with override_settings(settings,
193 7e82ac17 Christos Stavrakakis
                               CYCLADES_SERVERS_FQDN=None):
194 7e82ac17 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
195 7e82ac17 Christos Stavrakakis
            server = json.loads(response.content)['server']
196 92d2d1ce Christos Stavrakakis
            self.assertEqual(server["SNF:fqdn"], ipv6_address.address)
197 7e82ac17 Christos Stavrakakis
198 7e82ac17 Christos Stavrakakis
        # IPv4 NIC
199 92d2d1ce Christos Stavrakakis
        ipv4_address = mfactory.IPv4AddressFactory(nic__machine=vm,
200 92d2d1ce Christos Stavrakakis
                                                   network__public=True)
201 7e82ac17 Christos Stavrakakis
        with override_settings(settings,
202 7e82ac17 Christos Stavrakakis
                               CYCLADES_SERVERS_FQDN=None):
203 7e82ac17 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
204 7e82ac17 Christos Stavrakakis
            server = json.loads(response.content)['server']
205 92d2d1ce Christos Stavrakakis
            self.assertEqual(server["SNF:fqdn"], ipv4_address.address)
206 7e82ac17 Christos Stavrakakis
207 2522e489 Christos Stavrakakis
    def test_server_port_forwarding(self):
208 2522e489 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
209 2522e489 Christos Stavrakakis
        ports = {
210 2522e489 Christos Stavrakakis
            22: ("foo", 61000),
211 2522e489 Christos Stavrakakis
            80: lambda ip, id, fqdn, user: ("bar", 61001)}
212 2522e489 Christos Stavrakakis
        with override_settings(settings,
213 2522e489 Christos Stavrakakis
                               CYCLADES_PORT_FORWARDING=ports):
214 2522e489 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
215 2522e489 Christos Stavrakakis
            server = json.loads(response.content)['server']
216 2522e489 Christos Stavrakakis
            self.assertEqual(server["SNF:port_forwarding"],
217 2522e489 Christos Stavrakakis
                             {"22": {"host": "foo", "port": "61000"},
218 2522e489 Christos Stavrakakis
                              "80": {"host": "bar", "port": "61001"}})
219 2522e489 Christos Stavrakakis
220 2522e489 Christos Stavrakakis
        def _port_from_ip(ip, base):
221 2522e489 Christos Stavrakakis
            fields = ip.split('.', 4)
222 2522e489 Christos Stavrakakis
            return (base + 256*int(fields[2]) + int(fields[3]))
223 2522e489 Christos Stavrakakis
224 2522e489 Christos Stavrakakis
        ports = {
225 2522e489 Christos Stavrakakis
            22: lambda ip, id, fqdn, user:
226 2522e489 Christos Stavrakakis
            ip and ("gate", _port_from_ip(ip, 10000)) or None}
227 2522e489 Christos Stavrakakis
        with override_settings(settings,
228 2522e489 Christos Stavrakakis
                               CYCLADES_PORT_FORWARDING=ports):
229 2522e489 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
230 2522e489 Christos Stavrakakis
            server = json.loads(response.content)['server']
231 2522e489 Christos Stavrakakis
            self.assertEqual(server["SNF:port_forwarding"], {})
232 2522e489 Christos Stavrakakis
233 92d2d1ce Christos Stavrakakis
        mfactory.IPv4AddressFactory(nic__machine=vm,
234 92d2d1ce Christos Stavrakakis
                                    network__public=True,
235 92d2d1ce Christos Stavrakakis
                                    address="192.168.2.2")
236 2522e489 Christos Stavrakakis
        with override_settings(settings,
237 2522e489 Christos Stavrakakis
                               CYCLADES_PORT_FORWARDING=ports):
238 2522e489 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
239 2522e489 Christos Stavrakakis
            server = json.loads(response.content)['server']
240 2522e489 Christos Stavrakakis
            self.assertEqual(server["SNF:port_forwarding"],
241 2522e489 Christos Stavrakakis
                             {"22": {"host": "gate", "port": "10514"}})
242 2522e489 Christos Stavrakakis
243 939d71dd Christos Stavrakakis
    def test_server_building_nics(self):
244 939d71dd Christos Stavrakakis
        db_vm = self.vm2
245 939d71dd Christos Stavrakakis
        user = self.vm2.userid
246 939d71dd Christos Stavrakakis
        net1 = mfactory.NetworkFactory()
247 939d71dd Christos Stavrakakis
        net2 = mfactory.NetworkFactory()
248 939d71dd Christos Stavrakakis
        net3 = mfactory.NetworkFactory()
249 939d71dd Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net1,
250 939d71dd Christos Stavrakakis
                                         state="BUILDING")
251 939d71dd Christos Stavrakakis
        nic2 = mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net2,
252 939d71dd Christos Stavrakakis
                                                state="ACTIVE")
253 939d71dd Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net3,
254 939d71dd Christos Stavrakakis
                                         state="BUILDING")
255 939d71dd Christos Stavrakakis
256 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d' % db_vm.id, user)
257 939d71dd Christos Stavrakakis
        server = json.loads(response.content)['server']
258 2d04422f Christos Stavrakakis
        nics = server["attachments"]
259 939d71dd Christos Stavrakakis
        self.assertEqual(len(nics), 1)
260 939d71dd Christos Stavrakakis
        self.assertEqual(nics[0]["network_id"], str(nic2.network_id))
261 939d71dd Christos Stavrakakis
262 039e3e61 Christos Stavrakakis
    def test_noauthorized(self):
263 039e3e61 Christos Stavrakakis
        """Test 404 for detail of other user vm"""
264 039e3e61 Christos Stavrakakis
        db_vm = self.vm2
265 039e3e61 Christos Stavrakakis
266 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d' % db_vm.id, 'wrong_user')
267 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
268 039e3e61 Christos Stavrakakis
269 039e3e61 Christos Stavrakakis
    def test_wrong_server(self):
270 039e3e61 Christos Stavrakakis
        """Test 404 response if server does not exist."""
271 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d' % 5000)
272 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
273 039e3e61 Christos Stavrakakis
274 039e3e61 Christos Stavrakakis
    def test_create_server_empty(self):
275 039e3e61 Christos Stavrakakis
        """Test if the create server call returns a 400 badRequest if
276 039e3e61 Christos Stavrakakis
           no attributes are specified."""
277 039e3e61 Christos Stavrakakis
278 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers', params={})
279 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
280 039e3e61 Christos Stavrakakis
281 039e3e61 Christos Stavrakakis
    def test_rename_server(self):
282 039e3e61 Christos Stavrakakis
        vm = self.vm2
283 039e3e61 Christos Stavrakakis
        request = {'server': {'name': 'new_name'}}
284 a26e5a4d Georgios D. Tsoukalas
        response = self.myput('servers/%d' % vm.id, vm.userid,
285 a26e5a4d Georgios D. Tsoukalas
                              json.dumps(request), 'json')
286 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
287 039e3e61 Christos Stavrakakis
        self.assertEqual(VirtualMachine.objects.get(id=vm.id).name, "new_name")
288 039e3e61 Christos Stavrakakis
289 a3accf03 Georgios D. Tsoukalas
    def test_catch_wrong_api_paths(self):
290 a3accf03 Georgios D. Tsoukalas
        response = self.myget('nonexistent')
291 a3accf03 Georgios D. Tsoukalas
        self.assertEqual(response.status_code, 400)
292 a3accf03 Georgios D. Tsoukalas
        try:
293 e368ad39 Christos Stavrakakis
            json.loads(response.content)
294 a3accf03 Georgios D. Tsoukalas
        except ValueError:
295 a3accf03 Georgios D. Tsoukalas
            self.assertTrue(False)
296 a3accf03 Georgios D. Tsoukalas
297 16437e4d Kostas Papadimitriou
    def test_method_not_allowed(self, *args):
298 16437e4d Kostas Papadimitriou
        # /servers/ allows only POST, GET
299 16437e4d Kostas Papadimitriou
        response = self.myput('servers', '', '')
300 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
301 16437e4d Kostas Papadimitriou
        response = self.mydelete('servers')
302 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
303 16437e4d Kostas Papadimitriou
304 16437e4d Kostas Papadimitriou
        # /servers/<srvid>/ allows only GET, PUT, DELETE
305 16437e4d Kostas Papadimitriou
        response = self.mypost("servers/42")
306 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
307 16437e4d Kostas Papadimitriou
308 16437e4d Kostas Papadimitriou
        # /imags/<srvid>/metadata/ allows only POST, GET
309 16437e4d Kostas Papadimitriou
        response = self.myput('servers/42/metadata', '', '')
310 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
311 16437e4d Kostas Papadimitriou
        response = self.mydelete('servers/42/metadata')
312 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
313 16437e4d Kostas Papadimitriou
314 16437e4d Kostas Papadimitriou
        # /imags/<srvid>/metadata/ allows only POST, GET
315 16437e4d Kostas Papadimitriou
        response = self.myput('servers/42/metadata', '', '')
316 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
317 16437e4d Kostas Papadimitriou
        response = self.mydelete('servers/42/metadata')
318 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
319 16437e4d Kostas Papadimitriou
320 16437e4d Kostas Papadimitriou
        # /imags/<srvid>/metadata/<key> allows only PUT, GET, DELETE
321 16437e4d Kostas Papadimitriou
        response = self.mypost('servers/42/metadata/foo')
322 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
323 16437e4d Kostas Papadimitriou
324 039e3e61 Christos Stavrakakis
325 cb66110b Christos Stavrakakis
fixed_image = Mock()
326 cb66110b Christos Stavrakakis
fixed_image.return_value = {'location': 'pithos://foo',
327 cb66110b Christos Stavrakakis
                            'checksum': '1234',
328 cb66110b Christos Stavrakakis
                            "id": 1,
329 cb66110b Christos Stavrakakis
                            "name": "test_image",
330 dfcece01 Christos Stavrakakis
                            "size": "41242",
331 cb66110b Christos Stavrakakis
                            'disk_format': 'diskdump'}
332 cb66110b Christos Stavrakakis
333 cb66110b Christos Stavrakakis
334 cb66110b Christos Stavrakakis
@patch('synnefo.api.util.get_image', fixed_image)
335 039e3e61 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
336 a26e5a4d Georgios D. Tsoukalas
class ServerCreateAPITest(ComputeAPITest):
337 cb66110b Christos Stavrakakis
    def setUp(self):
338 cb66110b Christos Stavrakakis
        self.flavor = mfactory.FlavorFactory()
339 039e3e61 Christos Stavrakakis
        # Create public network and backend
340 92d2d1ce Christos Stavrakakis
        subnet = mfactory.IPv4SubnetFactory(network__public=True)
341 92d2d1ce Christos Stavrakakis
        self.network = subnet.network
342 cb66110b Christos Stavrakakis
        self.backend = mfactory.BackendFactory()
343 cb66110b Christos Stavrakakis
        mfactory.BackendNetworkFactory(network=self.network,
344 cb66110b Christos Stavrakakis
                                       backend=self.backend,
345 cb66110b Christos Stavrakakis
                                       operstate="ACTIVE")
346 cb66110b Christos Stavrakakis
        self.request = {
347 e368ad39 Christos Stavrakakis
            "server": {
348 e368ad39 Christos Stavrakakis
                "name": "new-server-test",
349 e368ad39 Christos Stavrakakis
                "userid": "test_user",
350 e368ad39 Christos Stavrakakis
                "imageRef": 1,
351 e368ad39 Christos Stavrakakis
                "flavorRef": self.flavor.id,
352 e368ad39 Christos Stavrakakis
                "metadata": {
353 e368ad39 Christos Stavrakakis
                    "My Server Name": "Apache1"
354 e368ad39 Christos Stavrakakis
                },
355 e368ad39 Christos Stavrakakis
                "personality": []
356 e368ad39 Christos Stavrakakis
            }
357 039e3e61 Christos Stavrakakis
        }
358 cb66110b Christos Stavrakakis
359 cb66110b Christos Stavrakakis
    def test_create_server(self, mrapi):
360 cb66110b Christos Stavrakakis
        """Test if the create server call returns the expected response
361 cb66110b Christos Stavrakakis
           if a valid request has been speficied."""
362 cb66110b Christos Stavrakakis
363 cb66110b Christos Stavrakakis
        mrapi().CreateInstance.return_value = 12
364 cb66110b Christos Stavrakakis
        with override_settings(settings, DEFAULT_INSTANCE_NETWORKS=[]):
365 cb66110b Christos Stavrakakis
            with mocked_quotaholder():
366 2cd55da6 Christos Stavrakakis
                response = self.mypost('servers', 'test_user',
367 cb66110b Christos Stavrakakis
                                       json.dumps(self.request), 'json')
368 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
369 039e3e61 Christos Stavrakakis
        mrapi().CreateInstance.assert_called_once()
370 039e3e61 Christos Stavrakakis
371 039e3e61 Christos Stavrakakis
        api_server = json.loads(response.content)['server']
372 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['status'], "BUILD")
373 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['progress'], 0)
374 2d04422f Christos Stavrakakis
        self.assertEqual(api_server['metadata'],
375 e368ad39 Christos Stavrakakis
                         {"My Server Name":  "Apache1"})
376 039e3e61 Christos Stavrakakis
        self.assertTrue('adminPass' in api_server)
377 039e3e61 Christos Stavrakakis
378 039e3e61 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(userid='test_user')
379 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['name'], db_vm.name)
380 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['status'], db_vm.operstate)
381 039e3e61 Christos Stavrakakis
382 6dafedf6 Christos Stavrakakis
        # Test drained flag in Network:
383 cb66110b Christos Stavrakakis
        self.network.drained = True
384 cb66110b Christos Stavrakakis
        self.network.save()
385 6dafedf6 Christos Stavrakakis
        with mocked_quotaholder():
386 a26e5a4d Georgios D. Tsoukalas
            response = self.mypost('servers', 'test_user',
387 f8675683 Christos Stavrakakis
                                   json.dumps(self.request), 'json')
388 6dafedf6 Christos Stavrakakis
        self.assertEqual(response.status_code, 503, "serviceUnavailable")
389 6dafedf6 Christos Stavrakakis
390 cb66110b Christos Stavrakakis
    def test_create_network_settings(self, mrapi):
391 cb66110b Christos Stavrakakis
        mrapi().CreateInstance.return_value = 12
392 92d2d1ce Christos Stavrakakis
        # Create public network and backend
393 92d2d1ce Christos Stavrakakis
        subnet1 = mfactory.IPv4SubnetFactory()
394 92d2d1ce Christos Stavrakakis
        bnet1 = mfactory.BackendNetworkFactory(network=subnet1.network,
395 92d2d1ce Christos Stavrakakis
                                               backend=self.backend,
396 92d2d1ce Christos Stavrakakis
                                               operstate="ACTIVE")
397 92d2d1ce Christos Stavrakakis
        subnet2 = mfactory.IPv4SubnetFactory()
398 92d2d1ce Christos Stavrakakis
        bnet2 = mfactory.BackendNetworkFactory(network=subnet2.network,
399 92d2d1ce Christos Stavrakakis
                                               backend=self.backend,
400 92d2d1ce Christos Stavrakakis
                                               operstate="ACTIVE")
401 92d2d1ce Christos Stavrakakis
        subnet3 = mfactory.IPv4SubnetFactory(network__userid="test_user")
402 92d2d1ce Christos Stavrakakis
        bnet3 = mfactory.BackendNetworkFactory(network=subnet3.network,
403 92d2d1ce Christos Stavrakakis
                                               backend=self.backend,
404 92d2d1ce Christos Stavrakakis
                                               operstate="ACTIVE")
405 92d2d1ce Christos Stavrakakis
        subnet4 = mfactory.IPv4SubnetFactory(network__userid="test_user")
406 92d2d1ce Christos Stavrakakis
        bnet4 = mfactory.BackendNetworkFactory(network=subnet4.network,
407 92d2d1ce Christos Stavrakakis
                                               backend=self.backend,
408 92d2d1ce Christos Stavrakakis
                                               operstate="ACTIVE")
409 cb66110b Christos Stavrakakis
        # User requested private networks
410 cb66110b Christos Stavrakakis
        request = deepcopy(self.request)
411 cb66110b Christos Stavrakakis
        request["server"]["networks"] = [bnet3.network.id, bnet4.network.id]
412 cb66110b Christos Stavrakakis
        with override_settings(settings,
413 e368ad39 Christos Stavrakakis
                               DEFAULT_INSTANCE_NETWORKS=[
414 e368ad39 Christos Stavrakakis
                                   "SNF:ANY_PUBLIC",
415 e368ad39 Christos Stavrakakis
                                   bnet1.network.id,
416 e368ad39 Christos Stavrakakis
                                   bnet2.network.id]):
417 cb66110b Christos Stavrakakis
            with mocked_quotaholder():
418 2cd55da6 Christos Stavrakakis
                response = self.mypost('servers', 'test_user',
419 cb66110b Christos Stavrakakis
                                       json.dumps(request), 'json')
420 cb66110b Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
421 cb66110b Christos Stavrakakis
        name, args, kwargs = mrapi().CreateInstance.mock_calls[0]
422 cb66110b Christos Stavrakakis
        self.assertEqual(len(kwargs["nics"]), 5)
423 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][0]["network"],
424 cb66110b Christos Stavrakakis
                         self.network.backend_id)
425 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][1]["network"],
426 cb66110b Christos Stavrakakis
                         bnet1.network.backend_id)
427 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][2]["network"],
428 cb66110b Christos Stavrakakis
                         bnet2.network.backend_id)
429 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][3]["network"],
430 cb66110b Christos Stavrakakis
                         bnet3.network.backend_id)
431 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][4]["network"],
432 cb66110b Christos Stavrakakis
                         bnet4.network.backend_id)
433 cb66110b Christos Stavrakakis
434 816d7588 Christos Stavrakakis
        request["server"]["floating_ips"] = []
435 cb66110b Christos Stavrakakis
        with override_settings(settings,
436 e368ad39 Christos Stavrakakis
                               DEFAULT_INSTANCE_NETWORKS=[bnet2.network.id]):
437 cb66110b Christos Stavrakakis
            with mocked_quotaholder():
438 2cd55da6 Christos Stavrakakis
                response = self.mypost('servers', 'test_user',
439 cb66110b Christos Stavrakakis
                                       json.dumps(request), 'json')
440 cb66110b Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
441 cb66110b Christos Stavrakakis
        name, args, kwargs = mrapi().CreateInstance.mock_calls[1]
442 cb66110b Christos Stavrakakis
        self.assertEqual(len(kwargs["nics"]), 3)
443 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][0]["network"],
444 cb66110b Christos Stavrakakis
                         bnet2.network.backend_id)
445 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][1]["network"],
446 cb66110b Christos Stavrakakis
                         bnet3.network.backend_id)
447 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][2]["network"],
448 cb66110b Christos Stavrakakis
                         bnet4.network.backend_id)
449 cb66110b Christos Stavrakakis
450 cb66110b Christos Stavrakakis
        # test invalid network in DEFAULT_INSTANCE_NETWORKS
451 cb66110b Christos Stavrakakis
        with override_settings(settings, DEFAULT_INSTANCE_NETWORKS=[42]):
452 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers', 'test_user',
453 cb66110b Christos Stavrakakis
                                   json.dumps(request), 'json')
454 cb66110b Christos Stavrakakis
        self.assertFault(response, 500, "internalServerError")
455 cb66110b Christos Stavrakakis
456 cb66110b Christos Stavrakakis
        # test connect to public netwok
457 cb66110b Christos Stavrakakis
        request = deepcopy(self.request)
458 cb66110b Christos Stavrakakis
        request["server"]["networks"] = [self.network.id]
459 9446e7e5 Christos Stavrakakis
        with override_settings(settings,
460 9446e7e5 Christos Stavrakakis
                               DEFAULT_INSTANCE_NETWORKS=["SNF:ANY_PUBLIC"]):
461 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers', 'test_user',
462 e368ad39 Christos Stavrakakis
                                   json.dumps(request), 'json')
463 cb66110b Christos Stavrakakis
        self.assertFault(response, 403, "forbidden")
464 cb66110b Christos Stavrakakis
        # test wrong user
465 cb66110b Christos Stavrakakis
        request = deepcopy(self.request)
466 cb66110b Christos Stavrakakis
        request["server"]["networks"] = [bnet3.network.id]
467 9446e7e5 Christos Stavrakakis
        with override_settings(settings,
468 9446e7e5 Christos Stavrakakis
                               DEFAULT_INSTANCE_NETWORKS=["SNF:ANY_PUBLIC"]):
469 cb66110b Christos Stavrakakis
            with mocked_quotaholder():
470 2cd55da6 Christos Stavrakakis
                response = self.mypost('servers', 'dummy_user',
471 cb66110b Christos Stavrakakis
                                       json.dumps(request), 'json')
472 cb66110b Christos Stavrakakis
        self.assertItemNotFound(response)
473 cb66110b Christos Stavrakakis
474 816d7588 Christos Stavrakakis
        # Test floating IPs
475 816d7588 Christos Stavrakakis
        request = deepcopy(self.request)
476 816d7588 Christos Stavrakakis
        request["server"]["networks"] = [bnet4.network.id]
477 92d2d1ce Christos Stavrakakis
        fp1 = mfactory.FloatingIPFactory(address="10.0.0.2",
478 816d7588 Christos Stavrakakis
                                         userid="test_user",
479 92d2d1ce Christos Stavrakakis
                                         nic=None)
480 92d2d1ce Christos Stavrakakis
        fp2 = mfactory.FloatingIPFactory(address="10.0.0.3",
481 816d7588 Christos Stavrakakis
                                         userid="test_user",
482 92d2d1ce Christos Stavrakakis
                                         nic=None)
483 92d2d1ce Christos Stavrakakis
        request["server"]["floating_ips"] = [fp1.address, fp2.address]
484 816d7588 Christos Stavrakakis
        with override_settings(settings,
485 e368ad39 Christos Stavrakakis
                               DEFAULT_INSTANCE_NETWORKS=[bnet3.network.id]):
486 816d7588 Christos Stavrakakis
            with mocked_quotaholder():
487 2cd55da6 Christos Stavrakakis
                response = self.mypost('servers', 'test_user',
488 e368ad39 Christos Stavrakakis
                                       json.dumps(request), 'json')
489 816d7588 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
490 816d7588 Christos Stavrakakis
        api_server = json.loads(response.content)['server']
491 816d7588 Christos Stavrakakis
        vm = VirtualMachine.objects.get(id=api_server["id"])
492 92d2d1ce Christos Stavrakakis
        fp1 = IPAddress.objects.get(floating_ip=True, id=fp1.id)
493 92d2d1ce Christos Stavrakakis
        fp2 = IPAddress.objects.get(floating_ip=True, id=fp2.id)
494 92d2d1ce Christos Stavrakakis
        self.assertEqual(fp1.nic.machine, vm)
495 92d2d1ce Christos Stavrakakis
        self.assertEqual(fp2.nic.machine, vm)
496 816d7588 Christos Stavrakakis
        name, args, kwargs = mrapi().CreateInstance.mock_calls[2]
497 816d7588 Christos Stavrakakis
        self.assertEqual(len(kwargs["nics"]), 4)
498 816d7588 Christos Stavrakakis
        self.assertEqual(kwargs["nics"][0]["network"],
499 816d7588 Christos Stavrakakis
                         bnet3.network.backend_id)
500 92d2d1ce Christos Stavrakakis
        self.assertEqual(kwargs["nics"][1]["network"], fp1.network.backend_id)
501 92d2d1ce Christos Stavrakakis
        self.assertEqual(kwargs["nics"][1]["ip"], fp1.address)
502 92d2d1ce Christos Stavrakakis
        self.assertEqual(kwargs["nics"][2]["network"], fp2.network.backend_id)
503 92d2d1ce Christos Stavrakakis
        self.assertEqual(kwargs["nics"][2]["ip"], fp2.address)
504 816d7588 Christos Stavrakakis
        self.assertEqual(kwargs["nics"][3]["network"],
505 816d7588 Christos Stavrakakis
                         bnet4.network.backend_id)
506 816d7588 Christos Stavrakakis
507 cb66110b Christos Stavrakakis
    def test_create_server_no_flavor(self, mrapi):
508 cb66110b Christos Stavrakakis
        request = deepcopy(self.request)
509 cb66110b Christos Stavrakakis
        request["server"]["flavorRef"] = 42
510 cb66110b Christos Stavrakakis
        with mocked_quotaholder():
511 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers', 'test_user',
512 cb66110b Christos Stavrakakis
                                   json.dumps(request), 'json')
513 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
514 039e3e61 Christos Stavrakakis
515 8e67ea28 Christos Stavrakakis
    def test_create_server_error(self, mrapi):
516 f2080d16 Christos Stavrakakis
        """Test if the create server call returns the expected response
517 f2080d16 Christos Stavrakakis
           if a valid request has been speficied."""
518 f2080d16 Christos Stavrakakis
        mrapi().CreateInstance.side_effect = GanetiApiError("..ganeti is down")
519 f2080d16 Christos Stavrakakis
520 8e67ea28 Christos Stavrakakis
        request = self.request
521 f2080d16 Christos Stavrakakis
        with mocked_quotaholder():
522 f2080d16 Christos Stavrakakis
            response = self.mypost('servers', 'test_user',
523 f2080d16 Christos Stavrakakis
                                   json.dumps(request), 'json')
524 9dcfad23 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
525 f2080d16 Christos Stavrakakis
        mrapi().CreateInstance.assert_called_once()
526 f2080d16 Christos Stavrakakis
        vm = VirtualMachine.objects.get()
527 9dcfad23 Christos Stavrakakis
        # The VM has not been deleted
528 9dcfad23 Christos Stavrakakis
        self.assertFalse(vm.deleted)
529 9dcfad23 Christos Stavrakakis
        # but is in "ERROR" operstate
530 9dcfad23 Christos Stavrakakis
        self.assertEqual(vm.operstate, "ERROR")
531 f2080d16 Christos Stavrakakis
532 039e3e61 Christos Stavrakakis
533 039e3e61 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
534 a26e5a4d Georgios D. Tsoukalas
class ServerDestroyAPITest(ComputeAPITest):
535 039e3e61 Christos Stavrakakis
    def test_delete_server(self, mrapi):
536 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
537 41a7fae7 Christos Stavrakakis
        mrapi().DeleteInstance.return_value = 12
538 2cd55da6 Christos Stavrakakis
        response = self.mydelete('servers/%d' % vm.id, vm.userid)
539 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 204)
540 039e3e61 Christos Stavrakakis
        mrapi().DeleteInstance.assert_called_once()
541 039e3e61 Christos Stavrakakis
542 039e3e61 Christos Stavrakakis
    def test_non_existing_delete_server(self, mrapi):
543 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
544 a26e5a4d Georgios D. Tsoukalas
        response = self.mydelete('servers/%d' % 42, vm.userid)
545 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
546 039e3e61 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
547 039e3e61 Christos Stavrakakis
548 039e3e61 Christos Stavrakakis
549 a26e5a4d Georgios D. Tsoukalas
class ServerMetadataAPITest(ComputeAPITest):
550 039e3e61 Christos Stavrakakis
    def setUp(self):
551 039e3e61 Christos Stavrakakis
        self.vm = mfactory.VirtualMachineFactory()
552 039e3e61 Christos Stavrakakis
        self.metadata = mfactory.VirtualMachineMetadataFactory(vm=self.vm)
553 a26e5a4d Georgios D. Tsoukalas
        super(ServerMetadataAPITest, self).setUp()
554 039e3e61 Christos Stavrakakis
555 039e3e61 Christos Stavrakakis
    def test_get_metadata(self):
556 039e3e61 Christos Stavrakakis
        vm = self.vm
557 039e3e61 Christos Stavrakakis
        create_meta = lambda: mfactory.VirtualMachineMetadataFactory(vm=vm)
558 039e3e61 Christos Stavrakakis
        metadata = [create_meta(), create_meta(), create_meta()]
559 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata' % vm.id, vm.userid)
560 039e3e61 Christos Stavrakakis
        self.assertTrue(response.status_code in [200, 203])
561 2d04422f Christos Stavrakakis
        api_metadata = json.loads(response.content)['metadata']
562 039e3e61 Christos Stavrakakis
        self.assertEqual(len(api_metadata), len(metadata) + 1)
563 039e3e61 Christos Stavrakakis
        for db_m in metadata:
564 039e3e61 Christos Stavrakakis
            self.assertEqual(api_metadata[db_m.meta_key], db_m.meta_value)
565 039e3e61 Christos Stavrakakis
566 e368ad39 Christos Stavrakakis
        request = {
567 e368ad39 Christos Stavrakakis
            'metadata': {
568 e368ad39 Christos Stavrakakis
                'foo': 'bar'
569 e368ad39 Christos Stavrakakis
            },
570 e368ad39 Christos Stavrakakis
            metadata[0].meta_key: 'bar2'
571 e368ad39 Christos Stavrakakis
        }
572 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/metadata' % vm.id,
573 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
574 039e3e61 Christos Stavrakakis
        metadata2 = VirtualMachineMetadata.objects.filter(vm=vm)
575 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata' % vm.id, vm.userid)
576 039e3e61 Christos Stavrakakis
        self.assertTrue(response.status_code in [200, 203])
577 2d04422f Christos Stavrakakis
        api_metadata2 = json.loads(response.content)['metadata']
578 039e3e61 Christos Stavrakakis
        self.assertTrue('foo' in api_metadata2.keys())
579 039e3e61 Christos Stavrakakis
        self.assertTrue(api_metadata2[metadata[0].meta_key], 'bar2')
580 039e3e61 Christos Stavrakakis
        self.assertEqual(len(api_metadata2), len(metadata2))
581 039e3e61 Christos Stavrakakis
        for db_m in metadata2:
582 039e3e61 Christos Stavrakakis
            self.assertEqual(api_metadata2[db_m.meta_key], db_m.meta_value)
583 039e3e61 Christos Stavrakakis
584 039e3e61 Christos Stavrakakis
        # Create new meta
585 039e3e61 Christos Stavrakakis
        request = {'meta': {'foo2': 'bar2'}}
586 a26e5a4d Georgios D. Tsoukalas
        response = self.myput('servers/%d/metadata/foo2' % vm.id,
587 a26e5a4d Georgios D. Tsoukalas
                              vm.userid, json.dumps(request), 'json')
588 039e3e61 Christos Stavrakakis
589 039e3e61 Christos Stavrakakis
        # Get the new meta
590 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid)
591 039e3e61 Christos Stavrakakis
        meta = json.loads(response.content)['meta']
592 039e3e61 Christos Stavrakakis
        self.assertEqual(meta['foo2'], 'bar2')
593 039e3e61 Christos Stavrakakis
594 039e3e61 Christos Stavrakakis
        # Delete the new meta
595 a26e5a4d Georgios D. Tsoukalas
        response = self.mydelete('servers/%d/metadata/foo2' % vm.id, vm.userid)
596 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 204)
597 039e3e61 Christos Stavrakakis
598 039e3e61 Christos Stavrakakis
        # Try to get the deleted meta: should raise 404
599 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid)
600 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 404)
601 039e3e61 Christos Stavrakakis
602 039e3e61 Christos Stavrakakis
    def test_invalid_metadata(self):
603 039e3e61 Christos Stavrakakis
        vm = self.vm
604 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/metadata' % vm.id, vm.userid)
605 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
606 039e3e61 Christos Stavrakakis
        self.assertEqual(len(vm.metadata.all()), 1)
607 039e3e61 Christos Stavrakakis
608 039e3e61 Christos Stavrakakis
    def test_invalid_metadata_server(self):
609 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/42/metadata', 'user')
610 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
611 039e3e61 Christos Stavrakakis
612 039e3e61 Christos Stavrakakis
    def test_get_meta_invalid_key(self):
613 039e3e61 Christos Stavrakakis
        vm = self.vm
614 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid)
615 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
616 039e3e61 Christos Stavrakakis
617 039e3e61 Christos Stavrakakis
618 039e3e61 Christos Stavrakakis
@patch('synnefo.api.util.get_image')
619 039e3e61 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
620 a26e5a4d Georgios D. Tsoukalas
class ServerActionAPITest(ComputeAPITest):
621 039e3e61 Christos Stavrakakis
    def test_actions(self, mrapi, mimage):
622 039e3e61 Christos Stavrakakis
        actions = ['start', 'shutdown', 'reboot']
623 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
624 039e3e61 Christos Stavrakakis
        vm.operstate = "STOPPED"
625 039e3e61 Christos Stavrakakis
        vm.save()
626 41a7fae7 Christos Stavrakakis
        mrapi().StartupInstance.return_value = 0
627 41a7fae7 Christos Stavrakakis
        mrapi().ShutdownInstance.return_value = 1
628 41a7fae7 Christos Stavrakakis
        mrapi().RebootInstance.return_value = 2
629 41a7fae7 Christos Stavrakakis
        for jobId, action in enumerate(actions):
630 41a7fae7 Christos Stavrakakis
            if action in ["shutdown", "reboot"]:
631 41a7fae7 Christos Stavrakakis
                vm.operstate = "STARTED"
632 41a7fae7 Christos Stavrakakis
            else:
633 41a7fae7 Christos Stavrakakis
                vm.operstate = "STOPPED"
634 41a7fae7 Christos Stavrakakis
            vm.task = None
635 41a7fae7 Christos Stavrakakis
            vm.task_job_id = None
636 41a7fae7 Christos Stavrakakis
            vm.save()
637 039e3e61 Christos Stavrakakis
            val = {'type': 'HARD'} if action == 'reboot' else {}
638 039e3e61 Christos Stavrakakis
            request = {action: val}
639 a26e5a4d Georgios D. Tsoukalas
            response = self.mypost('servers/%d/action' % vm.id,
640 a26e5a4d Georgios D. Tsoukalas
                                   vm.userid, json.dumps(request), 'json')
641 039e3e61 Christos Stavrakakis
            self.assertEqual(response.status_code, 202)
642 039e3e61 Christos Stavrakakis
            if action == 'shutdown':
643 41a7fae7 Christos Stavrakakis
                self.assertEqual(VirtualMachine.objects.get(id=vm.id).task,
644 039e3e61 Christos Stavrakakis
                                 "STOP")
645 039e3e61 Christos Stavrakakis
            else:
646 41a7fae7 Christos Stavrakakis
                self.assertEqual(VirtualMachine.objects.get(id=vm.id).task,
647 039e3e61 Christos Stavrakakis
                                 action.upper())
648 41a7fae7 Christos Stavrakakis
            self.assertEqual(VirtualMachine.objects.get(id=vm.id).task_job_id,
649 41a7fae7 Christos Stavrakakis
                             jobId)
650 039e3e61 Christos Stavrakakis
651 039e3e61 Christos Stavrakakis
    def test_action_in_building_vm(self, mrapi, mimage):
652 039e3e61 Christos Stavrakakis
        """Test building in progress"""
653 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate="BUILD")
654 41a7fae7 Christos Stavrakakis
        request = {'start': {}}
655 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
656 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers/%d/action' % vm.id,
657 41a7fae7 Christos Stavrakakis
                                   vm.userid, json.dumps(request), 'json')
658 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 409)
659 039e3e61 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
660 039e3e61 Christos Stavrakakis
661 039e3e61 Christos Stavrakakis
    def test_destroy_build_vm(self, mrapi, mimage):
662 039e3e61 Christos Stavrakakis
        """Test building in progress"""
663 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
664 41a7fae7 Christos Stavrakakis
        mrapi().DeleteInstance.return_value = 2
665 2cd55da6 Christos Stavrakakis
        response = self.mydelete('servers/%d' % vm.id,
666 41a7fae7 Christos Stavrakakis
                                 vm.userid)
667 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
668 039e3e61 Christos Stavrakakis
        mrapi().RemoveInstance.assert_called_once()
669 039e3e61 Christos Stavrakakis
670 039e3e61 Christos Stavrakakis
    def test_firewall(self, mrapi, mimage):
671 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
672 039e3e61 Christos Stavrakakis
        vm.operstate = "STOPPED"
673 039e3e61 Christos Stavrakakis
        vm.save()
674 039e3e61 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'PROTECTED'}}
675 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
676 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, json.dumps(request), 'json')
677 d0545590 Christos Stavrakakis
        self.assertBadRequest(response)
678 d0545590 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'PROTECTED', "nic": "10"}}
679 d0545590 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
680 d0545590 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
681 d0545590 Christos Stavrakakis
        self.assertItemNotFound(response)
682 d0545590 Christos Stavrakakis
        nic = mfactory.NetworkInterfaceFactory(machine=vm)
683 d0545590 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'PROTECTED', "nic": nic.id}}
684 d0545590 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
685 d0545590 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
686 d0545590 Christos Stavrakakis
        self.assertSuccess(response)
687 039e3e61 Christos Stavrakakis
        mrapi().ModifyInstance.assert_called_once()
688 039e3e61 Christos Stavrakakis
689 039e3e61 Christos Stavrakakis
    def test_unsupported_firewall(self, mrapi, mimage):
690 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
691 039e3e61 Christos Stavrakakis
        vm.operstate = "STOPPED"
692 039e3e61 Christos Stavrakakis
        vm.save()
693 039e3e61 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'FOO'}}
694 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
695 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, json.dumps(request), 'json')
696 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
697 039e3e61 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
698 039e3e61 Christos Stavrakakis
699 1af851fd Christos Stavrakakis
    def test_resize_vm(self, mrapi, mimage):
700 1af851fd Christos Stavrakakis
        flavor = mfactory.FlavorFactory(cpu=1, ram=1024)
701 1af851fd Christos Stavrakakis
        # Check building VM
702 1af851fd Christos Stavrakakis
        vm = self.get_vm(flavor=flavor, operstate="BUILD")
703 1af851fd Christos Stavrakakis
        request = {'resize': {'flavorRef': flavor.id}}
704 2cd55da6 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
705 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
706 1af851fd Christos Stavrakakis
        self.assertFault(response, 409, "buildInProgress")
707 1af851fd Christos Stavrakakis
        # Check same Flavor
708 1af851fd Christos Stavrakakis
        vm = self.get_vm(flavor=flavor, operstate="STOPPED")
709 1af851fd Christos Stavrakakis
        request = {'resize': {'flavorRef': flavor.id}}
710 2cd55da6 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
711 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
712 41a7fae7 Christos Stavrakakis
        self.assertBadRequest(response)
713 1af851fd Christos Stavrakakis
        # Check flavor with different disk
714 1af851fd Christos Stavrakakis
        flavor2 = mfactory.FlavorFactory(disk=1024)
715 1af851fd Christos Stavrakakis
        flavor3 = mfactory.FlavorFactory(disk=2048)
716 1af851fd Christos Stavrakakis
        vm = self.get_vm(flavor=flavor2, operstate="STOPPED")
717 1af851fd Christos Stavrakakis
        request = {'resize': {'flavorRef': flavor3.id}}
718 2cd55da6 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
719 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
720 1af851fd Christos Stavrakakis
        self.assertBadRequest(response)
721 1af851fd Christos Stavrakakis
        flavor2 = mfactory.FlavorFactory(disk_template="foo")
722 1af851fd Christos Stavrakakis
        flavor3 = mfactory.FlavorFactory(disk_template="baz")
723 1af851fd Christos Stavrakakis
        vm = self.get_vm(flavor=flavor2, operstate="STOPPED")
724 1af851fd Christos Stavrakakis
        request = {'resize': {'flavorRef': flavor3.id}}
725 2cd55da6 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
726 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
727 1af851fd Christos Stavrakakis
        self.assertBadRequest(response)
728 1af851fd Christos Stavrakakis
        # Check success
729 1af851fd Christos Stavrakakis
        vm = self.get_vm(flavor=flavor, operstate="STOPPED")
730 1af851fd Christos Stavrakakis
        flavor4 = mfactory.FlavorFactory(disk_template=flavor.disk_template,
731 1af851fd Christos Stavrakakis
                                         disk=flavor.disk,
732 1af851fd Christos Stavrakakis
                                         cpu=4, ram=2048)
733 1af851fd Christos Stavrakakis
        request = {'resize': {'flavorRef': flavor4.id}}
734 1af851fd Christos Stavrakakis
        mrapi().ModifyInstance.return_value = 42
735 2cd55da6 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
736 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
737 1af851fd Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
738 1af851fd Christos Stavrakakis
        vm = VirtualMachine.objects.get(id=vm.id)
739 41a7fae7 Christos Stavrakakis
        self.assertEqual(vm.task_job_id, 42)
740 1af851fd Christos Stavrakakis
        name, args, kwargs = mrapi().ModifyInstance.mock_calls[0]
741 1af851fd Christos Stavrakakis
        self.assertEqual(kwargs["beparams"]["vcpus"], 4)
742 1af851fd Christos Stavrakakis
        self.assertEqual(kwargs["beparams"]["minmem"], 2048)
743 1af851fd Christos Stavrakakis
        self.assertEqual(kwargs["beparams"]["maxmem"], 2048)
744 1af851fd Christos Stavrakakis
745 41a7fae7 Christos Stavrakakis
    def test_action_on_resizing_vm(self, mrapi, mimage):
746 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
747 41a7fae7 Christos Stavrakakis
        vm.operstate = "RESIZE"
748 41a7fae7 Christos Stavrakakis
        vm.save()
749 41a7fae7 Christos Stavrakakis
        for action in VirtualMachine.ACTIONS:
750 41a7fae7 Christos Stavrakakis
            request = {action[0]: ""}
751 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers/%d/action' % vm.id,
752 e368ad39 Christos Stavrakakis
                                   vm.userid, json.dumps(request), 'json')
753 41a7fae7 Christos Stavrakakis
            self.assertBadRequest(response)
754 41a7fae7 Christos Stavrakakis
        # however you can destroy
755 41a7fae7 Christos Stavrakakis
        mrapi().DeleteInstance.return_value = 42
756 2cd55da6 Christos Stavrakakis
        response = self.mydelete('servers/%d' % vm.id,
757 2cd55da6 Christos Stavrakakis
                                 vm.userid)
758 41a7fae7 Christos Stavrakakis
        self.assertSuccess(response)
759 41a7fae7 Christos Stavrakakis
760 1af851fd Christos Stavrakakis
    def get_vm(self, flavor, operstate):
761 1af851fd Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(flavor=flavor)
762 1af851fd Christos Stavrakakis
        vm.operstate = operstate
763 1af851fd Christos Stavrakakis
        vm.backendjobstatus = "success"
764 1af851fd Christos Stavrakakis
        vm.save()
765 1af851fd Christos Stavrakakis
        return vm
766 1af851fd Christos Stavrakakis
767 039e3e61 Christos Stavrakakis
768 a26e5a4d Georgios D. Tsoukalas
class ServerVNCConsole(ComputeAPITest):
769 039e3e61 Christos Stavrakakis
    def test_not_active_server(self):
770 039e3e61 Christos Stavrakakis
        """Test console req for not ACTIVE server returns badRequest"""
771 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate="BUILD")
772 039e3e61 Christos Stavrakakis
        data = json.dumps({'console': {'type': 'vnc'}})
773 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
774 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, data, 'json')
775 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
776 039e3e61 Christos Stavrakakis
777 039e3e61 Christos Stavrakakis
    def test_active_server(self):
778 039e3e61 Christos Stavrakakis
        """Test console req for ACTIVE server"""
779 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
780 039e3e61 Christos Stavrakakis
        vm.operstate = 'STARTED'
781 039e3e61 Christos Stavrakakis
        vm.save()
782 039e3e61 Christos Stavrakakis
783 039e3e61 Christos Stavrakakis
        data = json.dumps({'console': {'type': 'vnc'}})
784 41a7fae7 Christos Stavrakakis
        with override_settings(settings, TEST=True):
785 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers/%d/action' % vm.id,
786 41a7fae7 Christos Stavrakakis
                                   vm.userid, data, 'json')
787 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 200)
788 039e3e61 Christos Stavrakakis
        reply = json.loads(response.content)
789 039e3e61 Christos Stavrakakis
        self.assertEqual(reply.keys(), ['console'])
790 039e3e61 Christos Stavrakakis
        console = reply['console']
791 039e3e61 Christos Stavrakakis
        self.assertEqual(console['type'], 'vnc')
792 039e3e61 Christos Stavrakakis
        self.assertEqual(set(console.keys()),
793 039e3e61 Christos Stavrakakis
                         set(['type', 'host', 'port', 'password']))
794 039e3e61 Christos Stavrakakis
795 039e3e61 Christos Stavrakakis
    def test_wrong_console_type(self):
796 039e3e61 Christos Stavrakakis
        """Test console req for ACTIVE server"""
797 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
798 039e3e61 Christos Stavrakakis
        vm.operstate = 'STARTED'
799 039e3e61 Christos Stavrakakis
        vm.save()
800 039e3e61 Christos Stavrakakis
801 039e3e61 Christos Stavrakakis
        data = json.dumps({'console': {'type': 'foo'}})
802 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
803 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, data, 'json')
804 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)