Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (36.4 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 b3a43976 Christos Stavrakakis
        # test no public ip
165 b3a43976 Christos Stavrakakis
        with override_settings(settings,
166 b3a43976 Christos Stavrakakis
                               CYCLADES_SERVERS_FQDN="vm.example.org"):
167 b3a43976 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
168 b3a43976 Christos Stavrakakis
            server = json.loads(response.content)['server']
169 b3a43976 Christos Stavrakakis
            self.assertEqual(server["SNF:fqdn"], "")
170 b3a43976 Christos Stavrakakis
        mfactory.IPv4AddressFactory(nic__machine=vm, network__public=True)
171 7e82ac17 Christos Stavrakakis
        with override_settings(settings,
172 7e82ac17 Christos Stavrakakis
                               CYCLADES_SERVERS_FQDN="vm.example.org"):
173 7e82ac17 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
174 7e82ac17 Christos Stavrakakis
            server = json.loads(response.content)['server']
175 7e82ac17 Christos Stavrakakis
            self.assertEqual(server["SNF:fqdn"], "vm.example.org")
176 e368ad39 Christos Stavrakakis
        with override_settings(settings, CYCLADES_SERVERS_FQDN=
177 e368ad39 Christos Stavrakakis
                               "snf-%(id)s.vm.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 e368ad39 Christos Stavrakakis
            self.assertEqual(server["SNF:fqdn"],
181 e368ad39 Christos Stavrakakis
                             "snf-%d.vm.example.org" % vm.id)
182 7e82ac17 Christos Stavrakakis
        with override_settings(settings,
183 e368ad39 Christos Stavrakakis
                               CYCLADES_SERVERS_FQDN=
184 e368ad39 Christos Stavrakakis
                               "snf-%(id)s.vm-%(id)s.example.org"):
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"], "snf-%d.vm-%d.example.org" %
188 7e82ac17 Christos Stavrakakis
                             (vm.id, vm.id))
189 e08afd0b Christos Stavrakakis
190 e08afd0b Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
191 7e82ac17 Christos Stavrakakis
        # No setting, no NICs
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 7e82ac17 Christos Stavrakakis
            self.assertEqual(server["SNF:fqdn"], "")
197 7e82ac17 Christos Stavrakakis
198 7e82ac17 Christos Stavrakakis
        # IPv6 NIC
199 92d2d1ce Christos Stavrakakis
        ipv6_address = mfactory.IPv6AddressFactory(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"], ipv6_address.address)
206 7e82ac17 Christos Stavrakakis
207 7e82ac17 Christos Stavrakakis
        # IPv4 NIC
208 92d2d1ce Christos Stavrakakis
        ipv4_address = mfactory.IPv4AddressFactory(nic__machine=vm,
209 92d2d1ce Christos Stavrakakis
                                                   network__public=True)
210 7e82ac17 Christos Stavrakakis
        with override_settings(settings,
211 7e82ac17 Christos Stavrakakis
                               CYCLADES_SERVERS_FQDN=None):
212 7e82ac17 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
213 7e82ac17 Christos Stavrakakis
            server = json.loads(response.content)['server']
214 92d2d1ce Christos Stavrakakis
            self.assertEqual(server["SNF:fqdn"], ipv4_address.address)
215 7e82ac17 Christos Stavrakakis
216 2522e489 Christos Stavrakakis
    def test_server_port_forwarding(self):
217 2522e489 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
218 b3a43976 Christos Stavrakakis
        # test None if the server has no public IP
219 2522e489 Christos Stavrakakis
        ports = {
220 2522e489 Christos Stavrakakis
            22: ("foo", 61000),
221 2522e489 Christos Stavrakakis
            80: lambda ip, id, fqdn, user: ("bar", 61001)}
222 2522e489 Christos Stavrakakis
        with override_settings(settings,
223 2522e489 Christos Stavrakakis
                               CYCLADES_PORT_FORWARDING=ports):
224 2522e489 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
225 b3a43976 Christos Stavrakakis
        server = json.loads(response.content)['server']
226 b3a43976 Christos Stavrakakis
        self.assertEqual(server["SNF:port_forwarding"], {})
227 b3a43976 Christos Stavrakakis
228 b3a43976 Christos Stavrakakis
        # Add with public IP
229 b3a43976 Christos Stavrakakis
        mfactory.IPv4AddressFactory(nic__machine=vm, network__public=True)
230 b3a43976 Christos Stavrakakis
        with override_settings(settings,
231 b3a43976 Christos Stavrakakis
                               CYCLADES_PORT_FORWARDING=ports):
232 b3a43976 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
233 b3a43976 Christos Stavrakakis
        server = json.loads(response.content)['server']
234 b3a43976 Christos Stavrakakis
        self.assertEqual(server["SNF:port_forwarding"],
235 b3a43976 Christos Stavrakakis
                         {"22": {"host": "foo", "port": "61000"},
236 b3a43976 Christos Stavrakakis
                          "80": {"host": "bar", "port": "61001"}})
237 2522e489 Christos Stavrakakis
238 2522e489 Christos Stavrakakis
        def _port_from_ip(ip, base):
239 2522e489 Christos Stavrakakis
            fields = ip.split('.', 4)
240 2522e489 Christos Stavrakakis
            return (base + 256*int(fields[2]) + int(fields[3]))
241 2522e489 Christos Stavrakakis
242 2522e489 Christos Stavrakakis
        ports = {
243 2522e489 Christos Stavrakakis
            22: lambda ip, id, fqdn, user:
244 2522e489 Christos Stavrakakis
            ip and ("gate", _port_from_ip(ip, 10000)) or None}
245 e08afd0b Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
246 2522e489 Christos Stavrakakis
        with override_settings(settings,
247 2522e489 Christos Stavrakakis
                               CYCLADES_PORT_FORWARDING=ports):
248 2522e489 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
249 2522e489 Christos Stavrakakis
            server = json.loads(response.content)['server']
250 2522e489 Christos Stavrakakis
            self.assertEqual(server["SNF:port_forwarding"], {})
251 2522e489 Christos Stavrakakis
252 92d2d1ce Christos Stavrakakis
        mfactory.IPv4AddressFactory(nic__machine=vm,
253 92d2d1ce Christos Stavrakakis
                                    network__public=True,
254 92d2d1ce Christos Stavrakakis
                                    address="192.168.2.2")
255 2522e489 Christos Stavrakakis
        with override_settings(settings,
256 2522e489 Christos Stavrakakis
                               CYCLADES_PORT_FORWARDING=ports):
257 2522e489 Christos Stavrakakis
            response = self.myget("servers/%d" % vm.id, vm.userid)
258 2522e489 Christos Stavrakakis
            server = json.loads(response.content)['server']
259 2522e489 Christos Stavrakakis
            self.assertEqual(server["SNF:port_forwarding"],
260 2522e489 Christos Stavrakakis
                             {"22": {"host": "gate", "port": "10514"}})
261 2522e489 Christos Stavrakakis
262 939d71dd Christos Stavrakakis
    def test_server_building_nics(self):
263 939d71dd Christos Stavrakakis
        db_vm = self.vm2
264 939d71dd Christos Stavrakakis
        user = self.vm2.userid
265 939d71dd Christos Stavrakakis
        net1 = mfactory.NetworkFactory()
266 939d71dd Christos Stavrakakis
        net2 = mfactory.NetworkFactory()
267 939d71dd Christos Stavrakakis
        net3 = mfactory.NetworkFactory()
268 939d71dd Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net1,
269 3a6be177 Christos Stavrakakis
                                         state="BUILD")
270 939d71dd Christos Stavrakakis
        nic2 = mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net2,
271 939d71dd Christos Stavrakakis
                                                state="ACTIVE")
272 939d71dd Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net3,
273 3a6be177 Christos Stavrakakis
                                         state="BUILD")
274 939d71dd Christos Stavrakakis
275 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d' % db_vm.id, user)
276 939d71dd Christos Stavrakakis
        server = json.loads(response.content)['server']
277 2d04422f Christos Stavrakakis
        nics = server["attachments"]
278 939d71dd Christos Stavrakakis
        self.assertEqual(len(nics), 1)
279 939d71dd Christos Stavrakakis
        self.assertEqual(nics[0]["network_id"], str(nic2.network_id))
280 939d71dd Christos Stavrakakis
281 039e3e61 Christos Stavrakakis
    def test_noauthorized(self):
282 039e3e61 Christos Stavrakakis
        """Test 404 for detail of other user vm"""
283 039e3e61 Christos Stavrakakis
        db_vm = self.vm2
284 039e3e61 Christos Stavrakakis
285 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d' % db_vm.id, 'wrong_user')
286 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
287 039e3e61 Christos Stavrakakis
288 039e3e61 Christos Stavrakakis
    def test_wrong_server(self):
289 039e3e61 Christos Stavrakakis
        """Test 404 response if server does not exist."""
290 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d' % 5000)
291 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
292 039e3e61 Christos Stavrakakis
293 039e3e61 Christos Stavrakakis
    def test_create_server_empty(self):
294 039e3e61 Christos Stavrakakis
        """Test if the create server call returns a 400 badRequest if
295 039e3e61 Christos Stavrakakis
           no attributes are specified."""
296 039e3e61 Christos Stavrakakis
297 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers', params={})
298 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
299 039e3e61 Christos Stavrakakis
300 039e3e61 Christos Stavrakakis
    def test_rename_server(self):
301 039e3e61 Christos Stavrakakis
        vm = self.vm2
302 039e3e61 Christos Stavrakakis
        request = {'server': {'name': 'new_name'}}
303 a26e5a4d Georgios D. Tsoukalas
        response = self.myput('servers/%d' % vm.id, vm.userid,
304 a26e5a4d Georgios D. Tsoukalas
                              json.dumps(request), 'json')
305 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
306 039e3e61 Christos Stavrakakis
        self.assertEqual(VirtualMachine.objects.get(id=vm.id).name, "new_name")
307 039e3e61 Christos Stavrakakis
308 a3accf03 Georgios D. Tsoukalas
    def test_catch_wrong_api_paths(self):
309 a3accf03 Georgios D. Tsoukalas
        response = self.myget('nonexistent')
310 a3accf03 Georgios D. Tsoukalas
        self.assertEqual(response.status_code, 400)
311 a3accf03 Georgios D. Tsoukalas
        try:
312 e368ad39 Christos Stavrakakis
            json.loads(response.content)
313 a3accf03 Georgios D. Tsoukalas
        except ValueError:
314 a3accf03 Georgios D. Tsoukalas
            self.assertTrue(False)
315 a3accf03 Georgios D. Tsoukalas
316 16437e4d Kostas Papadimitriou
    def test_method_not_allowed(self, *args):
317 16437e4d Kostas Papadimitriou
        # /servers/ allows only POST, GET
318 16437e4d Kostas Papadimitriou
        response = self.myput('servers', '', '')
319 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
320 16437e4d Kostas Papadimitriou
        response = self.mydelete('servers')
321 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
322 16437e4d Kostas Papadimitriou
323 16437e4d Kostas Papadimitriou
        # /servers/<srvid>/ allows only GET, PUT, DELETE
324 16437e4d Kostas Papadimitriou
        response = self.mypost("servers/42")
325 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
326 16437e4d Kostas Papadimitriou
327 16437e4d Kostas Papadimitriou
        # /imags/<srvid>/metadata/ allows only POST, GET
328 16437e4d Kostas Papadimitriou
        response = self.myput('servers/42/metadata', '', '')
329 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
330 16437e4d Kostas Papadimitriou
        response = self.mydelete('servers/42/metadata')
331 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
332 16437e4d Kostas Papadimitriou
333 16437e4d Kostas Papadimitriou
        # /imags/<srvid>/metadata/ allows only POST, GET
334 16437e4d Kostas Papadimitriou
        response = self.myput('servers/42/metadata', '', '')
335 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
336 16437e4d Kostas Papadimitriou
        response = self.mydelete('servers/42/metadata')
337 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
338 16437e4d Kostas Papadimitriou
339 16437e4d Kostas Papadimitriou
        # /imags/<srvid>/metadata/<key> allows only PUT, GET, DELETE
340 16437e4d Kostas Papadimitriou
        response = self.mypost('servers/42/metadata/foo')
341 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
342 16437e4d Kostas Papadimitriou
343 039e3e61 Christos Stavrakakis
344 cb66110b Christos Stavrakakis
fixed_image = Mock()
345 cb66110b Christos Stavrakakis
fixed_image.return_value = {'location': 'pithos://foo',
346 cb66110b Christos Stavrakakis
                            'checksum': '1234',
347 cb66110b Christos Stavrakakis
                            "id": 1,
348 cb66110b Christos Stavrakakis
                            "name": "test_image",
349 dfcece01 Christos Stavrakakis
                            "size": "41242",
350 cb66110b Christos Stavrakakis
                            'disk_format': 'diskdump'}
351 cb66110b Christos Stavrakakis
352 cb66110b Christos Stavrakakis
353 cb66110b Christos Stavrakakis
@patch('synnefo.api.util.get_image', fixed_image)
354 039e3e61 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
355 a26e5a4d Georgios D. Tsoukalas
class ServerCreateAPITest(ComputeAPITest):
356 cb66110b Christos Stavrakakis
    def setUp(self):
357 cb66110b Christos Stavrakakis
        self.flavor = mfactory.FlavorFactory()
358 039e3e61 Christos Stavrakakis
        # Create public network and backend
359 92d2d1ce Christos Stavrakakis
        subnet = mfactory.IPv4SubnetFactory(network__public=True)
360 92d2d1ce Christos Stavrakakis
        self.network = subnet.network
361 cb66110b Christos Stavrakakis
        self.backend = mfactory.BackendFactory()
362 cb66110b Christos Stavrakakis
        mfactory.BackendNetworkFactory(network=self.network,
363 cb66110b Christos Stavrakakis
                                       backend=self.backend,
364 cb66110b Christos Stavrakakis
                                       operstate="ACTIVE")
365 cb66110b Christos Stavrakakis
        self.request = {
366 e368ad39 Christos Stavrakakis
            "server": {
367 e368ad39 Christos Stavrakakis
                "name": "new-server-test",
368 e368ad39 Christos Stavrakakis
                "userid": "test_user",
369 e368ad39 Christos Stavrakakis
                "imageRef": 1,
370 e368ad39 Christos Stavrakakis
                "flavorRef": self.flavor.id,
371 e368ad39 Christos Stavrakakis
                "metadata": {
372 e368ad39 Christos Stavrakakis
                    "My Server Name": "Apache1"
373 e368ad39 Christos Stavrakakis
                },
374 e368ad39 Christos Stavrakakis
                "personality": []
375 e368ad39 Christos Stavrakakis
            }
376 039e3e61 Christos Stavrakakis
        }
377 cb66110b Christos Stavrakakis
378 cb66110b Christos Stavrakakis
    def test_create_server(self, mrapi):
379 cb66110b Christos Stavrakakis
        """Test if the create server call returns the expected response
380 cb66110b Christos Stavrakakis
           if a valid request has been speficied."""
381 cb66110b Christos Stavrakakis
382 cb66110b Christos Stavrakakis
        mrapi().CreateInstance.return_value = 12
383 cb66110b Christos Stavrakakis
        with override_settings(settings, DEFAULT_INSTANCE_NETWORKS=[]):
384 cb66110b Christos Stavrakakis
            with mocked_quotaholder():
385 2cd55da6 Christos Stavrakakis
                response = self.mypost('servers', 'test_user',
386 cb66110b Christos Stavrakakis
                                       json.dumps(self.request), 'json')
387 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
388 039e3e61 Christos Stavrakakis
        mrapi().CreateInstance.assert_called_once()
389 039e3e61 Christos Stavrakakis
390 039e3e61 Christos Stavrakakis
        api_server = json.loads(response.content)['server']
391 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['status'], "BUILD")
392 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['progress'], 0)
393 2d04422f Christos Stavrakakis
        self.assertEqual(api_server['metadata'],
394 e368ad39 Christos Stavrakakis
                         {"My Server Name":  "Apache1"})
395 039e3e61 Christos Stavrakakis
        self.assertTrue('adminPass' in api_server)
396 039e3e61 Christos Stavrakakis
397 039e3e61 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(userid='test_user')
398 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['name'], db_vm.name)
399 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['status'], db_vm.operstate)
400 039e3e61 Christos Stavrakakis
401 6dafedf6 Christos Stavrakakis
        # Test drained flag in Network:
402 cb66110b Christos Stavrakakis
        self.network.drained = True
403 cb66110b Christos Stavrakakis
        self.network.save()
404 6dafedf6 Christos Stavrakakis
        with mocked_quotaholder():
405 a26e5a4d Georgios D. Tsoukalas
            response = self.mypost('servers', 'test_user',
406 f8675683 Christos Stavrakakis
                                   json.dumps(self.request), 'json')
407 6dafedf6 Christos Stavrakakis
        self.assertEqual(response.status_code, 503, "serviceUnavailable")
408 6dafedf6 Christos Stavrakakis
409 cb66110b Christos Stavrakakis
    def test_create_network_settings(self, mrapi):
410 cb66110b Christos Stavrakakis
        mrapi().CreateInstance.return_value = 12
411 92d2d1ce Christos Stavrakakis
        # Create public network and backend
412 710b1c43 Christos Stavrakakis
        subnet1 = mfactory.IPv4SubnetFactory(network__userid="test_user")
413 92d2d1ce Christos Stavrakakis
        bnet1 = mfactory.BackendNetworkFactory(network=subnet1.network,
414 92d2d1ce Christos Stavrakakis
                                               backend=self.backend,
415 92d2d1ce Christos Stavrakakis
                                               operstate="ACTIVE")
416 710b1c43 Christos Stavrakakis
        subnet2 = mfactory.IPv4SubnetFactory(network__userid="test_user")
417 92d2d1ce Christos Stavrakakis
        bnet2 = mfactory.BackendNetworkFactory(network=subnet2.network,
418 92d2d1ce Christos Stavrakakis
                                               backend=self.backend,
419 92d2d1ce Christos Stavrakakis
                                               operstate="ACTIVE")
420 cb66110b Christos Stavrakakis
        # User requested private networks
421 cb66110b Christos Stavrakakis
        request = deepcopy(self.request)
422 710b1c43 Christos Stavrakakis
        request["server"]["networks"] = [bnet1.network.id, bnet2.network.id]
423 cb66110b Christos Stavrakakis
        with override_settings(settings,
424 e368ad39 Christos Stavrakakis
                               DEFAULT_INSTANCE_NETWORKS=[
425 710b1c43 Christos Stavrakakis
                                   "SNF:ANY_PUBLIC"]):
426 cb66110b Christos Stavrakakis
            with mocked_quotaholder():
427 2cd55da6 Christos Stavrakakis
                response = self.mypost('servers', 'test_user',
428 cb66110b Christos Stavrakakis
                                       json.dumps(request), 'json')
429 cb66110b Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
430 cb66110b Christos Stavrakakis
        name, args, kwargs = mrapi().CreateInstance.mock_calls[0]
431 710b1c43 Christos Stavrakakis
        self.assertEqual(len(kwargs["nics"]), 3)
432 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][0]["network"],
433 cb66110b Christos Stavrakakis
                         self.network.backend_id)
434 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][1]["network"],
435 cb66110b Christos Stavrakakis
                         bnet1.network.backend_id)
436 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][2]["network"],
437 cb66110b Christos Stavrakakis
                         bnet2.network.backend_id)
438 cb66110b Christos Stavrakakis
439 710b1c43 Christos Stavrakakis
        subnet3 = mfactory.IPv4SubnetFactory(network__public=True,
440 710b1c43 Christos Stavrakakis
                                             network__floating_ip_pool=True)
441 710b1c43 Christos Stavrakakis
        bnet3 = mfactory.BackendNetworkFactory(network=subnet3.network,
442 710b1c43 Christos Stavrakakis
                                               backend=self.backend,
443 710b1c43 Christos Stavrakakis
                                               operstate="ACTIVE")
444 816d7588 Christos Stavrakakis
        request["server"]["floating_ips"] = []
445 cb66110b Christos Stavrakakis
        with override_settings(settings,
446 710b1c43 Christos Stavrakakis
                               DEFAULT_INSTANCE_NETWORKS=[bnet3.network.id]):
447 cb66110b Christos Stavrakakis
            with mocked_quotaholder():
448 2cd55da6 Christos Stavrakakis
                response = self.mypost('servers', 'test_user',
449 cb66110b Christos Stavrakakis
                                       json.dumps(request), 'json')
450 cb66110b Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
451 cb66110b Christos Stavrakakis
        name, args, kwargs = mrapi().CreateInstance.mock_calls[1]
452 cb66110b Christos Stavrakakis
        self.assertEqual(len(kwargs["nics"]), 3)
453 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][0]["network"],
454 cb66110b Christos Stavrakakis
                         bnet3.network.backend_id)
455 710b1c43 Christos Stavrakakis
        self.assertEqual(kwargs["nics"][1]["network"],
456 710b1c43 Christos Stavrakakis
                         bnet1.network.backend_id)
457 cb66110b Christos Stavrakakis
        self.assertEqual(kwargs["nics"][2]["network"],
458 710b1c43 Christos Stavrakakis
                         bnet2.network.backend_id)
459 cb66110b Christos Stavrakakis
460 cb66110b Christos Stavrakakis
        # test invalid network in DEFAULT_INSTANCE_NETWORKS
461 cb66110b Christos Stavrakakis
        with override_settings(settings, DEFAULT_INSTANCE_NETWORKS=[42]):
462 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers', 'test_user',
463 cb66110b Christos Stavrakakis
                                   json.dumps(request), 'json')
464 cb66110b Christos Stavrakakis
        self.assertFault(response, 500, "internalServerError")
465 cb66110b Christos Stavrakakis
466 cb66110b Christos Stavrakakis
        # test connect to public netwok
467 cb66110b Christos Stavrakakis
        request = deepcopy(self.request)
468 cb66110b Christos Stavrakakis
        request["server"]["networks"] = [self.network.id]
469 9446e7e5 Christos Stavrakakis
        with override_settings(settings,
470 9446e7e5 Christos Stavrakakis
                               DEFAULT_INSTANCE_NETWORKS=["SNF:ANY_PUBLIC"]):
471 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers', 'test_user',
472 e368ad39 Christos Stavrakakis
                                   json.dumps(request), 'json')
473 cb66110b Christos Stavrakakis
        self.assertFault(response, 403, "forbidden")
474 710b1c43 Christos Stavrakakis
475 cb66110b Christos Stavrakakis
        # test wrong user
476 cb66110b Christos Stavrakakis
        request = deepcopy(self.request)
477 710b1c43 Christos Stavrakakis
        request["server"]["networks"] = [bnet1.network.id]
478 9446e7e5 Christos Stavrakakis
        with override_settings(settings,
479 9446e7e5 Christos Stavrakakis
                               DEFAULT_INSTANCE_NETWORKS=["SNF:ANY_PUBLIC"]):
480 cb66110b Christos Stavrakakis
            with mocked_quotaholder():
481 2cd55da6 Christos Stavrakakis
                response = self.mypost('servers', 'dummy_user',
482 cb66110b Christos Stavrakakis
                                       json.dumps(request), 'json')
483 cb66110b Christos Stavrakakis
        self.assertItemNotFound(response)
484 cb66110b Christos Stavrakakis
485 816d7588 Christos Stavrakakis
        # Test floating IPs
486 816d7588 Christos Stavrakakis
        request = deepcopy(self.request)
487 710b1c43 Christos Stavrakakis
        request["server"]["networks"] = [bnet1.network.id]
488 92d2d1ce Christos Stavrakakis
        fp1 = mfactory.FloatingIPFactory(address="10.0.0.2",
489 816d7588 Christos Stavrakakis
                                         userid="test_user",
490 710b1c43 Christos Stavrakakis
                                         network=self.network,
491 92d2d1ce Christos Stavrakakis
                                         nic=None)
492 92d2d1ce Christos Stavrakakis
        fp2 = mfactory.FloatingIPFactory(address="10.0.0.3",
493 816d7588 Christos Stavrakakis
                                         userid="test_user",
494 710b1c43 Christos Stavrakakis
                                         network=self.network,
495 92d2d1ce Christos Stavrakakis
                                         nic=None)
496 92d2d1ce Christos Stavrakakis
        request["server"]["floating_ips"] = [fp1.address, fp2.address]
497 816d7588 Christos Stavrakakis
        with override_settings(settings,
498 e368ad39 Christos Stavrakakis
                               DEFAULT_INSTANCE_NETWORKS=[bnet3.network.id]):
499 816d7588 Christos Stavrakakis
            with mocked_quotaholder():
500 2cd55da6 Christos Stavrakakis
                response = self.mypost('servers', 'test_user',
501 e368ad39 Christos Stavrakakis
                                       json.dumps(request), 'json')
502 816d7588 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
503 816d7588 Christos Stavrakakis
        api_server = json.loads(response.content)['server']
504 816d7588 Christos Stavrakakis
        vm = VirtualMachine.objects.get(id=api_server["id"])
505 92d2d1ce Christos Stavrakakis
        fp1 = IPAddress.objects.get(floating_ip=True, id=fp1.id)
506 92d2d1ce Christos Stavrakakis
        fp2 = IPAddress.objects.get(floating_ip=True, id=fp2.id)
507 92d2d1ce Christos Stavrakakis
        self.assertEqual(fp1.nic.machine, vm)
508 92d2d1ce Christos Stavrakakis
        self.assertEqual(fp2.nic.machine, vm)
509 816d7588 Christos Stavrakakis
        name, args, kwargs = mrapi().CreateInstance.mock_calls[2]
510 816d7588 Christos Stavrakakis
        self.assertEqual(len(kwargs["nics"]), 4)
511 816d7588 Christos Stavrakakis
        self.assertEqual(kwargs["nics"][0]["network"],
512 816d7588 Christos Stavrakakis
                         bnet3.network.backend_id)
513 92d2d1ce Christos Stavrakakis
        self.assertEqual(kwargs["nics"][1]["network"], fp1.network.backend_id)
514 92d2d1ce Christos Stavrakakis
        self.assertEqual(kwargs["nics"][1]["ip"], fp1.address)
515 92d2d1ce Christos Stavrakakis
        self.assertEqual(kwargs["nics"][2]["network"], fp2.network.backend_id)
516 92d2d1ce Christos Stavrakakis
        self.assertEqual(kwargs["nics"][2]["ip"], fp2.address)
517 816d7588 Christos Stavrakakis
        self.assertEqual(kwargs["nics"][3]["network"],
518 710b1c43 Christos Stavrakakis
                         bnet1.network.backend_id)
519 816d7588 Christos Stavrakakis
520 cb66110b Christos Stavrakakis
    def test_create_server_no_flavor(self, mrapi):
521 cb66110b Christos Stavrakakis
        request = deepcopy(self.request)
522 cb66110b Christos Stavrakakis
        request["server"]["flavorRef"] = 42
523 cb66110b Christos Stavrakakis
        with mocked_quotaholder():
524 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers', 'test_user',
525 cb66110b Christos Stavrakakis
                                   json.dumps(request), 'json')
526 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
527 039e3e61 Christos Stavrakakis
528 8e67ea28 Christos Stavrakakis
    def test_create_server_error(self, mrapi):
529 f2080d16 Christos Stavrakakis
        """Test if the create server call returns the expected response
530 f2080d16 Christos Stavrakakis
           if a valid request has been speficied."""
531 f2080d16 Christos Stavrakakis
        mrapi().CreateInstance.side_effect = GanetiApiError("..ganeti is down")
532 f2080d16 Christos Stavrakakis
533 8e67ea28 Christos Stavrakakis
        request = self.request
534 f2080d16 Christos Stavrakakis
        with mocked_quotaholder():
535 f2080d16 Christos Stavrakakis
            response = self.mypost('servers', 'test_user',
536 f2080d16 Christos Stavrakakis
                                   json.dumps(request), 'json')
537 9dcfad23 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
538 f2080d16 Christos Stavrakakis
        mrapi().CreateInstance.assert_called_once()
539 f2080d16 Christos Stavrakakis
        vm = VirtualMachine.objects.get()
540 9dcfad23 Christos Stavrakakis
        # The VM has not been deleted
541 9dcfad23 Christos Stavrakakis
        self.assertFalse(vm.deleted)
542 9dcfad23 Christos Stavrakakis
        # but is in "ERROR" operstate
543 9dcfad23 Christos Stavrakakis
        self.assertEqual(vm.operstate, "ERROR")
544 f2080d16 Christos Stavrakakis
545 039e3e61 Christos Stavrakakis
546 039e3e61 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
547 a26e5a4d Georgios D. Tsoukalas
class ServerDestroyAPITest(ComputeAPITest):
548 039e3e61 Christos Stavrakakis
    def test_delete_server(self, mrapi):
549 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
550 41a7fae7 Christos Stavrakakis
        mrapi().DeleteInstance.return_value = 12
551 2cd55da6 Christos Stavrakakis
        response = self.mydelete('servers/%d' % vm.id, vm.userid)
552 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 204)
553 039e3e61 Christos Stavrakakis
        mrapi().DeleteInstance.assert_called_once()
554 039e3e61 Christos Stavrakakis
555 039e3e61 Christos Stavrakakis
    def test_non_existing_delete_server(self, mrapi):
556 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
557 a26e5a4d Georgios D. Tsoukalas
        response = self.mydelete('servers/%d' % 42, vm.userid)
558 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
559 039e3e61 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
560 039e3e61 Christos Stavrakakis
561 039e3e61 Christos Stavrakakis
562 a26e5a4d Georgios D. Tsoukalas
class ServerMetadataAPITest(ComputeAPITest):
563 039e3e61 Christos Stavrakakis
    def setUp(self):
564 039e3e61 Christos Stavrakakis
        self.vm = mfactory.VirtualMachineFactory()
565 039e3e61 Christos Stavrakakis
        self.metadata = mfactory.VirtualMachineMetadataFactory(vm=self.vm)
566 a26e5a4d Georgios D. Tsoukalas
        super(ServerMetadataAPITest, self).setUp()
567 039e3e61 Christos Stavrakakis
568 039e3e61 Christos Stavrakakis
    def test_get_metadata(self):
569 039e3e61 Christos Stavrakakis
        vm = self.vm
570 039e3e61 Christos Stavrakakis
        create_meta = lambda: mfactory.VirtualMachineMetadataFactory(vm=vm)
571 039e3e61 Christos Stavrakakis
        metadata = [create_meta(), create_meta(), create_meta()]
572 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata' % vm.id, vm.userid)
573 039e3e61 Christos Stavrakakis
        self.assertTrue(response.status_code in [200, 203])
574 2d04422f Christos Stavrakakis
        api_metadata = json.loads(response.content)['metadata']
575 039e3e61 Christos Stavrakakis
        self.assertEqual(len(api_metadata), len(metadata) + 1)
576 039e3e61 Christos Stavrakakis
        for db_m in metadata:
577 039e3e61 Christos Stavrakakis
            self.assertEqual(api_metadata[db_m.meta_key], db_m.meta_value)
578 039e3e61 Christos Stavrakakis
579 e368ad39 Christos Stavrakakis
        request = {
580 e368ad39 Christos Stavrakakis
            'metadata': {
581 e368ad39 Christos Stavrakakis
                'foo': 'bar'
582 e368ad39 Christos Stavrakakis
            },
583 e368ad39 Christos Stavrakakis
            metadata[0].meta_key: 'bar2'
584 e368ad39 Christos Stavrakakis
        }
585 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/metadata' % vm.id,
586 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
587 039e3e61 Christos Stavrakakis
        metadata2 = VirtualMachineMetadata.objects.filter(vm=vm)
588 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata' % vm.id, vm.userid)
589 039e3e61 Christos Stavrakakis
        self.assertTrue(response.status_code in [200, 203])
590 2d04422f Christos Stavrakakis
        api_metadata2 = json.loads(response.content)['metadata']
591 039e3e61 Christos Stavrakakis
        self.assertTrue('foo' in api_metadata2.keys())
592 039e3e61 Christos Stavrakakis
        self.assertTrue(api_metadata2[metadata[0].meta_key], 'bar2')
593 039e3e61 Christos Stavrakakis
        self.assertEqual(len(api_metadata2), len(metadata2))
594 039e3e61 Christos Stavrakakis
        for db_m in metadata2:
595 039e3e61 Christos Stavrakakis
            self.assertEqual(api_metadata2[db_m.meta_key], db_m.meta_value)
596 039e3e61 Christos Stavrakakis
597 039e3e61 Christos Stavrakakis
        # Create new meta
598 039e3e61 Christos Stavrakakis
        request = {'meta': {'foo2': 'bar2'}}
599 a26e5a4d Georgios D. Tsoukalas
        response = self.myput('servers/%d/metadata/foo2' % vm.id,
600 a26e5a4d Georgios D. Tsoukalas
                              vm.userid, json.dumps(request), 'json')
601 039e3e61 Christos Stavrakakis
602 039e3e61 Christos Stavrakakis
        # Get the new meta
603 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid)
604 039e3e61 Christos Stavrakakis
        meta = json.loads(response.content)['meta']
605 039e3e61 Christos Stavrakakis
        self.assertEqual(meta['foo2'], 'bar2')
606 039e3e61 Christos Stavrakakis
607 039e3e61 Christos Stavrakakis
        # Delete the new meta
608 a26e5a4d Georgios D. Tsoukalas
        response = self.mydelete('servers/%d/metadata/foo2' % vm.id, vm.userid)
609 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 204)
610 039e3e61 Christos Stavrakakis
611 039e3e61 Christos Stavrakakis
        # Try to get the deleted meta: should raise 404
612 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid)
613 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 404)
614 039e3e61 Christos Stavrakakis
615 039e3e61 Christos Stavrakakis
    def test_invalid_metadata(self):
616 039e3e61 Christos Stavrakakis
        vm = self.vm
617 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/metadata' % vm.id, vm.userid)
618 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
619 039e3e61 Christos Stavrakakis
        self.assertEqual(len(vm.metadata.all()), 1)
620 039e3e61 Christos Stavrakakis
621 039e3e61 Christos Stavrakakis
    def test_invalid_metadata_server(self):
622 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/42/metadata', 'user')
623 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
624 039e3e61 Christos Stavrakakis
625 039e3e61 Christos Stavrakakis
    def test_get_meta_invalid_key(self):
626 039e3e61 Christos Stavrakakis
        vm = self.vm
627 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid)
628 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
629 039e3e61 Christos Stavrakakis
630 039e3e61 Christos Stavrakakis
631 039e3e61 Christos Stavrakakis
@patch('synnefo.api.util.get_image')
632 039e3e61 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
633 a26e5a4d Georgios D. Tsoukalas
class ServerActionAPITest(ComputeAPITest):
634 039e3e61 Christos Stavrakakis
    def test_actions(self, mrapi, mimage):
635 039e3e61 Christos Stavrakakis
        actions = ['start', 'shutdown', 'reboot']
636 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
637 039e3e61 Christos Stavrakakis
        vm.operstate = "STOPPED"
638 039e3e61 Christos Stavrakakis
        vm.save()
639 41a7fae7 Christos Stavrakakis
        mrapi().StartupInstance.return_value = 0
640 41a7fae7 Christos Stavrakakis
        mrapi().ShutdownInstance.return_value = 1
641 41a7fae7 Christos Stavrakakis
        mrapi().RebootInstance.return_value = 2
642 41a7fae7 Christos Stavrakakis
        for jobId, action in enumerate(actions):
643 41a7fae7 Christos Stavrakakis
            if action in ["shutdown", "reboot"]:
644 41a7fae7 Christos Stavrakakis
                vm.operstate = "STARTED"
645 41a7fae7 Christos Stavrakakis
            else:
646 41a7fae7 Christos Stavrakakis
                vm.operstate = "STOPPED"
647 41a7fae7 Christos Stavrakakis
            vm.task = None
648 41a7fae7 Christos Stavrakakis
            vm.task_job_id = None
649 41a7fae7 Christos Stavrakakis
            vm.save()
650 039e3e61 Christos Stavrakakis
            val = {'type': 'HARD'} if action == 'reboot' else {}
651 039e3e61 Christos Stavrakakis
            request = {action: val}
652 a26e5a4d Georgios D. Tsoukalas
            response = self.mypost('servers/%d/action' % vm.id,
653 a26e5a4d Georgios D. Tsoukalas
                                   vm.userid, json.dumps(request), 'json')
654 039e3e61 Christos Stavrakakis
            self.assertEqual(response.status_code, 202)
655 039e3e61 Christos Stavrakakis
            if action == 'shutdown':
656 41a7fae7 Christos Stavrakakis
                self.assertEqual(VirtualMachine.objects.get(id=vm.id).task,
657 039e3e61 Christos Stavrakakis
                                 "STOP")
658 039e3e61 Christos Stavrakakis
            else:
659 41a7fae7 Christos Stavrakakis
                self.assertEqual(VirtualMachine.objects.get(id=vm.id).task,
660 039e3e61 Christos Stavrakakis
                                 action.upper())
661 41a7fae7 Christos Stavrakakis
            self.assertEqual(VirtualMachine.objects.get(id=vm.id).task_job_id,
662 41a7fae7 Christos Stavrakakis
                             jobId)
663 039e3e61 Christos Stavrakakis
664 039e3e61 Christos Stavrakakis
    def test_action_in_building_vm(self, mrapi, mimage):
665 039e3e61 Christos Stavrakakis
        """Test building in progress"""
666 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate="BUILD")
667 41a7fae7 Christos Stavrakakis
        request = {'start': {}}
668 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
669 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers/%d/action' % vm.id,
670 41a7fae7 Christos Stavrakakis
                                   vm.userid, json.dumps(request), 'json')
671 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 409)
672 039e3e61 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
673 039e3e61 Christos Stavrakakis
674 039e3e61 Christos Stavrakakis
    def test_destroy_build_vm(self, mrapi, mimage):
675 039e3e61 Christos Stavrakakis
        """Test building in progress"""
676 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
677 41a7fae7 Christos Stavrakakis
        mrapi().DeleteInstance.return_value = 2
678 2cd55da6 Christos Stavrakakis
        response = self.mydelete('servers/%d' % vm.id,
679 41a7fae7 Christos Stavrakakis
                                 vm.userid)
680 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
681 039e3e61 Christos Stavrakakis
        mrapi().RemoveInstance.assert_called_once()
682 039e3e61 Christos Stavrakakis
683 039e3e61 Christos Stavrakakis
    def test_firewall(self, mrapi, mimage):
684 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
685 039e3e61 Christos Stavrakakis
        vm.operstate = "STOPPED"
686 039e3e61 Christos Stavrakakis
        vm.save()
687 039e3e61 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'PROTECTED'}}
688 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
689 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, json.dumps(request), 'json')
690 d0545590 Christos Stavrakakis
        self.assertBadRequest(response)
691 d0545590 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'PROTECTED', "nic": "10"}}
692 d0545590 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
693 d0545590 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
694 d0545590 Christos Stavrakakis
        self.assertItemNotFound(response)
695 d0545590 Christos Stavrakakis
        nic = mfactory.NetworkInterfaceFactory(machine=vm)
696 d0545590 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'PROTECTED', "nic": nic.id}}
697 d0545590 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
698 d0545590 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
699 d0545590 Christos Stavrakakis
        self.assertSuccess(response)
700 039e3e61 Christos Stavrakakis
        mrapi().ModifyInstance.assert_called_once()
701 039e3e61 Christos Stavrakakis
702 039e3e61 Christos Stavrakakis
    def test_unsupported_firewall(self, mrapi, mimage):
703 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
704 039e3e61 Christos Stavrakakis
        vm.operstate = "STOPPED"
705 039e3e61 Christos Stavrakakis
        vm.save()
706 039e3e61 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'FOO'}}
707 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
708 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, json.dumps(request), 'json')
709 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
710 039e3e61 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
711 039e3e61 Christos Stavrakakis
712 1af851fd Christos Stavrakakis
    def test_resize_vm(self, mrapi, mimage):
713 1af851fd Christos Stavrakakis
        flavor = mfactory.FlavorFactory(cpu=1, ram=1024)
714 1af851fd Christos Stavrakakis
        # Check building VM
715 1af851fd Christos Stavrakakis
        vm = self.get_vm(flavor=flavor, operstate="BUILD")
716 1af851fd Christos Stavrakakis
        request = {'resize': {'flavorRef': flavor.id}}
717 2cd55da6 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
718 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
719 1af851fd Christos Stavrakakis
        self.assertFault(response, 409, "buildInProgress")
720 1af851fd Christos Stavrakakis
        # Check same Flavor
721 1af851fd Christos Stavrakakis
        vm = self.get_vm(flavor=flavor, operstate="STOPPED")
722 1af851fd Christos Stavrakakis
        request = {'resize': {'flavorRef': flavor.id}}
723 2cd55da6 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
724 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
725 41a7fae7 Christos Stavrakakis
        self.assertBadRequest(response)
726 1af851fd Christos Stavrakakis
        # Check flavor with different disk
727 1af851fd Christos Stavrakakis
        flavor2 = mfactory.FlavorFactory(disk=1024)
728 1af851fd Christos Stavrakakis
        flavor3 = mfactory.FlavorFactory(disk=2048)
729 1af851fd Christos Stavrakakis
        vm = self.get_vm(flavor=flavor2, operstate="STOPPED")
730 1af851fd Christos Stavrakakis
        request = {'resize': {'flavorRef': flavor3.id}}
731 2cd55da6 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
732 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
733 1af851fd Christos Stavrakakis
        self.assertBadRequest(response)
734 1af851fd Christos Stavrakakis
        flavor2 = mfactory.FlavorFactory(disk_template="foo")
735 1af851fd Christos Stavrakakis
        flavor3 = mfactory.FlavorFactory(disk_template="baz")
736 1af851fd Christos Stavrakakis
        vm = self.get_vm(flavor=flavor2, operstate="STOPPED")
737 1af851fd Christos Stavrakakis
        request = {'resize': {'flavorRef': flavor3.id}}
738 2cd55da6 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
739 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
740 1af851fd Christos Stavrakakis
        self.assertBadRequest(response)
741 1af851fd Christos Stavrakakis
        # Check success
742 1af851fd Christos Stavrakakis
        vm = self.get_vm(flavor=flavor, operstate="STOPPED")
743 1af851fd Christos Stavrakakis
        flavor4 = mfactory.FlavorFactory(disk_template=flavor.disk_template,
744 1af851fd Christos Stavrakakis
                                         disk=flavor.disk,
745 1af851fd Christos Stavrakakis
                                         cpu=4, ram=2048)
746 1af851fd Christos Stavrakakis
        request = {'resize': {'flavorRef': flavor4.id}}
747 1af851fd Christos Stavrakakis
        mrapi().ModifyInstance.return_value = 42
748 2cd55da6 Christos Stavrakakis
        response = self.mypost('servers/%d/action' % vm.id,
749 e368ad39 Christos Stavrakakis
                               vm.userid, json.dumps(request), 'json')
750 1af851fd Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
751 1af851fd Christos Stavrakakis
        vm = VirtualMachine.objects.get(id=vm.id)
752 41a7fae7 Christos Stavrakakis
        self.assertEqual(vm.task_job_id, 42)
753 1af851fd Christos Stavrakakis
        name, args, kwargs = mrapi().ModifyInstance.mock_calls[0]
754 1af851fd Christos Stavrakakis
        self.assertEqual(kwargs["beparams"]["vcpus"], 4)
755 1af851fd Christos Stavrakakis
        self.assertEqual(kwargs["beparams"]["minmem"], 2048)
756 1af851fd Christos Stavrakakis
        self.assertEqual(kwargs["beparams"]["maxmem"], 2048)
757 1af851fd Christos Stavrakakis
758 41a7fae7 Christos Stavrakakis
    def test_action_on_resizing_vm(self, mrapi, mimage):
759 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
760 41a7fae7 Christos Stavrakakis
        vm.operstate = "RESIZE"
761 41a7fae7 Christos Stavrakakis
        vm.save()
762 41a7fae7 Christos Stavrakakis
        for action in VirtualMachine.ACTIONS:
763 41a7fae7 Christos Stavrakakis
            request = {action[0]: ""}
764 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers/%d/action' % vm.id,
765 e368ad39 Christos Stavrakakis
                                   vm.userid, json.dumps(request), 'json')
766 41a7fae7 Christos Stavrakakis
            self.assertBadRequest(response)
767 41a7fae7 Christos Stavrakakis
        # however you can destroy
768 41a7fae7 Christos Stavrakakis
        mrapi().DeleteInstance.return_value = 42
769 2cd55da6 Christos Stavrakakis
        response = self.mydelete('servers/%d' % vm.id,
770 2cd55da6 Christos Stavrakakis
                                 vm.userid)
771 41a7fae7 Christos Stavrakakis
        self.assertSuccess(response)
772 41a7fae7 Christos Stavrakakis
773 1af851fd Christos Stavrakakis
    def get_vm(self, flavor, operstate):
774 1af851fd Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(flavor=flavor)
775 1af851fd Christos Stavrakakis
        vm.operstate = operstate
776 1af851fd Christos Stavrakakis
        vm.backendjobstatus = "success"
777 1af851fd Christos Stavrakakis
        vm.save()
778 1af851fd Christos Stavrakakis
        return vm
779 1af851fd Christos Stavrakakis
780 039e3e61 Christos Stavrakakis
781 a26e5a4d Georgios D. Tsoukalas
class ServerVNCConsole(ComputeAPITest):
782 039e3e61 Christos Stavrakakis
    def test_not_active_server(self):
783 039e3e61 Christos Stavrakakis
        """Test console req for not ACTIVE server returns badRequest"""
784 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate="BUILD")
785 039e3e61 Christos Stavrakakis
        data = json.dumps({'console': {'type': 'vnc'}})
786 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
787 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, data, 'json')
788 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
789 039e3e61 Christos Stavrakakis
790 039e3e61 Christos Stavrakakis
    def test_active_server(self):
791 039e3e61 Christos Stavrakakis
        """Test console req for ACTIVE server"""
792 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
793 039e3e61 Christos Stavrakakis
        vm.operstate = 'STARTED'
794 039e3e61 Christos Stavrakakis
        vm.save()
795 039e3e61 Christos Stavrakakis
796 039e3e61 Christos Stavrakakis
        data = json.dumps({'console': {'type': 'vnc'}})
797 41a7fae7 Christos Stavrakakis
        with override_settings(settings, TEST=True):
798 2cd55da6 Christos Stavrakakis
            response = self.mypost('servers/%d/action' % vm.id,
799 41a7fae7 Christos Stavrakakis
                                   vm.userid, data, 'json')
800 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 200)
801 039e3e61 Christos Stavrakakis
        reply = json.loads(response.content)
802 039e3e61 Christos Stavrakakis
        self.assertEqual(reply.keys(), ['console'])
803 039e3e61 Christos Stavrakakis
        console = reply['console']
804 039e3e61 Christos Stavrakakis
        self.assertEqual(console['type'], 'vnc')
805 039e3e61 Christos Stavrakakis
        self.assertEqual(set(console.keys()),
806 039e3e61 Christos Stavrakakis
                         set(['type', 'host', 'port', 'password']))
807 039e3e61 Christos Stavrakakis
808 039e3e61 Christos Stavrakakis
    def test_wrong_console_type(self):
809 039e3e61 Christos Stavrakakis
        """Test console req for ACTIVE server"""
810 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
811 039e3e61 Christos Stavrakakis
        vm.operstate = 'STARTED'
812 039e3e61 Christos Stavrakakis
        vm.save()
813 039e3e61 Christos Stavrakakis
814 039e3e61 Christos Stavrakakis
        data = json.dumps({'console': {'type': 'foo'}})
815 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
816 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, data, 'json')
817 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)