Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / utils.py @ 2b8f654c

History | View | Annotate | Download (6.9 kB)

1 48130e66 Georgios Gousios
# Copyright 2011 GRNET S.A. All rights reserved.
2 8d97deff Vassilios Karakoidas
#
3 48130e66 Georgios Gousios
# Redistribution and use in source and binary forms, with or without
4 48130e66 Georgios Gousios
# modification, are permitted provided that the following conditions
5 48130e66 Georgios Gousios
# are met:
6 48130e66 Georgios Gousios
#
7 48130e66 Georgios Gousios
#   1. Redistributions of source code must retain the above copyright
8 48130e66 Georgios Gousios
#      notice, this list of conditions and the following disclaimer.
9 8d97deff Vassilios Karakoidas
#
10 48130e66 Georgios Gousios
#  2. Redistributions in binary form must reproduce the above copyright
11 48130e66 Georgios Gousios
#     notice, this list of conditions and the following disclaimer in the
12 48130e66 Georgios Gousios
#     documentation and/or other materials provided with the distribution.
13 8d97deff Vassilios Karakoidas
#
14 48130e66 Georgios Gousios
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15 48130e66 Georgios Gousios
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 48130e66 Georgios Gousios
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 48130e66 Georgios Gousios
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18 48130e66 Georgios Gousios
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 48130e66 Georgios Gousios
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 48130e66 Georgios Gousios
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 48130e66 Georgios Gousios
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 48130e66 Georgios Gousios
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 48130e66 Georgios Gousios
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 48130e66 Georgios Gousios
# SUCH DAMAGE.
25 8d97deff Vassilios Karakoidas
#
26 48130e66 Georgios Gousios
# The views and conclusions contained in the software and documentation are
27 48130e66 Georgios Gousios
# those of the authors and should not be interpreted as representing official
28 48130e66 Georgios Gousios
# policies, either expressed or implied, of GRNET S.A.
29 48130e66 Georgios Gousios
30 48130e66 Georgios Gousios
# Utility functions
31 8d97deff Vassilios Karakoidas
32 22ee6892 Christos Stavrakakis
from synnefo.db.models import VirtualMachine, Network
33 ba6ad346 Dionysis Grigoropoulos
from snf_django.lib.api import faults
34 6efeecee Faidon Liambotis
from django.conf import settings
35 6de6677b Christos Stavrakakis
from copy import deepcopy
36 b6f688dd Dionysis Grigoropoulos
from synnefo.util.text import uenc
37 8d97deff Vassilios Karakoidas
38 68b952f9 Christos Stavrakakis
39 8d97deff Vassilios Karakoidas
def id_from_instance_name(name):
40 8d97deff Vassilios Karakoidas
    """Returns VirtualMachine's Django id, given a ganeti machine name.
41 8d97deff Vassilios Karakoidas

42 8d97deff Vassilios Karakoidas
    Strips the ganeti prefix atm. Needs a better name!
43 8d97deff Vassilios Karakoidas

44 8d97deff Vassilios Karakoidas
    """
45 4cbef2a0 Christos Stavrakakis
    sname = str(name)
46 4cbef2a0 Christos Stavrakakis
    if not sname.startswith(settings.BACKEND_PREFIX_ID):
47 4cbef2a0 Christos Stavrakakis
        raise VirtualMachine.InvalidBackendIdError(sname)
48 4cbef2a0 Christos Stavrakakis
    ns = sname.replace(settings.BACKEND_PREFIX_ID, "", 1)
49 8d97deff Vassilios Karakoidas
    if not ns.isdigit():
50 4cbef2a0 Christos Stavrakakis
        raise VirtualMachine.InvalidBackendIdError(sname)
51 8d97deff Vassilios Karakoidas
52 8d97deff Vassilios Karakoidas
    return int(ns)
53 8d97deff Vassilios Karakoidas
54 d30f29aa Christos Stavrakakis
55 d30f29aa Christos Stavrakakis
def id_to_instance_name(id):
56 c55b0cdc Christos Stavrakakis
    return "%s%s" % (settings.BACKEND_PREFIX_ID, str(id))
57 d30f29aa Christos Stavrakakis
58 d30f29aa Christos Stavrakakis
59 22ee6892 Christos Stavrakakis
def id_from_network_name(name):
60 a1baa42b Christos Stavrakakis
    """Returns Network's Django id, given a ganeti network name.
61 22ee6892 Christos Stavrakakis

62 22ee6892 Christos Stavrakakis
    Strips the ganeti prefix atm. Needs a better name!
63 22ee6892 Christos Stavrakakis

64 22ee6892 Christos Stavrakakis
    """
65 22ee6892 Christos Stavrakakis
    if not str(name).startswith(settings.BACKEND_PREFIX_ID):
66 22ee6892 Christos Stavrakakis
        raise Network.InvalidBackendIdError(str(name))
67 44e2c577 Christos Stavrakakis
    ns = str(name).replace(settings.BACKEND_PREFIX_ID + 'net-', "", 1)
68 22ee6892 Christos Stavrakakis
    if not ns.isdigit():
69 22ee6892 Christos Stavrakakis
        raise Network.InvalidBackendIdError(str(name))
70 22ee6892 Christos Stavrakakis
71 22ee6892 Christos Stavrakakis
    return int(ns)
72 22ee6892 Christos Stavrakakis
73 22ee6892 Christos Stavrakakis
74 d30f29aa Christos Stavrakakis
def id_to_network_name(id):
75 0b827aa4 Christos Stavrakakis
    return "%snet-%s" % (settings.BACKEND_PREFIX_ID, str(id))
76 d30f29aa Christos Stavrakakis
77 d30f29aa Christos Stavrakakis
78 a1baa42b Christos Stavrakakis
def id_from_nic_name(name):
79 a1baa42b Christos Stavrakakis
    """Returns NIC's Django id, given a Ganeti's NIC name.
80 a1baa42b Christos Stavrakakis

81 a1baa42b Christos Stavrakakis
    """
82 a1baa42b Christos Stavrakakis
    if not str(name).startswith(settings.BACKEND_PREFIX_ID):
83 a1baa42b Christos Stavrakakis
        raise ValueError("Invalid NIC name: %s" % name)
84 a1baa42b Christos Stavrakakis
    ns = str(name).replace(settings.BACKEND_PREFIX_ID + 'nic-', "", 1)
85 a1baa42b Christos Stavrakakis
    if not ns.isdigit():
86 a1baa42b Christos Stavrakakis
        raise ValueError("Invalid NIC name: %s" % name)
87 a1baa42b Christos Stavrakakis
88 a1baa42b Christos Stavrakakis
    return int(ns)
89 a1baa42b Christos Stavrakakis
90 a1baa42b Christos Stavrakakis
91 c583d487 Christos Stavrakakis
def id_from_disk_name(name):
92 c583d487 Christos Stavrakakis
    """Returns Disk Django id, given a Ganeti's Disk name.
93 c583d487 Christos Stavrakakis

94 c583d487 Christos Stavrakakis
    """
95 c583d487 Christos Stavrakakis
    if not str(name).startswith(settings.BACKEND_PREFIX_ID):
96 c583d487 Christos Stavrakakis
        raise ValueError("Invalid Disk name: %s" % name)
97 2b8f654c Christos Stavrakakis
    ns = str(name).replace(settings.BACKEND_PREFIX_ID + 'vol-', "", 1)
98 c583d487 Christos Stavrakakis
    if not ns.isdigit():
99 c583d487 Christos Stavrakakis
        raise ValueError("Invalid Disk name: %s" % name)
100 c583d487 Christos Stavrakakis
101 c583d487 Christos Stavrakakis
    return int(ns)
102 c583d487 Christos Stavrakakis
103 c583d487 Christos Stavrakakis
104 8d97deff Vassilios Karakoidas
def get_rsapi_state(vm):
105 fc30c430 Vangelis Koukis
    """Returns the API state for a virtual machine
106 f16c6944 Kostas Papadimitriou

107 fc30c430 Vangelis Koukis
    The API state for an instance of VirtualMachine is derived as follows:
108 fc30c430 Vangelis Koukis

109 fc30c430 Vangelis Koukis
    * If the deleted flag has been set, it is "DELETED".
110 fc30c430 Vangelis Koukis
    * Otherwise, it is a mapping of the last state reported by Ganeti
111 fc30c430 Vangelis Koukis
      (vm.operstate) through the RSAPI_STATE_FROM_OPER_STATE dictionary.
112 f16c6944 Kostas Papadimitriou

113 fc30c430 Vangelis Koukis
      The last state reported by Ganeti is set whenever Ganeti reports
114 68b952f9 Christos Stavrakakis
      successful completion of an operation. If Ganeti says an
115 68b952f9 Christos Stavrakakis
      OP_INSTANCE_STARTUP operation succeeded, vm.operstate is set to
116 68b952f9 Christos Stavrakakis
      "STARTED".
117 68b952f9 Christos Stavrakakis

118 68b952f9 Christos Stavrakakis
    * To support any transitional states defined by the API (only REBOOT for
119 68b952f9 Christos Stavrakakis
    the time being) this mapping is amended with information reported by Ganeti
120 68b952f9 Christos Stavrakakis
    regarding any outstanding operation. If an OP_INSTANCE_STARTUP had
121 68b952f9 Christos Stavrakakis
    succeeded previously and an OP_INSTANCE_REBOOT has been reported as in
122 68b952f9 Christos Stavrakakis
    progress, the API state is "REBOOT".
123 fc30c430 Vangelis Koukis

124 fc30c430 Vangelis Koukis
    """
125 8d97deff Vassilios Karakoidas
    try:
126 dfd19c2d Vassilios Karakoidas
        r = VirtualMachine.RSAPI_STATE_FROM_OPER_STATE[vm.operstate]
127 8d97deff Vassilios Karakoidas
    except KeyError:
128 8d97deff Vassilios Karakoidas
        return "UNKNOWN"
129 685b219e Vangelis Koukis
    # A machine is DELETED if the deleted flag has been set
130 685b219e Vangelis Koukis
    if vm.deleted:
131 685b219e Vangelis Koukis
        return "DELETED"
132 8d97deff Vassilios Karakoidas
    # A machine is in REBOOT if an OP_INSTANCE_REBOOT request is in progress
133 41a7fae7 Christos Stavrakakis
    in_reboot = (r == "ACTIVE") and\
134 c4e45b57 Christos Stavrakakis
                (vm.backendopcode == "OP_INSTANCE_REBOOT") and\
135 41a7fae7 Christos Stavrakakis
                (vm.backendjobstatus in ("queued", "waiting", "running"))
136 c4e45b57 Christos Stavrakakis
    if in_reboot:
137 8d97deff Vassilios Karakoidas
        return "REBOOT"
138 41a7fae7 Christos Stavrakakis
    in_resize = (r == "STOPPED") and\
139 41a7fae7 Christos Stavrakakis
                (vm.backendopcode == "OP_INSTANCE_MODIFY") and\
140 41a7fae7 Christos Stavrakakis
                (vm.task == "RESIZE") and \
141 41a7fae7 Christos Stavrakakis
                (vm.backendjobstatus in ("queued", "waiting", "running"))
142 41a7fae7 Christos Stavrakakis
    if in_resize:
143 41a7fae7 Christos Stavrakakis
        return "RESIZE"
144 8d97deff Vassilios Karakoidas
    return r
145 8d97deff Vassilios Karakoidas
146 6afeb85d Christos Stavrakakis
147 41a7fae7 Christos Stavrakakis
TASK_STATE_FROM_ACTION = {
148 48bac1b6 Chrysostomos Nanakos
    "BUILD": "BUILDING",
149 41a7fae7 Christos Stavrakakis
    "START": "STARTING",
150 41a7fae7 Christos Stavrakakis
    "STOP": "STOPPING",
151 41a7fae7 Christos Stavrakakis
    "REBOOT": "REBOOTING",
152 41a7fae7 Christos Stavrakakis
    "DESTROY": "DESTROYING",
153 41a7fae7 Christos Stavrakakis
    "RESIZE": "RESIZING",
154 41a7fae7 Christos Stavrakakis
    "CONNECT": "CONNECTING",
155 41a7fae7 Christos Stavrakakis
    "DISCONNECT": "DISCONNECTING"}
156 41a7fae7 Christos Stavrakakis
157 41a7fae7 Christos Stavrakakis
158 41a7fae7 Christos Stavrakakis
def get_task_state(vm):
159 41a7fae7 Christos Stavrakakis
    if vm.task is None:
160 41a7fae7 Christos Stavrakakis
        return ""
161 41a7fae7 Christos Stavrakakis
    try:
162 41a7fae7 Christos Stavrakakis
        return TASK_STATE_FROM_ACTION[vm.task]
163 41a7fae7 Christos Stavrakakis
    except KeyError:
164 41a7fae7 Christos Stavrakakis
        return "UNKNOWN"
165 41a7fae7 Christos Stavrakakis
166 41a7fae7 Christos Stavrakakis
167 41a7fae7 Christos Stavrakakis
OPCODE_TO_ACTION = {
168 41a7fae7 Christos Stavrakakis
    "OP_INSTANCE_CREATE": "BUILD",
169 3af1fb4b Christos Stavrakakis
    "OP_INSTANCE_STARTUP": "START",
170 3af1fb4b Christos Stavrakakis
    "OP_INSTANCE_SHUTDOWN": "STOP",
171 41a7fae7 Christos Stavrakakis
    "OP_INSTANCE_REBOOT": "REBOOT",
172 41a7fae7 Christos Stavrakakis
    "OP_INSTANCE_REMOVE": "DESTROY"}
173 41a7fae7 Christos Stavrakakis
174 41a7fae7 Christos Stavrakakis
175 41a7fae7 Christos Stavrakakis
def get_action_from_opcode(opcode, job_fields):
176 41a7fae7 Christos Stavrakakis
    if opcode == "OP_INSTANCE_SET_PARAMS":
177 41a7fae7 Christos Stavrakakis
        nics = job_fields.get("nics")
178 41a7fae7 Christos Stavrakakis
        beparams = job_fields.get("beparams")
179 41a7fae7 Christos Stavrakakis
        if nics:
180 3c52a9df Christos Stavrakakis
            try:
181 3c52a9df Christos Stavrakakis
                nic_action = nics[0][0]
182 3c52a9df Christos Stavrakakis
                if nic_action == "add":
183 3c52a9df Christos Stavrakakis
                    return "CONNECT"
184 3c52a9df Christos Stavrakakis
                elif nic_action == "remove":
185 3c52a9df Christos Stavrakakis
                    return "DISCONNECT"
186 3c52a9df Christos Stavrakakis
                else:
187 3c52a9df Christos Stavrakakis
                    return None
188 3c52a9df Christos Stavrakakis
            except:
189 3c52a9df Christos Stavrakakis
                return None
190 41a7fae7 Christos Stavrakakis
        elif beparams:
191 41a7fae7 Christos Stavrakakis
            return "RESIZE"
192 41a7fae7 Christos Stavrakakis
        else:
193 41a7fae7 Christos Stavrakakis
            return None
194 41a7fae7 Christos Stavrakakis
    else:
195 41a7fae7 Christos Stavrakakis
        return OPCODE_TO_ACTION.get(opcode, None)
196 41a7fae7 Christos Stavrakakis
197 41a7fae7 Christos Stavrakakis
198 6afeb85d Christos Stavrakakis
def hide_pass(kw):
199 6afeb85d Christos Stavrakakis
    if 'osparams' in kw and 'img_passwd' in kw['osparams']:
200 6de6677b Christos Stavrakakis
        kw1 = deepcopy(kw)
201 6afeb85d Christos Stavrakakis
        kw1['osparams']['img_passwd'] = 'x' * 8
202 6afeb85d Christos Stavrakakis
        return kw1
203 6afeb85d Christos Stavrakakis
    else:
204 6afeb85d Christos Stavrakakis
        return kw
205 ba6ad346 Dionysis Grigoropoulos
206 ba6ad346 Dionysis Grigoropoulos
207 ba6ad346 Dionysis Grigoropoulos
def check_name_length(name, max_length, message):
208 ba6ad346 Dionysis Grigoropoulos
    """Check if a string is within acceptable value length"""
209 b6f688dd Dionysis Grigoropoulos
    if len(uenc(name)) > max_length:
210 ba6ad346 Dionysis Grigoropoulos
        raise faults.BadRequest(message)