Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (15 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 dca7553e Christos Stavrakakis
from base64 import b64encode, b64decode
35 c738c935 Giorgos Verigakis
from hashlib import sha256
36 2035039b Giorgos Verigakis
from logging import getLogger
37 d8e50a39 Giorgos Verigakis
from random import choice
38 dca2a31f Giorgos Verigakis
from string import digits, lowercase, uppercase
39 2035039b Giorgos Verigakis
40 c738c935 Giorgos Verigakis
from Crypto.Cipher import AES
41 529178b1 Giorgos Verigakis
42 d8e50a39 Giorgos Verigakis
from django.conf import settings
43 7e2f9d4b Giorgos Verigakis
from django.http import HttpResponse
44 7e2f9d4b Giorgos Verigakis
from django.template.loader import render_to_string
45 29a59bc1 Giorgos Verigakis
from django.utils import simplejson as json
46 d3406fbc Christos Stavrakakis
from django.db.models import Q
47 7e2f9d4b Giorgos Verigakis
48 bd40abfa Christos Stavrakakis
from snf_django.lib.api import faults
49 6ef51e9f Giorgos Verigakis
from synnefo.db.models import (Flavor, VirtualMachine, VirtualMachineMetadata,
50 7fede91e Christos Stavrakakis
                               Network, BackendNetwork, NetworkInterface,
51 f8675683 Christos Stavrakakis
                               BridgePoolTable, MacPrefixPoolTable, Backend,
52 326c3ec8 Christos Stavrakakis
                               IPAddress)
53 adc46059 Christos Stavrakakis
from synnefo.db.pools import EmptyPool
54 6dd70a5c Christos Stavrakakis
55 b3fd98ae Christos Stavrakakis
from synnefo.plankton.utils import image_backend
56 9e98ba3c Giorgos Verigakis
57 1b696c26 Christos Stavrakakis
from synnefo.cyclades_settings import cyclades_services, BASE_HOST
58 1b696c26 Christos Stavrakakis
from synnefo.lib.services import get_service_path
59 1b696c26 Christos Stavrakakis
from synnefo.lib import join_urls
60 1b696c26 Christos Stavrakakis
61 1b696c26 Christos Stavrakakis
COMPUTE_URL = \
62 1b696c26 Christos Stavrakakis
    join_urls(BASE_HOST,
63 1b696c26 Christos Stavrakakis
              get_service_path(cyclades_services, "compute", version="v2.0"))
64 1b696c26 Christos Stavrakakis
SERVERS_URL = join_urls(COMPUTE_URL, "servers/")
65 1b696c26 Christos Stavrakakis
NETWORKS_URL = join_urls(COMPUTE_URL, "networks/")
66 1b696c26 Christos Stavrakakis
FLAVORS_URL = join_urls(COMPUTE_URL, "flavors/")
67 1b696c26 Christos Stavrakakis
IMAGES_URL = join_urls(COMPUTE_URL, "images/")
68 1b696c26 Christos Stavrakakis
PLANKTON_URL = \
69 1b696c26 Christos Stavrakakis
    join_urls(BASE_HOST,
70 1b696c26 Christos Stavrakakis
              get_service_path(cyclades_services, "image", version="v1.0"))
71 1b696c26 Christos Stavrakakis
IMAGES_PLANKTON_URL = join_urls(PLANKTON_URL, "images/")
72 1b696c26 Christos Stavrakakis
73 c172f4ab Christos Stavrakakis
PITHOSMAP_PREFIX = "pithosmap://"
74 9e98ba3c Giorgos Verigakis
75 9e98ba3c Giorgos Verigakis
log = getLogger('synnefo.api')
76 9e98ba3c Giorgos Verigakis
77 7e2f9d4b Giorgos Verigakis
78 dca2a31f Giorgos Verigakis
def random_password():
79 dca2a31f Giorgos Verigakis
    """Generates a random password
80 ce55f211 Kostas Papadimitriou

81 62eac5a6 Giorgos Verigakis
    We generate a windows compliant password: it must contain at least
82 dca2a31f Giorgos Verigakis
    one charachter from each of the groups: upper case, lower case, digits.
83 dca2a31f Giorgos Verigakis
    """
84 ce55f211 Kostas Papadimitriou
85 dca2a31f Giorgos Verigakis
    pool = lowercase + uppercase + digits
86 dca2a31f Giorgos Verigakis
    lowerset = set(lowercase)
87 dca2a31f Giorgos Verigakis
    upperset = set(uppercase)
88 dca2a31f Giorgos Verigakis
    digitset = set(digits)
89 dca2a31f Giorgos Verigakis
    length = 10
90 ce55f211 Kostas Papadimitriou
91 62eac5a6 Giorgos Verigakis
    password = ''.join(choice(pool) for i in range(length - 2))
92 ce55f211 Kostas Papadimitriou
93 62eac5a6 Giorgos Verigakis
    # Make sure the password is compliant
94 62eac5a6 Giorgos Verigakis
    chars = set(password)
95 62eac5a6 Giorgos Verigakis
    if not chars & lowerset:
96 62eac5a6 Giorgos Verigakis
        password += choice(lowercase)
97 62eac5a6 Giorgos Verigakis
    if not chars & upperset:
98 62eac5a6 Giorgos Verigakis
        password += choice(uppercase)
99 62eac5a6 Giorgos Verigakis
    if not chars & digitset:
100 62eac5a6 Giorgos Verigakis
        password += choice(digits)
101 ce55f211 Kostas Papadimitriou
102 62eac5a6 Giorgos Verigakis
    # Pad if necessary to reach required length
103 62eac5a6 Giorgos Verigakis
    password += ''.join(choice(pool) for i in range(length - len(password)))
104 ce55f211 Kostas Papadimitriou
105 dca2a31f Giorgos Verigakis
    return password
106 dca2a31f Giorgos Verigakis
107 d8e50a39 Giorgos Verigakis
108 c738c935 Giorgos Verigakis
def zeropad(s):
109 c738c935 Giorgos Verigakis
    """Add zeros at the end of a string in order to make its length
110 c738c935 Giorgos Verigakis
       a multiple of 16."""
111 d1387ed7 Christodoulos Psaltis
112 c738c935 Giorgos Verigakis
    npad = 16 - len(s) % 16
113 c738c935 Giorgos Verigakis
    return s + '\x00' * npad
114 c738c935 Giorgos Verigakis
115 a08e4270 Vangelis Koukis
116 c738c935 Giorgos Verigakis
def encrypt(plaintext):
117 c738c935 Giorgos Verigakis
    # Make sure key is 32 bytes long
118 c738c935 Giorgos Verigakis
    key = sha256(settings.SECRET_KEY).digest()
119 d1387ed7 Christodoulos Psaltis
120 c738c935 Giorgos Verigakis
    aes = AES.new(key)
121 c738c935 Giorgos Verigakis
    enc = aes.encrypt(zeropad(plaintext))
122 c738c935 Giorgos Verigakis
    return b64encode(enc)
123 c738c935 Giorgos Verigakis
124 7e2f9d4b Giorgos Verigakis
125 7f2dbcad Christos Stavrakakis
def get_vm(server_id, user_id, for_update=False, non_deleted=False,
126 7f2dbcad Christos Stavrakakis
           non_suspended=False):
127 e221ade2 Christos Stavrakakis
    """Find a VirtualMachine instance based on ID and owner."""
128 aa197ee4 Vangelis Koukis
129 d8e50a39 Giorgos Verigakis
    try:
130 d8e50a39 Giorgos Verigakis
        server_id = int(server_id)
131 7f2dbcad Christos Stavrakakis
        servers = VirtualMachine.objects
132 7f2dbcad Christos Stavrakakis
        if for_update:
133 7f2dbcad Christos Stavrakakis
            servers = servers.select_for_update()
134 7f2dbcad Christos Stavrakakis
        vm = servers.get(id=server_id, userid=user_id)
135 e221ade2 Christos Stavrakakis
        if non_deleted and vm.deleted:
136 5b0832fc Christos Stavrakakis
            raise faults.BadRequest("Server has been deleted.")
137 e221ade2 Christos Stavrakakis
        if non_suspended and vm.suspended:
138 bd40abfa Christos Stavrakakis
            raise faults.Forbidden("Administratively Suspended VM")
139 3a522cff Christos Stavrakakis
        return vm
140 d8e50a39 Giorgos Verigakis
    except ValueError:
141 bd40abfa Christos Stavrakakis
        raise faults.BadRequest('Invalid server ID.')
142 d8e50a39 Giorgos Verigakis
    except VirtualMachine.DoesNotExist:
143 bd40abfa Christos Stavrakakis
        raise faults.ItemNotFound('Server not found.')
144 d8e50a39 Giorgos Verigakis
145 7f2dbcad Christos Stavrakakis
146 40777cc8 Giorgos Verigakis
def get_vm_meta(vm, key):
147 d8e50a39 Giorgos Verigakis
    """Return a VirtualMachineMetadata instance or raise ItemNotFound."""
148 aa197ee4 Vangelis Koukis
149 d8e50a39 Giorgos Verigakis
    try:
150 40777cc8 Giorgos Verigakis
        return VirtualMachineMetadata.objects.get(meta_key=key, vm=vm)
151 d8e50a39 Giorgos Verigakis
    except VirtualMachineMetadata.DoesNotExist:
152 bd40abfa Christos Stavrakakis
        raise faults.ItemNotFound('Metadata key not found.')
153 d8e50a39 Giorgos Verigakis
154 a08e4270 Vangelis Koukis
155 6ef51e9f Giorgos Verigakis
def get_image(image_id, user_id):
156 d8e50a39 Giorgos Verigakis
    """Return an Image instance or raise ItemNotFound."""
157 aa197ee4 Vangelis Koukis
158 b3fd98ae Christos Stavrakakis
    with image_backend(user_id) as backend:
159 cda71050 Christos Stavrakakis
        return backend.get_image(image_id)
160 3a9b3cde Giorgos Verigakis
161 a08e4270 Vangelis Koukis
162 dca7553e Christos Stavrakakis
def get_image_dict(image_id, user_id):
163 dca7553e Christos Stavrakakis
    image = {}
164 dca7553e Christos Stavrakakis
    img = get_image(image_id, user_id)
165 bcd80cd9 Christos Stavrakakis
    image["id"] = img["id"]
166 bcd80cd9 Christos Stavrakakis
    image["name"] = img["name"]
167 c172f4ab Christos Stavrakakis
    image["format"] = img["disk_format"]
168 c172f4ab Christos Stavrakakis
    image["checksum"] = img["checksum"]
169 c172f4ab Christos Stavrakakis
    image["location"] = img["location"]
170 c172f4ab Christos Stavrakakis
171 c172f4ab Christos Stavrakakis
    checksum = image["checksum"] = img["checksum"]
172 c172f4ab Christos Stavrakakis
    size = image["size"] = img["size"]
173 c172f4ab Christos Stavrakakis
    image["backend_id"] = PITHOSMAP_PREFIX + "/".join([checksum, str(size)])
174 c172f4ab Christos Stavrakakis
175 c172f4ab Christos Stavrakakis
    properties = img.get("properties", {})
176 c172f4ab Christos Stavrakakis
    image["metadata"] = dict((key.upper(), val)
177 dca7553e Christos Stavrakakis
                             for key, val in properties.items())
178 c172f4ab Christos Stavrakakis
179 dca7553e Christos Stavrakakis
    return image
180 dca7553e Christos Stavrakakis
181 dca7553e Christos Stavrakakis
182 aa8230bd Christos Stavrakakis
def get_flavor(flavor_id, include_deleted=False):
183 529178b1 Giorgos Verigakis
    """Return a Flavor instance or raise ItemNotFound."""
184 aa197ee4 Vangelis Koukis
185 529178b1 Giorgos Verigakis
    try:
186 529178b1 Giorgos Verigakis
        flavor_id = int(flavor_id)
187 aa8230bd Christos Stavrakakis
        if include_deleted:
188 aa8230bd Christos Stavrakakis
            return Flavor.objects.get(id=flavor_id)
189 aa8230bd Christos Stavrakakis
        else:
190 aa8230bd Christos Stavrakakis
            return Flavor.objects.get(id=flavor_id, deleted=include_deleted)
191 6ef51e9f Giorgos Verigakis
    except (ValueError, Flavor.DoesNotExist):
192 bd40abfa Christos Stavrakakis
        raise faults.ItemNotFound('Flavor not found.')
193 d8e50a39 Giorgos Verigakis
194 a08e4270 Vangelis Koukis
195 9dcb5b8a Christos Stavrakakis
def get_flavor_provider(flavor):
196 9dcb5b8a Christos Stavrakakis
    """Extract provider from disk template.
197 9dcb5b8a Christos Stavrakakis

198 9dcb5b8a Christos Stavrakakis
    Provider for `ext` disk_template is encoded in the disk template
199 9dcb5b8a Christos Stavrakakis
    name, which is formed `ext_<provider_name>`. Provider is None
200 9dcb5b8a Christos Stavrakakis
    for all other disk templates.
201 9dcb5b8a Christos Stavrakakis

202 9dcb5b8a Christos Stavrakakis
    """
203 9dcb5b8a Christos Stavrakakis
    disk_template = flavor.disk_template
204 9dcb5b8a Christos Stavrakakis
    provider = None
205 9dcb5b8a Christos Stavrakakis
    if disk_template.startswith("ext"):
206 9dcb5b8a Christos Stavrakakis
        disk_template, provider = disk_template.split("_", 1)
207 9dcb5b8a Christos Stavrakakis
    return disk_template, provider
208 9dcb5b8a Christos Stavrakakis
209 95a213d4 Christos Stavrakakis
210 9e8be4fb Christos Stavrakakis
def get_network(network_id, user_id, for_update=False, non_deleted=False):
211 e2ee7808 Giorgos Verigakis
    """Return a Network instance or raise ItemNotFound."""
212 aa197ee4 Vangelis Koukis
213 e2ee7808 Giorgos Verigakis
    try:
214 7fede91e Christos Stavrakakis
        network_id = int(network_id)
215 a96e84cf Christos Stavrakakis
        objects = Network.objects.prefetch_related("subnets")
216 d2e73c0c Christos Stavrakakis
        if for_update:
217 d3406fbc Christos Stavrakakis
            objects = objects.select_for_update()
218 9e8be4fb Christos Stavrakakis
        network = objects.get(Q(userid=user_id) | Q(public=True),
219 9e8be4fb Christos Stavrakakis
                              id=network_id)
220 9e8be4fb Christos Stavrakakis
        if non_deleted and network.deleted:
221 f8675683 Christos Stavrakakis
            raise faults.BadRequest("Network has been deleted.")
222 9e8be4fb Christos Stavrakakis
        return network
223 6ef51e9f Giorgos Verigakis
    except (ValueError, Network.DoesNotExist):
224 0baa1e3d Buildbot
        raise faults.ItemNotFound('Network not found.')
225 95a213d4 Christos Stavrakakis
226 95a213d4 Christos Stavrakakis
227 95a213d4 Christos Stavrakakis
def get_port(port_id, user_id, for_update=False):
228 0baa1e3d Buildbot
    """
229 95a213d4 Christos Stavrakakis
    Return a NetworkInteface instance or raise ItemNotFound.
230 0baa1e3d Buildbot
    """
231 0baa1e3d Buildbot
    try:
232 593851e0 Buildbot
        objects = NetworkInterface.objects
233 593851e0 Buildbot
        if for_update:
234 593851e0 Buildbot
            objects = objects.select_for_update()
235 593851e0 Buildbot
236 593851e0 Buildbot
        port = objects.get(network__userid=user_id, id=port_id)
237 593851e0 Buildbot
238 593851e0 Buildbot
        if (port.device_owner != "vm") and for_update:
239 95a213d4 Christos Stavrakakis
            raise faults.BadRequest('Can not update non vm port')
240 593851e0 Buildbot
241 593851e0 Buildbot
        return port
242 95a213d4 Christos Stavrakakis
    except (ValueError, NetworkInterface.DoesNotExist):
243 95a213d4 Christos Stavrakakis
        raise faults.ItemNotFound('Port not found.')
244 95a213d4 Christos Stavrakakis
245 a08e4270 Vangelis Koukis
246 f8675683 Christos Stavrakakis
def get_floating_ip(user_id, ipv4, for_update=False):
247 f8675683 Christos Stavrakakis
    try:
248 326c3ec8 Christos Stavrakakis
        objects = IPAddress.objects
249 f8675683 Christos Stavrakakis
        if for_update:
250 f8675683 Christos Stavrakakis
            objects = objects.select_for_update()
251 f8675683 Christos Stavrakakis
        return objects.get(userid=user_id, ipv4=ipv4, deleted=False)
252 326c3ec8 Christos Stavrakakis
    except IPAddress.DoesNotExist:
253 f8675683 Christos Stavrakakis
        raise faults.ItemNotFound("Floating IP does not exist.")
254 f8675683 Christos Stavrakakis
255 f8675683 Christos Stavrakakis
256 92d2d1ce Christos Stavrakakis
def allocate_public_address(backend, userid):
257 660b9f3b Christos Stavrakakis
    """Get a public IP for any available network of a backend."""
258 85919a0f Christos Stavrakakis
    # Guarantee exclusive access to backend, because accessing the IP pools of
259 85919a0f Christos Stavrakakis
    # the backend networks may result in a deadlock with backend allocator
260 85919a0f Christos Stavrakakis
    # which also checks that backend networks have a free IP.
261 85919a0f Christos Stavrakakis
    backend = Backend.objects.select_for_update().get(id=backend.id)
262 660b9f3b Christos Stavrakakis
    public_networks = backend_public_networks(backend)
263 92d2d1ce Christos Stavrakakis
    return get_free_ip(public_networks, userid)
264 dca7553e Christos Stavrakakis
265 dca7553e Christos Stavrakakis
266 7fede91e Christos Stavrakakis
def backend_public_networks(backend):
267 7fede91e Christos Stavrakakis
    """Return available public networks of the backend.
268 7fede91e Christos Stavrakakis

269 7fede91e Christos Stavrakakis
    Iterator for non-deleted public networks that are available
270 7fede91e Christos Stavrakakis
    to the specified backend.
271 7fede91e Christos Stavrakakis

272 7fede91e Christos Stavrakakis
    """
273 660b9f3b Christos Stavrakakis
    bnets = BackendNetwork.objects.filter(backend=backend,
274 660b9f3b Christos Stavrakakis
                                          network__public=True,
275 660b9f3b Christos Stavrakakis
                                          network__deleted=False,
276 12e539f0 Christos Stavrakakis
                                          network__floating_ip_pool=False,
277 660b9f3b Christos Stavrakakis
                                          network__drained=False)
278 660b9f3b Christos Stavrakakis
    return [b.network for b in bnets]
279 660b9f3b Christos Stavrakakis
280 660b9f3b Christos Stavrakakis
281 92d2d1ce Christos Stavrakakis
def get_free_ip(networks, userid):
282 660b9f3b Christos Stavrakakis
    for network in networks:
283 660b9f3b Christos Stavrakakis
        try:
284 92d2d1ce Christos Stavrakakis
            return network.allocate_address(userid=userid)
285 660b9f3b Christos Stavrakakis
        except faults.OverLimit:
286 660b9f3b Christos Stavrakakis
            pass
287 660b9f3b Christos Stavrakakis
    msg = "Can not allocate public IP. Public networks are full."
288 660b9f3b Christos Stavrakakis
    log.error(msg)
289 660b9f3b Christos Stavrakakis
    raise faults.OverLimit(msg)
290 7fede91e Christos Stavrakakis
291 7fede91e Christos Stavrakakis
292 92d2d1ce Christos Stavrakakis
def get_network_free_address(network, userid):
293 34c03a51 Christos Stavrakakis
    """Reserve an IP address from the IP Pool of the network."""
294 7fede91e Christos Stavrakakis
295 34c03a51 Christos Stavrakakis
    try:
296 92d2d1ce Christos Stavrakakis
        return network.allocate_address(userid=userid)
297 34c03a51 Christos Stavrakakis
    except EmptyPool:
298 34c03a51 Christos Stavrakakis
        raise faults.OverLimit("Network %s is full." % network.backend_id)
299 7fede91e Christos Stavrakakis
300 7fede91e Christos Stavrakakis
301 c988fcca Christos Stavrakakis
def get_vm_nic(vm, nic_id):
302 d0545590 Christos Stavrakakis
    """Get a VMs NIC by its ID."""
303 d44c236b Giorgos Verigakis
    try:
304 7c714455 Christos Stavrakakis
        return vm.nics.get(id=nic_id)
305 d44c236b Giorgos Verigakis
    except NetworkInterface.DoesNotExist:
306 d0545590 Christos Stavrakakis
        raise faults.ItemNotFound("NIC '%s' not found" % nic_id)
307 d44c236b Giorgos Verigakis
308 7fede91e Christos Stavrakakis
309 c988fcca Christos Stavrakakis
def get_nic(nic_id):
310 c988fcca Christos Stavrakakis
    try:
311 c988fcca Christos Stavrakakis
        return NetworkInterface.objects.get(id=nic_id)
312 c988fcca Christos Stavrakakis
    except NetworkInterface.DoesNotExist:
313 c988fcca Christos Stavrakakis
        raise faults.ItemNotFound("NIC '%s' not found" % nic_id)
314 c988fcca Christos Stavrakakis
315 c988fcca Christos Stavrakakis
316 432fc8c3 Giorgos Verigakis
def render_metadata(request, metadata, use_values=False, status=200):
317 432fc8c3 Giorgos Verigakis
    if request.serialization == 'xml':
318 432fc8c3 Giorgos Verigakis
        data = render_to_string('metadata.xml', {'metadata': metadata})
319 432fc8c3 Giorgos Verigakis
    else:
320 b36f78fa Giorgos Verigakis
        if use_values:
321 b36f78fa Giorgos Verigakis
            d = {'metadata': {'values': metadata}}
322 b36f78fa Giorgos Verigakis
        else:
323 b36f78fa Giorgos Verigakis
            d = {'metadata': metadata}
324 432fc8c3 Giorgos Verigakis
        data = json.dumps(d)
325 432fc8c3 Giorgos Verigakis
    return HttpResponse(data, status=status)
326 432fc8c3 Giorgos Verigakis
327 a08e4270 Vangelis Koukis
328 432fc8c3 Giorgos Verigakis
def render_meta(request, meta, status=200):
329 432fc8c3 Giorgos Verigakis
    if request.serialization == 'xml':
330 32e4e343 Christos Stavrakakis
        key, val = meta.items()[0]
331 6ef51e9f Giorgos Verigakis
        data = render_to_string('meta.xml', dict(key=key, val=val))
332 432fc8c3 Giorgos Verigakis
    else:
333 6ef51e9f Giorgos Verigakis
        data = json.dumps(dict(meta=meta))
334 432fc8c3 Giorgos Verigakis
    return HttpResponse(data, status=status)
335 432fc8c3 Giorgos Verigakis
336 a08e4270 Vangelis Koukis
337 dca7553e Christos Stavrakakis
def verify_personality(personality):
338 6ec4694f Christos Stavrakakis
    """Verify that a a list of personalities is well formed"""
339 006c6249 Christos Stavrakakis
    if len(personality) > settings.MAX_PERSONALITY:
340 bd40abfa Christos Stavrakakis
        raise faults.OverLimit("Maximum number of personalities"
341 32e4e343 Christos Stavrakakis
                               " exceeded")
342 dca7553e Christos Stavrakakis
    for p in personality:
343 dca7553e Christos Stavrakakis
        # Verify that personalities are well-formed
344 dca7553e Christos Stavrakakis
        try:
345 dca7553e Christos Stavrakakis
            assert isinstance(p, dict)
346 dca7553e Christos Stavrakakis
            keys = set(p.keys())
347 dca7553e Christos Stavrakakis
            allowed = set(['contents', 'group', 'mode', 'owner', 'path'])
348 dca7553e Christos Stavrakakis
            assert keys.issubset(allowed)
349 dca7553e Christos Stavrakakis
            contents = p['contents']
350 dca7553e Christos Stavrakakis
            if len(contents) > settings.MAX_PERSONALITY_SIZE:
351 dca7553e Christos Stavrakakis
                # No need to decode if contents already exceed limit
352 bd40abfa Christos Stavrakakis
                raise faults.OverLimit("Maximum size of personality exceeded")
353 dca7553e Christos Stavrakakis
            if len(b64decode(contents)) > settings.MAX_PERSONALITY_SIZE:
354 bd40abfa Christos Stavrakakis
                raise faults.OverLimit("Maximum size of personality exceeded")
355 dca7553e Christos Stavrakakis
        except AssertionError:
356 bd40abfa Christos Stavrakakis
            raise faults.BadRequest("Malformed personality in request")
357 2a599282 Christos Stavrakakis
358 2a599282 Christos Stavrakakis
359 b7d38981 Dimitris Aragiorgis
def values_from_flavor(flavor):
360 b7d38981 Dimitris Aragiorgis
    """Get Ganeti connectivity info from flavor type.
361 b7d38981 Dimitris Aragiorgis

362 b7d38981 Dimitris Aragiorgis
    If link or mac_prefix equals to "pool", then the resources
363 b7d38981 Dimitris Aragiorgis
    are allocated from the corresponding Pools.
364 b7d38981 Dimitris Aragiorgis

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