Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / util.py @ 58194535

History | View | Annotate | Download (15.8 kB)

1 6ef51e9f Giorgos Verigakis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 d1387ed7 Christodoulos Psaltis
#
3 adee02b8 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
4 adee02b8 Giorgos Verigakis
# without modification, are permitted provided that the following
5 adee02b8 Giorgos Verigakis
# conditions are met:
6 d1387ed7 Christodoulos Psaltis
#
7 adee02b8 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
8 adee02b8 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
9 adee02b8 Giorgos Verigakis
#      disclaimer.
10 d1387ed7 Christodoulos Psaltis
#
11 adee02b8 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
12 adee02b8 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
13 adee02b8 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
14 adee02b8 Giorgos Verigakis
#      provided with the distribution.
15 d1387ed7 Christodoulos Psaltis
#
16 adee02b8 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 adee02b8 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 adee02b8 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 adee02b8 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 adee02b8 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 adee02b8 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 adee02b8 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 adee02b8 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 adee02b8 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 adee02b8 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 adee02b8 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 adee02b8 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
28 d1387ed7 Christodoulos Psaltis
#
29 adee02b8 Giorgos Verigakis
# The views and conclusions contained in the software and
30 adee02b8 Giorgos Verigakis
# documentation are those of the authors and should not be
31 adee02b8 Giorgos Verigakis
# interpreted as representing official policies, either expressed
32 adee02b8 Giorgos Verigakis
# or implied, of GRNET S.A.
33 7e2f9d4b Giorgos Verigakis
34 bd16bf3e Stratos Psomadakis
from base64 import urlsafe_b64encode, b64decode
35 bd16bf3e Stratos Psomadakis
from urllib import quote
36 c738c935 Giorgos Verigakis
from hashlib import sha256
37 2035039b Giorgos Verigakis
from logging import getLogger
38 d8e50a39 Giorgos Verigakis
from random import choice
39 dca2a31f Giorgos Verigakis
from string import digits, lowercase, uppercase
40 2035039b Giorgos Verigakis
41 c738c935 Giorgos Verigakis
from Crypto.Cipher import AES
42 529178b1 Giorgos Verigakis
43 d8e50a39 Giorgos Verigakis
from django.conf import settings
44 7e2f9d4b Giorgos Verigakis
from django.http import HttpResponse
45 7e2f9d4b Giorgos Verigakis
from django.template.loader import render_to_string
46 29a59bc1 Giorgos Verigakis
from django.utils import simplejson as json
47 d3406fbc Christos Stavrakakis
from django.db.models import Q
48 7e2f9d4b Giorgos Verigakis
49 bd40abfa Christos Stavrakakis
from snf_django.lib.api import faults
50 6ef51e9f Giorgos Verigakis
from synnefo.db.models import (Flavor, VirtualMachine, VirtualMachineMetadata,
51 a1713485 Marios Kogias
                               Network, NetworkInterface, SecurityGroup,
52 a1713485 Marios Kogias
                               BridgePoolTable, MacPrefixPoolTable, IPAddress,
53 495e2be8 Christos Stavrakakis
                               IPPoolTable)
54 b3fd98ae Christos Stavrakakis
from synnefo.plankton.utils import image_backend
55 9e98ba3c Giorgos Verigakis
56 1b696c26 Christos Stavrakakis
from synnefo.cyclades_settings import cyclades_services, BASE_HOST
57 1b696c26 Christos Stavrakakis
from synnefo.lib.services import get_service_path
58 1b696c26 Christos Stavrakakis
from synnefo.lib import join_urls
59 1b696c26 Christos Stavrakakis
60 1b696c26 Christos Stavrakakis
COMPUTE_URL = \
61 1b696c26 Christos Stavrakakis
    join_urls(BASE_HOST,
62 1b696c26 Christos Stavrakakis
              get_service_path(cyclades_services, "compute", version="v2.0"))
63 1b696c26 Christos Stavrakakis
SERVERS_URL = join_urls(COMPUTE_URL, "servers/")
64 1b696c26 Christos Stavrakakis
FLAVORS_URL = join_urls(COMPUTE_URL, "flavors/")
65 1b696c26 Christos Stavrakakis
IMAGES_URL = join_urls(COMPUTE_URL, "images/")
66 1b696c26 Christos Stavrakakis
PLANKTON_URL = \
67 1b696c26 Christos Stavrakakis
    join_urls(BASE_HOST,
68 1b696c26 Christos Stavrakakis
              get_service_path(cyclades_services, "image", version="v1.0"))
69 1b696c26 Christos Stavrakakis
IMAGES_PLANKTON_URL = join_urls(PLANKTON_URL, "images/")
70 1b696c26 Christos Stavrakakis
71 cdd6fc06 Christos Stavrakakis
NETWORK_URL = \
72 cdd6fc06 Christos Stavrakakis
    join_urls(BASE_HOST,
73 cdd6fc06 Christos Stavrakakis
              get_service_path(cyclades_services, "network", version="v2.0"))
74 cdd6fc06 Christos Stavrakakis
NETWORKS_URL = join_urls(NETWORK_URL, "networks/")
75 cdd6fc06 Christos Stavrakakis
PORTS_URL = join_urls(NETWORK_URL, "ports/")
76 cdd6fc06 Christos Stavrakakis
SUBNETS_URL = join_urls(NETWORK_URL, "subnets/")
77 cdd6fc06 Christos Stavrakakis
FLOATING_IPS_URL = join_urls(NETWORK_URL, "floatingips/")
78 cdd6fc06 Christos Stavrakakis
79 c172f4ab Christos Stavrakakis
PITHOSMAP_PREFIX = "pithosmap://"
80 9e98ba3c Giorgos Verigakis
81 9e98ba3c Giorgos Verigakis
log = getLogger('synnefo.api')
82 9e98ba3c Giorgos Verigakis
83 7e2f9d4b Giorgos Verigakis
84 dca2a31f Giorgos Verigakis
def random_password():
85 dca2a31f Giorgos Verigakis
    """Generates a random password
86 ce55f211 Kostas Papadimitriou

87 62eac5a6 Giorgos Verigakis
    We generate a windows compliant password: it must contain at least
88 dca2a31f Giorgos Verigakis
    one charachter from each of the groups: upper case, lower case, digits.
89 dca2a31f Giorgos Verigakis
    """
90 ce55f211 Kostas Papadimitriou
91 dca2a31f Giorgos Verigakis
    pool = lowercase + uppercase + digits
92 dca2a31f Giorgos Verigakis
    lowerset = set(lowercase)
93 dca2a31f Giorgos Verigakis
    upperset = set(uppercase)
94 dca2a31f Giorgos Verigakis
    digitset = set(digits)
95 dca2a31f Giorgos Verigakis
    length = 10
96 ce55f211 Kostas Papadimitriou
97 62eac5a6 Giorgos Verigakis
    password = ''.join(choice(pool) for i in range(length - 2))
98 ce55f211 Kostas Papadimitriou
99 62eac5a6 Giorgos Verigakis
    # Make sure the password is compliant
100 62eac5a6 Giorgos Verigakis
    chars = set(password)
101 62eac5a6 Giorgos Verigakis
    if not chars & lowerset:
102 62eac5a6 Giorgos Verigakis
        password += choice(lowercase)
103 62eac5a6 Giorgos Verigakis
    if not chars & upperset:
104 62eac5a6 Giorgos Verigakis
        password += choice(uppercase)
105 62eac5a6 Giorgos Verigakis
    if not chars & digitset:
106 62eac5a6 Giorgos Verigakis
        password += choice(digits)
107 ce55f211 Kostas Papadimitriou
108 62eac5a6 Giorgos Verigakis
    # Pad if necessary to reach required length
109 62eac5a6 Giorgos Verigakis
    password += ''.join(choice(pool) for i in range(length - len(password)))
110 ce55f211 Kostas Papadimitriou
111 dca2a31f Giorgos Verigakis
    return password
112 dca2a31f Giorgos Verigakis
113 d8e50a39 Giorgos Verigakis
114 c738c935 Giorgos Verigakis
def zeropad(s):
115 c738c935 Giorgos Verigakis
    """Add zeros at the end of a string in order to make its length
116 c738c935 Giorgos Verigakis
       a multiple of 16."""
117 d1387ed7 Christodoulos Psaltis
118 c738c935 Giorgos Verigakis
    npad = 16 - len(s) % 16
119 c738c935 Giorgos Verigakis
    return s + '\x00' * npad
120 c738c935 Giorgos Verigakis
121 a08e4270 Vangelis Koukis
122 bd16bf3e Stratos Psomadakis
def stats_encrypt(plaintext):
123 c738c935 Giorgos Verigakis
    # Make sure key is 32 bytes long
124 bd16bf3e Stratos Psomadakis
    key = sha256(settings.CYCLADES_STATS_SECRET_KEY).digest()
125 d1387ed7 Christodoulos Psaltis
126 c738c935 Giorgos Verigakis
    aes = AES.new(key)
127 c738c935 Giorgos Verigakis
    enc = aes.encrypt(zeropad(plaintext))
128 bd16bf3e Stratos Psomadakis
    return quote(urlsafe_b64encode(enc))
129 c738c935 Giorgos Verigakis
130 7e2f9d4b Giorgos Verigakis
131 7f2dbcad Christos Stavrakakis
def get_vm(server_id, user_id, for_update=False, non_deleted=False,
132 b3a43976 Christos Stavrakakis
           non_suspended=False, prefetch_related=None):
133 e221ade2 Christos Stavrakakis
    """Find a VirtualMachine instance based on ID and owner."""
134 aa197ee4 Vangelis Koukis
135 d8e50a39 Giorgos Verigakis
    try:
136 d8e50a39 Giorgos Verigakis
        server_id = int(server_id)
137 7f2dbcad Christos Stavrakakis
        servers = VirtualMachine.objects
138 7f2dbcad Christos Stavrakakis
        if for_update:
139 7f2dbcad Christos Stavrakakis
            servers = servers.select_for_update()
140 b3a43976 Christos Stavrakakis
        if prefetch_related is not None:
141 b3a43976 Christos Stavrakakis
            servers = servers.prefetch_related(prefetch_related)
142 7f2dbcad Christos Stavrakakis
        vm = servers.get(id=server_id, userid=user_id)
143 e221ade2 Christos Stavrakakis
        if non_deleted and vm.deleted:
144 5b0832fc Christos Stavrakakis
            raise faults.BadRequest("Server has been deleted.")
145 e221ade2 Christos Stavrakakis
        if non_suspended and vm.suspended:
146 bd40abfa Christos Stavrakakis
            raise faults.Forbidden("Administratively Suspended VM")
147 3a522cff Christos Stavrakakis
        return vm
148 406968dc Dionysis Grigoropoulos
    except (ValueError, TypeError):
149 bd40abfa Christos Stavrakakis
        raise faults.BadRequest('Invalid server ID.')
150 d8e50a39 Giorgos Verigakis
    except VirtualMachine.DoesNotExist:
151 bd40abfa Christos Stavrakakis
        raise faults.ItemNotFound('Server not found.')
152 d8e50a39 Giorgos Verigakis
153 7f2dbcad Christos Stavrakakis
154 40777cc8 Giorgos Verigakis
def get_vm_meta(vm, key):
155 d8e50a39 Giorgos Verigakis
    """Return a VirtualMachineMetadata instance or raise ItemNotFound."""
156 aa197ee4 Vangelis Koukis
157 d8e50a39 Giorgos Verigakis
    try:
158 40777cc8 Giorgos Verigakis
        return VirtualMachineMetadata.objects.get(meta_key=key, vm=vm)
159 d8e50a39 Giorgos Verigakis
    except VirtualMachineMetadata.DoesNotExist:
160 bd40abfa Christos Stavrakakis
        raise faults.ItemNotFound('Metadata key not found.')
161 d8e50a39 Giorgos Verigakis
162 a08e4270 Vangelis Koukis
163 6ef51e9f Giorgos Verigakis
def get_image(image_id, user_id):
164 d8e50a39 Giorgos Verigakis
    """Return an Image instance or raise ItemNotFound."""
165 aa197ee4 Vangelis Koukis
166 b3fd98ae Christos Stavrakakis
    with image_backend(user_id) as backend:
167 cda71050 Christos Stavrakakis
        return backend.get_image(image_id)
168 3a9b3cde Giorgos Verigakis
169 a08e4270 Vangelis Koukis
170 dca7553e Christos Stavrakakis
def get_image_dict(image_id, user_id):
171 dca7553e Christos Stavrakakis
    image = {}
172 dca7553e Christos Stavrakakis
    img = get_image(image_id, user_id)
173 bcd80cd9 Christos Stavrakakis
    image["id"] = img["id"]
174 bcd80cd9 Christos Stavrakakis
    image["name"] = img["name"]
175 c172f4ab Christos Stavrakakis
    image["format"] = img["disk_format"]
176 c172f4ab Christos Stavrakakis
    image["location"] = img["location"]
177 f518210b Christos Stavrakakis
    image["is_snapshot"] = img["is_snapshot"]
178 c172f4ab Christos Stavrakakis
    size = image["size"] = img["size"]
179 e7953d63 Christos Stavrakakis
180 e7953d63 Christos Stavrakakis
    checksum = img["checksum"]
181 e7953d63 Christos Stavrakakis
    if checksum.startswith("archip:"):
182 e7953d63 Christos Stavrakakis
        unprefixed_checksum, _ = checksum.split("archip:")
183 e7953d63 Christos Stavrakakis
        checksum = unprefixed_checksum
184 e7953d63 Christos Stavrakakis
    else:
185 e7953d63 Christos Stavrakakis
        unprefixed_checksum = checksum
186 e7953d63 Christos Stavrakakis
        checksum = "pithos:" + checksum
187 e7953d63 Christos Stavrakakis
188 e7953d63 Christos Stavrakakis
    image["backend_id"] = PITHOSMAP_PREFIX + "/".join([unprefixed_checksum,
189 e7953d63 Christos Stavrakakis
                                                       str(size)])
190 e7953d63 Christos Stavrakakis
    image["checksum"] = checksum
191 c172f4ab Christos Stavrakakis
192 c172f4ab Christos Stavrakakis
    properties = img.get("properties", {})
193 c172f4ab Christos Stavrakakis
    image["metadata"] = dict((key.upper(), val)
194 dca7553e Christos Stavrakakis
                             for key, val in properties.items())
195 c172f4ab Christos Stavrakakis
196 dca7553e Christos Stavrakakis
    return image
197 dca7553e Christos Stavrakakis
198 dca7553e Christos Stavrakakis
199 aa8230bd Christos Stavrakakis
def get_flavor(flavor_id, include_deleted=False):
200 529178b1 Giorgos Verigakis
    """Return a Flavor instance or raise ItemNotFound."""
201 aa197ee4 Vangelis Koukis
202 529178b1 Giorgos Verigakis
    try:
203 529178b1 Giorgos Verigakis
        flavor_id = int(flavor_id)
204 aa8230bd Christos Stavrakakis
        if include_deleted:
205 aa8230bd Christos Stavrakakis
            return Flavor.objects.get(id=flavor_id)
206 aa8230bd Christos Stavrakakis
        else:
207 aa8230bd Christos Stavrakakis
            return Flavor.objects.get(id=flavor_id, deleted=include_deleted)
208 8b7c2fc3 Christos Stavrakakis
    except (ValueError, TypeError):
209 8b7c2fc3 Christos Stavrakakis
        raise faults.BadRequest("Invalid flavor ID '%s'" % flavor_id)
210 8b7c2fc3 Christos Stavrakakis
    except Flavor.DoesNotExist:
211 bd40abfa Christos Stavrakakis
        raise faults.ItemNotFound('Flavor not found.')
212 d8e50a39 Giorgos Verigakis
213 a08e4270 Vangelis Koukis
214 9e8be4fb Christos Stavrakakis
def get_network(network_id, user_id, for_update=False, non_deleted=False):
215 e2ee7808 Giorgos Verigakis
    """Return a Network instance or raise ItemNotFound."""
216 aa197ee4 Vangelis Koukis
217 e2ee7808 Giorgos Verigakis
    try:
218 7fede91e Christos Stavrakakis
        network_id = int(network_id)
219 b7e79bf3 Christos Stavrakakis
        objects = Network.objects
220 d2e73c0c Christos Stavrakakis
        if for_update:
221 d3406fbc Christos Stavrakakis
            objects = objects.select_for_update()
222 9e8be4fb Christos Stavrakakis
        network = objects.get(Q(userid=user_id) | Q(public=True),
223 9e8be4fb Christos Stavrakakis
                              id=network_id)
224 9e8be4fb Christos Stavrakakis
        if non_deleted and network.deleted:
225 f8675683 Christos Stavrakakis
            raise faults.BadRequest("Network has been deleted.")
226 9e8be4fb Christos Stavrakakis
        return network
227 8b7c2fc3 Christos Stavrakakis
    except (ValueError, TypeError):
228 8b7c2fc3 Christos Stavrakakis
        raise faults.BadRequest("Invalid network ID '%s'" % network_id)
229 8b7c2fc3 Christos Stavrakakis
    except Network.DoesNotExist:
230 710b1c43 Christos Stavrakakis
        raise faults.ItemNotFound('Network %s not found.' % network_id)
231 95a213d4 Christos Stavrakakis
232 95a213d4 Christos Stavrakakis
233 95a213d4 Christos Stavrakakis
def get_port(port_id, user_id, for_update=False):
234 0baa1e3d Buildbot
    """
235 95a213d4 Christos Stavrakakis
    Return a NetworkInteface instance or raise ItemNotFound.
236 0baa1e3d Buildbot
    """
237 0baa1e3d Buildbot
    try:
238 09b76b7e Christos Stavrakakis
        objects = NetworkInterface.objects.filter(userid=user_id)
239 593851e0 Buildbot
        if for_update:
240 593851e0 Buildbot
            objects = objects.select_for_update()
241 fae6e5f0 Christos Stavrakakis
        # if (port.device_owner != "vm") and for_update:
242 8d5795b4 Christos Stavrakakis
        #     raise faults.BadRequest('Cannot update non vm port')
243 09b76b7e Christos Stavrakakis
        return objects.get(id=port_id)
244 8b7c2fc3 Christos Stavrakakis
    except (ValueError, TypeError):
245 8b7c2fc3 Christos Stavrakakis
        raise faults.BadRequest("Invalid port ID '%s'" % port_id)
246 8b7c2fc3 Christos Stavrakakis
    except NetworkInterface.DoesNotExist:
247 09b76b7e Christos Stavrakakis
        raise faults.ItemNotFound("Port '%s' not found." % port_id)
248 95a213d4 Christos Stavrakakis
249 0711e5aa Christos Stavrakakis
250 a1713485 Marios Kogias
def get_security_group(sg_id):
251 a1713485 Marios Kogias
    try:
252 a1713485 Marios Kogias
        sg = SecurityGroup.objects.get(id=sg_id)
253 a1713485 Marios Kogias
        return sg
254 a1713485 Marios Kogias
    except (ValueError, SecurityGroup.DoesNotExist):
255 a1713485 Marios Kogias
        raise faults.ItemNotFound("Not valid security group")
256 a08e4270 Vangelis Koukis
257 0711e5aa Christos Stavrakakis
258 710b1c43 Christos Stavrakakis
def get_floating_ip_by_address(userid, address, for_update=False):
259 f8675683 Christos Stavrakakis
    try:
260 326c3ec8 Christos Stavrakakis
        objects = IPAddress.objects
261 f8675683 Christos Stavrakakis
        if for_update:
262 f8675683 Christos Stavrakakis
            objects = objects.select_for_update()
263 710b1c43 Christos Stavrakakis
        return objects.get(userid=userid, floating_ip=True,
264 710b1c43 Christos Stavrakakis
                           address=address, deleted=False)
265 326c3ec8 Christos Stavrakakis
    except IPAddress.DoesNotExist:
266 f8675683 Christos Stavrakakis
        raise faults.ItemNotFound("Floating IP does not exist.")
267 f8675683 Christos Stavrakakis
268 f8675683 Christos Stavrakakis
269 710b1c43 Christos Stavrakakis
def get_floating_ip_by_id(userid, floating_ip_id, for_update=False):
270 710b1c43 Christos Stavrakakis
    try:
271 01def7a4 Dionysis Grigoropoulos
        floating_ip_id = int(floating_ip_id)
272 710b1c43 Christos Stavrakakis
        objects = IPAddress.objects
273 710b1c43 Christos Stavrakakis
        if for_update:
274 710b1c43 Christos Stavrakakis
            objects = objects.select_for_update()
275 d9c36253 Marios Kogias
        return objects.get(id=floating_ip_id, floating_ip=True,
276 0711e5aa Christos Stavrakakis
                           userid=userid, deleted=False)
277 710b1c43 Christos Stavrakakis
    except IPAddress.DoesNotExist:
278 fae6e5f0 Christos Stavrakakis
        raise faults.ItemNotFound("Floating IP with ID %s does not exist." %
279 710b1c43 Christos Stavrakakis
                                  floating_ip_id)
280 01def7a4 Dionysis Grigoropoulos
    except (ValueError, TypeError):
281 01def7a4 Dionysis Grigoropoulos
        raise faults.BadRequest("Invalid Floating IP ID %s" % floating_ip_id)
282 dca7553e Christos Stavrakakis
283 dca7553e Christos Stavrakakis
284 710b1c43 Christos Stavrakakis
def backend_has_free_public_ip(backend):
285 710b1c43 Christos Stavrakakis
    """Check if a backend has a free public IPv4 address."""
286 710b1c43 Christos Stavrakakis
    ip_pool_rows = IPPoolTable.objects.select_for_update()\
287 710b1c43 Christos Stavrakakis
        .filter(subnet__network__public=True)\
288 710b1c43 Christos Stavrakakis
        .filter(subnet__network__drained=False)\
289 710b1c43 Christos Stavrakakis
        .filter(subnet__deleted=False)\
290 710b1c43 Christos Stavrakakis
        .filter(subnet__network__backend_networks__backend=backend)
291 710b1c43 Christos Stavrakakis
    for pool_row in ip_pool_rows:
292 710b1c43 Christos Stavrakakis
        pool = pool_row.pool
293 710b1c43 Christos Stavrakakis
        if pool.empty():
294 710b1c43 Christos Stavrakakis
            continue
295 710b1c43 Christos Stavrakakis
        else:
296 710b1c43 Christos Stavrakakis
            return True
297 710b1c43 Christos Stavrakakis
298 710b1c43 Christos Stavrakakis
299 710b1c43 Christos Stavrakakis
def backend_public_networks(backend):
300 710b1c43 Christos Stavrakakis
    return Network.objects.filter(deleted=False, public=True,
301 710b1c43 Christos Stavrakakis
                                  backend_networks__backend=backend)
302 7fede91e Christos Stavrakakis
303 7fede91e Christos Stavrakakis
304 c988fcca Christos Stavrakakis
def get_vm_nic(vm, nic_id):
305 d0545590 Christos Stavrakakis
    """Get a VMs NIC by its ID."""
306 d44c236b Giorgos Verigakis
    try:
307 7c714455 Christos Stavrakakis
        return vm.nics.get(id=nic_id)
308 d44c236b Giorgos Verigakis
    except NetworkInterface.DoesNotExist:
309 d0545590 Christos Stavrakakis
        raise faults.ItemNotFound("NIC '%s' not found" % nic_id)
310 d44c236b Giorgos Verigakis
311 7fede91e Christos Stavrakakis
312 c988fcca Christos Stavrakakis
def get_nic(nic_id):
313 c988fcca Christos Stavrakakis
    try:
314 c988fcca Christos Stavrakakis
        return NetworkInterface.objects.get(id=nic_id)
315 c988fcca Christos Stavrakakis
    except NetworkInterface.DoesNotExist:
316 c988fcca Christos Stavrakakis
        raise faults.ItemNotFound("NIC '%s' not found" % nic_id)
317 c988fcca Christos Stavrakakis
318 c988fcca Christos Stavrakakis
319 432fc8c3 Giorgos Verigakis
def render_metadata(request, metadata, use_values=False, status=200):
320 432fc8c3 Giorgos Verigakis
    if request.serialization == 'xml':
321 432fc8c3 Giorgos Verigakis
        data = render_to_string('metadata.xml', {'metadata': metadata})
322 432fc8c3 Giorgos Verigakis
    else:
323 b36f78fa Giorgos Verigakis
        if use_values:
324 b36f78fa Giorgos Verigakis
            d = {'metadata': {'values': metadata}}
325 b36f78fa Giorgos Verigakis
        else:
326 b36f78fa Giorgos Verigakis
            d = {'metadata': metadata}
327 432fc8c3 Giorgos Verigakis
        data = json.dumps(d)
328 432fc8c3 Giorgos Verigakis
    return HttpResponse(data, status=status)
329 432fc8c3 Giorgos Verigakis
330 a08e4270 Vangelis Koukis
331 432fc8c3 Giorgos Verigakis
def render_meta(request, meta, status=200):
332 432fc8c3 Giorgos Verigakis
    if request.serialization == 'xml':
333 32e4e343 Christos Stavrakakis
        key, val = meta.items()[0]
334 6ef51e9f Giorgos Verigakis
        data = render_to_string('meta.xml', dict(key=key, val=val))
335 432fc8c3 Giorgos Verigakis
    else:
336 6ef51e9f Giorgos Verigakis
        data = json.dumps(dict(meta=meta))
337 432fc8c3 Giorgos Verigakis
    return HttpResponse(data, status=status)
338 432fc8c3 Giorgos Verigakis
339 a08e4270 Vangelis Koukis
340 dca7553e Christos Stavrakakis
def verify_personality(personality):
341 6ec4694f Christos Stavrakakis
    """Verify that a a list of personalities is well formed"""
342 006c6249 Christos Stavrakakis
    if len(personality) > settings.MAX_PERSONALITY:
343 bd40abfa Christos Stavrakakis
        raise faults.OverLimit("Maximum number of personalities"
344 32e4e343 Christos Stavrakakis
                               " exceeded")
345 dca7553e Christos Stavrakakis
    for p in personality:
346 dca7553e Christos Stavrakakis
        # Verify that personalities are well-formed
347 dca7553e Christos Stavrakakis
        try:
348 dca7553e Christos Stavrakakis
            assert isinstance(p, dict)
349 dca7553e Christos Stavrakakis
            keys = set(p.keys())
350 dca7553e Christos Stavrakakis
            allowed = set(['contents', 'group', 'mode', 'owner', 'path'])
351 dca7553e Christos Stavrakakis
            assert keys.issubset(allowed)
352 dca7553e Christos Stavrakakis
            contents = p['contents']
353 dca7553e Christos Stavrakakis
            if len(contents) > settings.MAX_PERSONALITY_SIZE:
354 dca7553e Christos Stavrakakis
                # No need to decode if contents already exceed limit
355 bd40abfa Christos Stavrakakis
                raise faults.OverLimit("Maximum size of personality exceeded")
356 dca7553e Christos Stavrakakis
            if len(b64decode(contents)) > settings.MAX_PERSONALITY_SIZE:
357 bd40abfa Christos Stavrakakis
                raise faults.OverLimit("Maximum size of personality exceeded")
358 7bbe4333 Ilias Tsitsimpis
        except (AssertionError, TypeError):
359 bd40abfa Christos Stavrakakis
            raise faults.BadRequest("Malformed personality in request")
360 2a599282 Christos Stavrakakis
361 2a599282 Christos Stavrakakis
362 b7d38981 Dimitris Aragiorgis
def values_from_flavor(flavor):
363 b7d38981 Dimitris Aragiorgis
    """Get Ganeti connectivity info from flavor type.
364 b7d38981 Dimitris Aragiorgis

365 b7d38981 Dimitris Aragiorgis
    If link or mac_prefix equals to "pool", then the resources
366 b7d38981 Dimitris Aragiorgis
    are allocated from the corresponding Pools.
367 b7d38981 Dimitris Aragiorgis

368 b7d38981 Dimitris Aragiorgis
    """
369 b7d38981 Dimitris Aragiorgis
    try:
370 b7d38981 Dimitris Aragiorgis
        flavor = Network.FLAVORS[flavor]
371 b7d38981 Dimitris Aragiorgis
    except KeyError:
372 bd40abfa Christos Stavrakakis
        raise faults.BadRequest("Unknown network flavor")
373 b7d38981 Dimitris Aragiorgis
374 b7d38981 Dimitris Aragiorgis
    mode = flavor.get("mode")
375 b7d38981 Dimitris Aragiorgis
376 b7d38981 Dimitris Aragiorgis
    link = flavor.get("link")
377 b7d38981 Dimitris Aragiorgis
    if link == "pool":
378 b7d38981 Dimitris Aragiorgis
        link = allocate_resource("bridge")
379 b7d38981 Dimitris Aragiorgis
380 b7d38981 Dimitris Aragiorgis
    mac_prefix = flavor.get("mac_prefix")
381 b7d38981 Dimitris Aragiorgis
    if mac_prefix == "pool":
382 b7d38981 Dimitris Aragiorgis
        mac_prefix = allocate_resource("mac_prefix")
383 b7d38981 Dimitris Aragiorgis
384 b7d38981 Dimitris Aragiorgis
    tags = flavor.get("tags")
385 b7d38981 Dimitris Aragiorgis
386 b7d38981 Dimitris Aragiorgis
    return mode, link, mac_prefix, tags
387 b7d38981 Dimitris Aragiorgis
388 b7d38981 Dimitris Aragiorgis
389 b7d38981 Dimitris Aragiorgis
def allocate_resource(res_type):
390 b7d38981 Dimitris Aragiorgis
    table = get_pool_table(res_type)
391 b7d38981 Dimitris Aragiorgis
    pool = table.get_pool()
392 b7d38981 Dimitris Aragiorgis
    value = pool.get()
393 b7d38981 Dimitris Aragiorgis
    pool.save()
394 b7d38981 Dimitris Aragiorgis
    return value
395 b7d38981 Dimitris Aragiorgis
396 b7d38981 Dimitris Aragiorgis
397 b7d38981 Dimitris Aragiorgis
def release_resource(res_type, value):
398 b7d38981 Dimitris Aragiorgis
    table = get_pool_table(res_type)
399 b7d38981 Dimitris Aragiorgis
    pool = table.get_pool()
400 b7d38981 Dimitris Aragiorgis
    pool.put(value)
401 b7d38981 Dimitris Aragiorgis
    pool.save()
402 b7d38981 Dimitris Aragiorgis
403 b7d38981 Dimitris Aragiorgis
404 b7d38981 Dimitris Aragiorgis
def get_pool_table(res_type):
405 b7d38981 Dimitris Aragiorgis
    if res_type == "bridge":
406 b7d38981 Dimitris Aragiorgis
        return BridgePoolTable
407 b7d38981 Dimitris Aragiorgis
    elif res_type == "mac_prefix":
408 b7d38981 Dimitris Aragiorgis
        return MacPrefixPoolTable
409 b7d38981 Dimitris Aragiorgis
    else:
410 b7d38981 Dimitris Aragiorgis
        raise Exception("Unknown resource type")
411 55f562a4 Kostas Papadimitriou
412 55f562a4 Kostas Papadimitriou
413 55f562a4 Kostas Papadimitriou
def get_existing_users():
414 55f562a4 Kostas Papadimitriou
    """
415 55f562a4 Kostas Papadimitriou
    Retrieve user ids stored in cyclades user agnostic models.
416 55f562a4 Kostas Papadimitriou
    """
417 55f562a4 Kostas Papadimitriou
    # also check PublicKeys a user with no servers/networks exist
418 b47b110d Kostas Papadimitriou
    from synnefo.userdata.models import PublicKeyPair
419 55f562a4 Kostas Papadimitriou
    from synnefo.db.models import VirtualMachine, Network
420 55f562a4 Kostas Papadimitriou
421 55f562a4 Kostas Papadimitriou
    keypairusernames = PublicKeyPair.objects.filter().values_list('user',
422 e440e835 Christos Stavrakakis
                                                                  flat=True)
423 55f562a4 Kostas Papadimitriou
    serverusernames = VirtualMachine.objects.filter().values_list('userid',
424 e440e835 Christos Stavrakakis
                                                                  flat=True)
425 55f562a4 Kostas Papadimitriou
    networkusernames = Network.objects.filter().values_list('userid',
426 55f562a4 Kostas Papadimitriou
                                                            flat=True)
427 55f562a4 Kostas Papadimitriou
428 e440e835 Christos Stavrakakis
    return set(list(keypairusernames) + list(serverusernames) +
429 e440e835 Christos Stavrakakis
               list(networkusernames))
430 1b696c26 Christos Stavrakakis
431 1b696c26 Christos Stavrakakis
432 1b696c26 Christos Stavrakakis
def vm_to_links(vm_id):
433 73fbaad3 Christos Stavrakakis
    href = join_urls(SERVERS_URL, str(vm_id))
434 73fbaad3 Christos Stavrakakis
    return [{"rel": rel, "href": href} for rel in ("self", "bookmark")]
435 1b696c26 Christos Stavrakakis
436 1b696c26 Christos Stavrakakis
437 1b696c26 Christos Stavrakakis
def network_to_links(network_id):
438 73fbaad3 Christos Stavrakakis
    href = join_urls(NETWORKS_URL, str(network_id))
439 73fbaad3 Christos Stavrakakis
    return [{"rel": rel, "href": href} for rel in ("self", "bookmark")]
440 1b696c26 Christos Stavrakakis
441 1b696c26 Christos Stavrakakis
442 24ea227b Dionysis Grigoropoulos
def subnet_to_links(subnet_id):
443 24ea227b Dionysis Grigoropoulos
    href = join_urls(SUBNETS_URL, str(subnet_id))
444 24ea227b Dionysis Grigoropoulos
    return [{"rel": rel, "href": href} for rel in ("self", "bookmark")]
445 24ea227b Dionysis Grigoropoulos
446 24ea227b Dionysis Grigoropoulos
447 24ea227b Dionysis Grigoropoulos
def port_to_links(port_id):
448 24ea227b Dionysis Grigoropoulos
    href = join_urls(PORTS_URL, str(port_id))
449 24ea227b Dionysis Grigoropoulos
    return [{"rel": rel, "href": href} for rel in ("self", "bookmark")]
450 24ea227b Dionysis Grigoropoulos
451 24ea227b Dionysis Grigoropoulos
452 1b696c26 Christos Stavrakakis
def flavor_to_links(flavor_id):
453 73fbaad3 Christos Stavrakakis
    href = join_urls(FLAVORS_URL, str(flavor_id))
454 73fbaad3 Christos Stavrakakis
    return [{"rel": rel, "href": href} for rel in ("self", "bookmark")]
455 1b696c26 Christos Stavrakakis
456 1b696c26 Christos Stavrakakis
457 1b696c26 Christos Stavrakakis
def image_to_links(image_id):
458 73fbaad3 Christos Stavrakakis
    href = join_urls(IMAGES_URL, str(image_id))
459 73fbaad3 Christos Stavrakakis
    links = [{"rel": rel, "href": href} for rel in ("self", "bookmark")]
460 1b696c26 Christos Stavrakakis
    links.append({"rel": "alternate",
461 73fbaad3 Christos Stavrakakis
                  "href": join_urls(IMAGES_PLANKTON_URL, str(image_id))})
462 1b696c26 Christos Stavrakakis
    return links
463 41a7fae7 Christos Stavrakakis
464 32e4e343 Christos Stavrakakis
465 41a7fae7 Christos Stavrakakis
def start_action(vm, action, jobId):
466 41a7fae7 Christos Stavrakakis
    vm.action = action
467 41a7fae7 Christos Stavrakakis
    vm.backendjobid = jobId
468 41a7fae7 Christos Stavrakakis
    vm.backendopcode = None
469 41a7fae7 Christos Stavrakakis
    vm.backendjobstatus = None
470 41a7fae7 Christos Stavrakakis
    vm.backendlogmsg = None
471 41a7fae7 Christos Stavrakakis
    vm.save()