Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (15.9 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["checksum"] = img["checksum"]
177 c172f4ab Christos Stavrakakis
    image["location"] = img["location"]
178 c172f4ab Christos Stavrakakis
179 c172f4ab Christos Stavrakakis
    checksum = image["checksum"] = img["checksum"]
180 c172f4ab Christos Stavrakakis
    size = image["size"] = img["size"]
181 c172f4ab Christos Stavrakakis
    image["backend_id"] = PITHOSMAP_PREFIX + "/".join([checksum, str(size)])
182 c172f4ab Christos Stavrakakis
183 c172f4ab Christos Stavrakakis
    properties = img.get("properties", {})
184 c172f4ab Christos Stavrakakis
    image["metadata"] = dict((key.upper(), val)
185 dca7553e Christos Stavrakakis
                             for key, val in properties.items())
186 c172f4ab Christos Stavrakakis
187 dca7553e Christos Stavrakakis
    return image
188 dca7553e Christos Stavrakakis
189 dca7553e Christos Stavrakakis
190 aa8230bd Christos Stavrakakis
def get_flavor(flavor_id, include_deleted=False):
191 529178b1 Giorgos Verigakis
    """Return a Flavor instance or raise ItemNotFound."""
192 aa197ee4 Vangelis Koukis
193 529178b1 Giorgos Verigakis
    try:
194 529178b1 Giorgos Verigakis
        flavor_id = int(flavor_id)
195 aa8230bd Christos Stavrakakis
        if include_deleted:
196 aa8230bd Christos Stavrakakis
            return Flavor.objects.get(id=flavor_id)
197 aa8230bd Christos Stavrakakis
        else:
198 aa8230bd Christos Stavrakakis
            return Flavor.objects.get(id=flavor_id, deleted=include_deleted)
199 8b7c2fc3 Christos Stavrakakis
    except (ValueError, TypeError):
200 8b7c2fc3 Christos Stavrakakis
        raise faults.BadRequest("Invalid flavor ID '%s'" % flavor_id)
201 8b7c2fc3 Christos Stavrakakis
    except Flavor.DoesNotExist:
202 bd40abfa Christos Stavrakakis
        raise faults.ItemNotFound('Flavor not found.')
203 d8e50a39 Giorgos Verigakis
204 a08e4270 Vangelis Koukis
205 9dcb5b8a Christos Stavrakakis
def get_flavor_provider(flavor):
206 9dcb5b8a Christos Stavrakakis
    """Extract provider from disk template.
207 9dcb5b8a Christos Stavrakakis

208 9dcb5b8a Christos Stavrakakis
    Provider for `ext` disk_template is encoded in the disk template
209 9dcb5b8a Christos Stavrakakis
    name, which is formed `ext_<provider_name>`. Provider is None
210 9dcb5b8a Christos Stavrakakis
    for all other disk templates.
211 9dcb5b8a Christos Stavrakakis

212 9dcb5b8a Christos Stavrakakis
    """
213 9dcb5b8a Christos Stavrakakis
    disk_template = flavor.disk_template
214 9dcb5b8a Christos Stavrakakis
    provider = None
215 9dcb5b8a Christos Stavrakakis
    if disk_template.startswith("ext"):
216 9dcb5b8a Christos Stavrakakis
        disk_template, provider = disk_template.split("_", 1)
217 9dcb5b8a Christos Stavrakakis
    return disk_template, provider
218 9dcb5b8a Christos Stavrakakis
219 95a213d4 Christos Stavrakakis
220 9e8be4fb Christos Stavrakakis
def get_network(network_id, user_id, for_update=False, non_deleted=False):
221 e2ee7808 Giorgos Verigakis
    """Return a Network instance or raise ItemNotFound."""
222 aa197ee4 Vangelis Koukis
223 e2ee7808 Giorgos Verigakis
    try:
224 7fede91e Christos Stavrakakis
        network_id = int(network_id)
225 b7e79bf3 Christos Stavrakakis
        objects = Network.objects
226 d2e73c0c Christos Stavrakakis
        if for_update:
227 d3406fbc Christos Stavrakakis
            objects = objects.select_for_update()
228 9e8be4fb Christos Stavrakakis
        network = objects.get(Q(userid=user_id) | Q(public=True),
229 9e8be4fb Christos Stavrakakis
                              id=network_id)
230 9e8be4fb Christos Stavrakakis
        if non_deleted and network.deleted:
231 f8675683 Christos Stavrakakis
            raise faults.BadRequest("Network has been deleted.")
232 9e8be4fb Christos Stavrakakis
        return network
233 8b7c2fc3 Christos Stavrakakis
    except (ValueError, TypeError):
234 8b7c2fc3 Christos Stavrakakis
        raise faults.BadRequest("Invalid network ID '%s'" % network_id)
235 8b7c2fc3 Christos Stavrakakis
    except Network.DoesNotExist:
236 710b1c43 Christos Stavrakakis
        raise faults.ItemNotFound('Network %s not found.' % network_id)
237 95a213d4 Christos Stavrakakis
238 95a213d4 Christos Stavrakakis
239 95a213d4 Christos Stavrakakis
def get_port(port_id, user_id, for_update=False):
240 0baa1e3d Buildbot
    """
241 95a213d4 Christos Stavrakakis
    Return a NetworkInteface instance or raise ItemNotFound.
242 0baa1e3d Buildbot
    """
243 0baa1e3d Buildbot
    try:
244 09b76b7e Christos Stavrakakis
        objects = NetworkInterface.objects.filter(userid=user_id)
245 593851e0 Buildbot
        if for_update:
246 593851e0 Buildbot
            objects = objects.select_for_update()
247 fae6e5f0 Christos Stavrakakis
        # if (port.device_owner != "vm") and for_update:
248 8d5795b4 Christos Stavrakakis
        #     raise faults.BadRequest('Cannot update non vm port')
249 09b76b7e Christos Stavrakakis
        return objects.get(id=port_id)
250 8b7c2fc3 Christos Stavrakakis
    except (ValueError, TypeError):
251 8b7c2fc3 Christos Stavrakakis
        raise faults.BadRequest("Invalid port ID '%s'" % port_id)
252 8b7c2fc3 Christos Stavrakakis
    except NetworkInterface.DoesNotExist:
253 09b76b7e Christos Stavrakakis
        raise faults.ItemNotFound("Port '%s' not found." % port_id)
254 95a213d4 Christos Stavrakakis
255 0711e5aa Christos Stavrakakis
256 a1713485 Marios Kogias
def get_security_group(sg_id):
257 a1713485 Marios Kogias
    try:
258 a1713485 Marios Kogias
        sg = SecurityGroup.objects.get(id=sg_id)
259 a1713485 Marios Kogias
        return sg
260 a1713485 Marios Kogias
    except (ValueError, SecurityGroup.DoesNotExist):
261 a1713485 Marios Kogias
        raise faults.ItemNotFound("Not valid security group")
262 a08e4270 Vangelis Koukis
263 0711e5aa Christos Stavrakakis
264 710b1c43 Christos Stavrakakis
def get_floating_ip_by_address(userid, address, for_update=False):
265 f8675683 Christos Stavrakakis
    try:
266 326c3ec8 Christos Stavrakakis
        objects = IPAddress.objects
267 f8675683 Christos Stavrakakis
        if for_update:
268 f8675683 Christos Stavrakakis
            objects = objects.select_for_update()
269 710b1c43 Christos Stavrakakis
        return objects.get(userid=userid, floating_ip=True,
270 710b1c43 Christos Stavrakakis
                           address=address, deleted=False)
271 326c3ec8 Christos Stavrakakis
    except IPAddress.DoesNotExist:
272 f8675683 Christos Stavrakakis
        raise faults.ItemNotFound("Floating IP does not exist.")
273 f8675683 Christos Stavrakakis
274 f8675683 Christos Stavrakakis
275 710b1c43 Christos Stavrakakis
def get_floating_ip_by_id(userid, floating_ip_id, for_update=False):
276 710b1c43 Christos Stavrakakis
    try:
277 01def7a4 Dionysis Grigoropoulos
        floating_ip_id = int(floating_ip_id)
278 710b1c43 Christos Stavrakakis
        objects = IPAddress.objects
279 710b1c43 Christos Stavrakakis
        if for_update:
280 710b1c43 Christos Stavrakakis
            objects = objects.select_for_update()
281 d9c36253 Marios Kogias
        return objects.get(id=floating_ip_id, floating_ip=True,
282 0711e5aa Christos Stavrakakis
                           userid=userid, deleted=False)
283 710b1c43 Christos Stavrakakis
    except IPAddress.DoesNotExist:
284 fae6e5f0 Christos Stavrakakis
        raise faults.ItemNotFound("Floating IP with ID %s does not exist." %
285 710b1c43 Christos Stavrakakis
                                  floating_ip_id)
286 01def7a4 Dionysis Grigoropoulos
    except (ValueError, TypeError):
287 01def7a4 Dionysis Grigoropoulos
        raise faults.BadRequest("Invalid Floating IP ID %s" % floating_ip_id)
288 dca7553e Christos Stavrakakis
289 dca7553e Christos Stavrakakis
290 710b1c43 Christos Stavrakakis
def backend_has_free_public_ip(backend):
291 710b1c43 Christos Stavrakakis
    """Check if a backend has a free public IPv4 address."""
292 710b1c43 Christos Stavrakakis
    ip_pool_rows = IPPoolTable.objects.select_for_update()\
293 710b1c43 Christos Stavrakakis
        .filter(subnet__network__public=True)\
294 710b1c43 Christos Stavrakakis
        .filter(subnet__network__drained=False)\
295 710b1c43 Christos Stavrakakis
        .filter(subnet__deleted=False)\
296 710b1c43 Christos Stavrakakis
        .filter(subnet__network__backend_networks__backend=backend)
297 710b1c43 Christos Stavrakakis
    for pool_row in ip_pool_rows:
298 710b1c43 Christos Stavrakakis
        pool = pool_row.pool
299 710b1c43 Christos Stavrakakis
        if pool.empty():
300 710b1c43 Christos Stavrakakis
            continue
301 710b1c43 Christos Stavrakakis
        else:
302 710b1c43 Christos Stavrakakis
            return True
303 710b1c43 Christos Stavrakakis
304 710b1c43 Christos Stavrakakis
305 710b1c43 Christos Stavrakakis
def backend_public_networks(backend):
306 710b1c43 Christos Stavrakakis
    return Network.objects.filter(deleted=False, public=True,
307 710b1c43 Christos Stavrakakis
                                  backend_networks__backend=backend)
308 7fede91e Christos Stavrakakis
309 7fede91e Christos Stavrakakis
310 c988fcca Christos Stavrakakis
def get_vm_nic(vm, nic_id):
311 d0545590 Christos Stavrakakis
    """Get a VMs NIC by its ID."""
312 d44c236b Giorgos Verigakis
    try:
313 7c714455 Christos Stavrakakis
        return vm.nics.get(id=nic_id)
314 d44c236b Giorgos Verigakis
    except NetworkInterface.DoesNotExist:
315 d0545590 Christos Stavrakakis
        raise faults.ItemNotFound("NIC '%s' not found" % nic_id)
316 d44c236b Giorgos Verigakis
317 7fede91e Christos Stavrakakis
318 c988fcca Christos Stavrakakis
def get_nic(nic_id):
319 c988fcca Christos Stavrakakis
    try:
320 c988fcca Christos Stavrakakis
        return NetworkInterface.objects.get(id=nic_id)
321 c988fcca Christos Stavrakakis
    except NetworkInterface.DoesNotExist:
322 c988fcca Christos Stavrakakis
        raise faults.ItemNotFound("NIC '%s' not found" % nic_id)
323 c988fcca Christos Stavrakakis
324 c988fcca Christos Stavrakakis
325 432fc8c3 Giorgos Verigakis
def render_metadata(request, metadata, use_values=False, status=200):
326 432fc8c3 Giorgos Verigakis
    if request.serialization == 'xml':
327 432fc8c3 Giorgos Verigakis
        data = render_to_string('metadata.xml', {'metadata': metadata})
328 432fc8c3 Giorgos Verigakis
    else:
329 b36f78fa Giorgos Verigakis
        if use_values:
330 b36f78fa Giorgos Verigakis
            d = {'metadata': {'values': metadata}}
331 b36f78fa Giorgos Verigakis
        else:
332 b36f78fa Giorgos Verigakis
            d = {'metadata': metadata}
333 432fc8c3 Giorgos Verigakis
        data = json.dumps(d)
334 432fc8c3 Giorgos Verigakis
    return HttpResponse(data, status=status)
335 432fc8c3 Giorgos Verigakis
336 a08e4270 Vangelis Koukis
337 432fc8c3 Giorgos Verigakis
def render_meta(request, meta, status=200):
338 432fc8c3 Giorgos Verigakis
    if request.serialization == 'xml':
339 32e4e343 Christos Stavrakakis
        key, val = meta.items()[0]
340 6ef51e9f Giorgos Verigakis
        data = render_to_string('meta.xml', dict(key=key, val=val))
341 432fc8c3 Giorgos Verigakis
    else:
342 6ef51e9f Giorgos Verigakis
        data = json.dumps(dict(meta=meta))
343 432fc8c3 Giorgos Verigakis
    return HttpResponse(data, status=status)
344 432fc8c3 Giorgos Verigakis
345 a08e4270 Vangelis Koukis
346 dca7553e Christos Stavrakakis
def verify_personality(personality):
347 6ec4694f Christos Stavrakakis
    """Verify that a a list of personalities is well formed"""
348 006c6249 Christos Stavrakakis
    if len(personality) > settings.MAX_PERSONALITY:
349 bd40abfa Christos Stavrakakis
        raise faults.OverLimit("Maximum number of personalities"
350 32e4e343 Christos Stavrakakis
                               " exceeded")
351 dca7553e Christos Stavrakakis
    for p in personality:
352 dca7553e Christos Stavrakakis
        # Verify that personalities are well-formed
353 dca7553e Christos Stavrakakis
        try:
354 dca7553e Christos Stavrakakis
            assert isinstance(p, dict)
355 dca7553e Christos Stavrakakis
            keys = set(p.keys())
356 dca7553e Christos Stavrakakis
            allowed = set(['contents', 'group', 'mode', 'owner', 'path'])
357 dca7553e Christos Stavrakakis
            assert keys.issubset(allowed)
358 dca7553e Christos Stavrakakis
            contents = p['contents']
359 dca7553e Christos Stavrakakis
            if len(contents) > settings.MAX_PERSONALITY_SIZE:
360 dca7553e Christos Stavrakakis
                # No need to decode if contents already exceed limit
361 bd40abfa Christos Stavrakakis
                raise faults.OverLimit("Maximum size of personality exceeded")
362 dca7553e Christos Stavrakakis
            if len(b64decode(contents)) > settings.MAX_PERSONALITY_SIZE:
363 bd40abfa Christos Stavrakakis
                raise faults.OverLimit("Maximum size of personality exceeded")
364 7bbe4333 Ilias Tsitsimpis
        except (AssertionError, TypeError):
365 bd40abfa Christos Stavrakakis
            raise faults.BadRequest("Malformed personality in request")
366 2a599282 Christos Stavrakakis
367 2a599282 Christos Stavrakakis
368 b7d38981 Dimitris Aragiorgis
def values_from_flavor(flavor):
369 b7d38981 Dimitris Aragiorgis
    """Get Ganeti connectivity info from flavor type.
370 b7d38981 Dimitris Aragiorgis

371 b7d38981 Dimitris Aragiorgis
    If link or mac_prefix equals to "pool", then the resources
372 b7d38981 Dimitris Aragiorgis
    are allocated from the corresponding Pools.
373 b7d38981 Dimitris Aragiorgis

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