Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / management / common.py @ 4a769fc0

History | View | Annotate | Download (9.2 kB)

1 11300d7b Giorgos Verigakis
# Copyright 2012 GRNET S.A. All rights reserved.
2 11300d7b Giorgos Verigakis
#
3 11300d7b Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
4 11300d7b Giorgos Verigakis
# without modification, are permitted provided that the following
5 11300d7b Giorgos Verigakis
# conditions are met:
6 11300d7b Giorgos Verigakis
#
7 11300d7b Giorgos Verigakis
#   1. Redistributions of source code must retain the above
8 11300d7b Giorgos Verigakis
#      copyright notice, this list of conditions and the following
9 11300d7b Giorgos Verigakis
#      disclaimer.
10 11300d7b Giorgos Verigakis
#
11 11300d7b Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
12 11300d7b Giorgos Verigakis
#      copyright notice, this list of conditions and the following
13 11300d7b Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
14 11300d7b Giorgos Verigakis
#      provided with the distribution.
15 11300d7b Giorgos Verigakis
#
16 11300d7b Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 11300d7b Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 11300d7b Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 11300d7b Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 11300d7b Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 11300d7b Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 11300d7b Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 11300d7b Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 11300d7b Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 11300d7b Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 11300d7b Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 11300d7b Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
28 11300d7b Giorgos Verigakis
#
29 11300d7b Giorgos Verigakis
# The views and conclusions contained in the software and
30 11300d7b Giorgos Verigakis
# documentation are those of the authors and should not be
31 11300d7b Giorgos Verigakis
# interpreted as representing official policies, either expressed
32 11300d7b Giorgos Verigakis
# or implied, of GRNET S.A.
33 11300d7b Giorgos Verigakis
34 53b9ba10 Christos Stavrakakis
from django.core.management import CommandError
35 9d1e6480 Marios Kogias
from synnefo.db.models import (Backend, VirtualMachine, Network,
36 b48697f0 Christos Stavrakakis
                               Flavor, IPAddress, Subnet,
37 09b76b7e Christos Stavrakakis
                               BridgePoolTable, MacPrefixPoolTable,
38 0fc4b580 Marios Kogias
                               NetworkInterface, IPAddressLog)
39 c75ab92e Christos Stavrakakis
from functools import wraps
40 bad9404c Christos Stavrakakis
41 bd40abfa Christos Stavrakakis
from snf_django.lib.api import faults
42 bcd80cd9 Christos Stavrakakis
from synnefo.api import util
43 35f2fc07 Christos Stavrakakis
from synnefo.logic import backend as backend_mod
44 2333a2c4 Christos Stavrakakis
from synnefo.logic.rapi import GanetiApiError, GanetiRapiClient
45 0252fb8b Christos Stavrakakis
from synnefo.logic.utils import (id_from_instance_name,
46 0252fb8b Christos Stavrakakis
                                 id_from_network_name)
47 11300d7b Giorgos Verigakis
48 8814e07c Christos Stavrakakis
import logging
49 8814e07c Christos Stavrakakis
log = logging.getLogger(__name__)
50 8814e07c Christos Stavrakakis
51 11300d7b Giorgos Verigakis
52 f66d8b04 Christos Stavrakakis
def format_vm_state(vm):
53 f66d8b04 Christos Stavrakakis
    if vm.operstate == "BUILD":
54 f66d8b04 Christos Stavrakakis
        return "BUILD(" + str(vm.buildpercentage) + "%)"
55 f66d8b04 Christos Stavrakakis
    else:
56 f66d8b04 Christos Stavrakakis
        return vm.operstate
57 53b9ba10 Christos Stavrakakis
58 53b9ba10 Christos Stavrakakis
59 b84ed662 Christos Stavrakakis
def get_backend(backend_id):
60 b84ed662 Christos Stavrakakis
    try:
61 b84ed662 Christos Stavrakakis
        backend_id = int(backend_id)
62 b84ed662 Christos Stavrakakis
        return Backend.objects.get(id=backend_id)
63 b84ed662 Christos Stavrakakis
    except ValueError:
64 b84ed662 Christos Stavrakakis
        raise CommandError("Invalid Backend ID: %s" % backend_id)
65 b84ed662 Christos Stavrakakis
    except Backend.DoesNotExist:
66 b84ed662 Christos Stavrakakis
        raise CommandError("Backend with ID %s not found in DB. "
67 b84ed662 Christos Stavrakakis
                           " Use snf-manage backend-list to find"
68 b84ed662 Christos Stavrakakis
                           " out available backend IDs." % backend_id)
69 b84ed662 Christos Stavrakakis
70 b84ed662 Christos Stavrakakis
71 b84ed662 Christos Stavrakakis
def get_image(image_id, user_id):
72 b84ed662 Christos Stavrakakis
    if image_id:
73 b84ed662 Christos Stavrakakis
        try:
74 bcd80cd9 Christos Stavrakakis
            return util.get_image_dict(image_id, user_id)
75 bd40abfa Christos Stavrakakis
        except faults.ItemNotFound:
76 b84ed662 Christos Stavrakakis
            raise CommandError("Image with ID %s not found."
77 b84ed662 Christos Stavrakakis
                               " Use snf-manage image-list to find"
78 b84ed662 Christos Stavrakakis
                               " out available image IDs." % image_id)
79 b84ed662 Christos Stavrakakis
    else:
80 b84ed662 Christos Stavrakakis
        raise CommandError("image-id is mandatory")
81 b84ed662 Christos Stavrakakis
82 b84ed662 Christos Stavrakakis
83 b84ed662 Christos Stavrakakis
def get_vm(server_id):
84 0252fb8b Christos Stavrakakis
    """Get a VirtualMachine object by its ID.
85 0252fb8b Christos Stavrakakis

86 0252fb8b Christos Stavrakakis
    @type server_id: int or string
87 0252fb8b Christos Stavrakakis
    @param server_id: The server's DB id or the Ganeti name
88 0252fb8b Christos Stavrakakis

89 0252fb8b Christos Stavrakakis
    """
90 b84ed662 Christos Stavrakakis
    try:
91 b84ed662 Christos Stavrakakis
        server_id = int(server_id)
92 0252fb8b Christos Stavrakakis
    except (ValueError, TypeError):
93 0252fb8b Christos Stavrakakis
        try:
94 0252fb8b Christos Stavrakakis
            server_id = id_from_instance_name(server_id)
95 0252fb8b Christos Stavrakakis
        except VirtualMachine.InvalidBackendIdError:
96 0252fb8b Christos Stavrakakis
            raise CommandError("Invalid server ID: %s" % server_id)
97 0252fb8b Christos Stavrakakis
98 0252fb8b Christos Stavrakakis
    try:
99 b84ed662 Christos Stavrakakis
        return VirtualMachine.objects.get(id=server_id)
100 b84ed662 Christos Stavrakakis
    except VirtualMachine.DoesNotExist:
101 b84ed662 Christos Stavrakakis
        raise CommandError("Server with ID %s not found in DB."
102 b84ed662 Christos Stavrakakis
                           " Use snf-manage server-list to find out"
103 b84ed662 Christos Stavrakakis
                           " available server IDs." % server_id)
104 b84ed662 Christos Stavrakakis
105 b84ed662 Christos Stavrakakis
106 e57893cd Christos Stavrakakis
def get_network(network_id, for_update=True):
107 0252fb8b Christos Stavrakakis
    """Get a Network object by its ID.
108 0252fb8b Christos Stavrakakis

109 0252fb8b Christos Stavrakakis
    @type network_id: int or string
110 0252fb8b Christos Stavrakakis
    @param network_id: The networks DB id or the Ganeti name
111 0252fb8b Christos Stavrakakis

112 0252fb8b Christos Stavrakakis
    """
113 0252fb8b Christos Stavrakakis
114 b84ed662 Christos Stavrakakis
    try:
115 b84ed662 Christos Stavrakakis
        network_id = int(network_id)
116 0252fb8b Christos Stavrakakis
    except (ValueError, TypeError):
117 0252fb8b Christos Stavrakakis
        try:
118 0252fb8b Christos Stavrakakis
            network_id = id_from_network_name(network_id)
119 0252fb8b Christos Stavrakakis
        except Network.InvalidBackendIdError:
120 0252fb8b Christos Stavrakakis
            raise CommandError("Invalid network ID: %s" % network_id)
121 0252fb8b Christos Stavrakakis
122 e57893cd Christos Stavrakakis
    networks = Network.objects
123 e57893cd Christos Stavrakakis
    if for_update:
124 e57893cd Christos Stavrakakis
        networks = networks.select_for_update()
125 0252fb8b Christos Stavrakakis
    try:
126 e57893cd Christos Stavrakakis
        return networks.get(id=network_id)
127 b84ed662 Christos Stavrakakis
    except Network.DoesNotExist:
128 b84ed662 Christos Stavrakakis
        raise CommandError("Network with ID %s not found in DB."
129 b84ed662 Christos Stavrakakis
                           " Use snf-manage network-list to find out"
130 b84ed662 Christos Stavrakakis
                           " available network IDs." % network_id)
131 b84ed662 Christos Stavrakakis
132 b84ed662 Christos Stavrakakis
133 a17ce1de Dionysis Grigoropoulos
def get_subnet(subnet_id, for_update=True):
134 a17ce1de Dionysis Grigoropoulos
    """Get a Subnet object by its ID."""
135 a17ce1de Dionysis Grigoropoulos
    try:
136 f04ada8d Dionysis Grigoropoulos
        subet_id = int(subnet_id)
137 f04ada8d Dionysis Grigoropoulos
    except (ValueError, TypeError):
138 f04ada8d Dionysis Grigoropoulos
        raise CommandError("Invalid subnet ID: %s" % subnet_id)
139 f04ada8d Dionysis Grigoropoulos
140 f04ada8d Dionysis Grigoropoulos
    try:
141 09b76b7e Christos Stavrakakis
        subnets = Subnet.objects
142 09b76b7e Christos Stavrakakis
        if for_update:
143 09b76b7e Christos Stavrakakis
            subnets.select_for_update()
144 09b76b7e Christos Stavrakakis
        return subnets.get(id=subnet_id)
145 a17ce1de Dionysis Grigoropoulos
    except Subnet.DoesNotExist:
146 a17ce1de Dionysis Grigoropoulos
        raise CommandError("Subnet with ID %s not found in DB."
147 a17ce1de Dionysis Grigoropoulos
                           " Use snf-manage subnet-list to find out"
148 a17ce1de Dionysis Grigoropoulos
                           " available subnet IDs" % subnet_id)
149 a17ce1de Dionysis Grigoropoulos
150 a17ce1de Dionysis Grigoropoulos
151 09b76b7e Christos Stavrakakis
def get_port(port_id, for_update=True):
152 09b76b7e Christos Stavrakakis
    """Get a port object by its ID."""
153 09b76b7e Christos Stavrakakis
    try:
154 4a769fc0 Dionysis Grigoropoulos
        port_id = int(port_id)
155 4a769fc0 Dionysis Grigoropoulos
    except (ValueError, TypeError):
156 4a769fc0 Dionysis Grigoropoulos
        raise CommandError("Invalid port ID: %s" % port_id)
157 4a769fc0 Dionysis Grigoropoulos
158 4a769fc0 Dionysis Grigoropoulos
    try:
159 09b76b7e Christos Stavrakakis
        ports = NetworkInterface.objects
160 09b76b7e Christos Stavrakakis
        if for_update:
161 09b76b7e Christos Stavrakakis
            ports.select_for_update()
162 09b76b7e Christos Stavrakakis
        return ports.get(id=port_id)
163 09b76b7e Christos Stavrakakis
    except NetworkInterface.DoesNotExist:
164 09b76b7e Christos Stavrakakis
        raise CommandError("Port with ID %s not found in DB."
165 09b76b7e Christos Stavrakakis
                           " Use snf-manage port-list to find out"
166 09b76b7e Christos Stavrakakis
                           " available port IDs" % port_id)
167 09b76b7e Christos Stavrakakis
168 09b76b7e Christos Stavrakakis
169 b84ed662 Christos Stavrakakis
def get_flavor(flavor_id):
170 b84ed662 Christos Stavrakakis
    try:
171 b84ed662 Christos Stavrakakis
        flavor_id = int(flavor_id)
172 b84ed662 Christos Stavrakakis
        return Flavor.objects.get(id=flavor_id)
173 b84ed662 Christos Stavrakakis
    except ValueError:
174 b84ed662 Christos Stavrakakis
        raise CommandError("Invalid flavor ID: %s", flavor_id)
175 b84ed662 Christos Stavrakakis
    except Flavor.DoesNotExist:
176 b84ed662 Christos Stavrakakis
        raise CommandError("Flavor with ID %s not found in DB."
177 b84ed662 Christos Stavrakakis
                           " Use snf-manage flavor-list to find out"
178 b84ed662 Christos Stavrakakis
                           " available flavor IDs." % flavor_id)
179 bad9404c Christos Stavrakakis
180 bad9404c Christos Stavrakakis
181 9d1e6480 Marios Kogias
def get_floating_ip_by_address(address, for_update=False):
182 9d1e6480 Marios Kogias
    try:
183 9d1e6480 Marios Kogias
        objects = IPAddress.objects
184 9d1e6480 Marios Kogias
        if for_update:
185 9d1e6480 Marios Kogias
            objects = objects.select_for_update()
186 9d1e6480 Marios Kogias
        return objects.get(floating_ip=True, address=address, deleted=False)
187 9d1e6480 Marios Kogias
    except IPAddress.DoesNotExist:
188 9d1e6480 Marios Kogias
        raise CommandError("Floating IP does not exist.")
189 9d1e6480 Marios Kogias
190 9d1e6480 Marios Kogias
191 0fc4b580 Marios Kogias
def get_floating_ip_log_by_address(address):
192 0fc4b580 Marios Kogias
    try:
193 0fc4b580 Marios Kogias
        objects = IPAddressLog.objects
194 0fc4b580 Marios Kogias
        return objects.filter(address=address).order_by("released_at")
195 0fc4b580 Marios Kogias
    except IPAddressLog.DoesNotExist:
196 0fc4b580 Marios Kogias
        raise CommandError("Floating IP does not exist or it hasn't be"
197 0fc4b580 Marios Kogias
                           "attached to any server yet")
198 0fc4b580 Marios Kogias
199 0fc4b580 Marios Kogias
200 79f4eec0 Christos Stavrakakis
def get_floating_ip_by_id(floating_ip_id, for_update=False):
201 79f4eec0 Christos Stavrakakis
    try:
202 4a769fc0 Dionysis Grigoropoulos
        floating_ip_id = int(floating_ip_id)
203 4a769fc0 Dionysis Grigoropoulos
    except (ValueError, TypeError):
204 4a769fc0 Dionysis Grigoropoulos
        raise CommandError("Invalid floating-ip ID: %s" % floating_ip_id)
205 4a769fc0 Dionysis Grigoropoulos
206 4a769fc0 Dionysis Grigoropoulos
    try:
207 79f4eec0 Christos Stavrakakis
        objects = IPAddress.objects
208 79f4eec0 Christos Stavrakakis
        if for_update:
209 79f4eec0 Christos Stavrakakis
            objects = objects.select_for_update()
210 79f4eec0 Christos Stavrakakis
        return objects.get(floating_ip=True, id=floating_ip_id, deleted=False)
211 79f4eec0 Christos Stavrakakis
    except IPAddress.DoesNotExist:
212 4a769fc0 Dionysis Grigoropoulos
        raise CommandError("Floating IP %s does not exist." % floating_ip_id)
213 79f4eec0 Christos Stavrakakis
214 79f4eec0 Christos Stavrakakis
215 2333a2c4 Christos Stavrakakis
def check_backend_credentials(clustername, port, username, password):
216 2333a2c4 Christos Stavrakakis
    try:
217 2333a2c4 Christos Stavrakakis
        client = GanetiRapiClient(clustername, port, username, password)
218 2333a2c4 Christos Stavrakakis
        # This command will raise an exception if there is no
219 2333a2c4 Christos Stavrakakis
        # write-access
220 2333a2c4 Christos Stavrakakis
        client.ModifyCluster()
221 2333a2c4 Christos Stavrakakis
    except GanetiApiError as e:
222 2333a2c4 Christos Stavrakakis
        raise CommandError(e)
223 2333a2c4 Christos Stavrakakis
224 2333a2c4 Christos Stavrakakis
    info = client.GetInfo()
225 2333a2c4 Christos Stavrakakis
    info_name = info['name']
226 2333a2c4 Christos Stavrakakis
    if info_name != clustername:
227 2333a2c4 Christos Stavrakakis
        raise CommandError("Invalid clustername value. Please use the"
228 2333a2c4 Christos Stavrakakis
                           " Ganeti Cluster name: %s" % info_name)
229 7a0aa449 Christos Stavrakakis
230 7a0aa449 Christos Stavrakakis
231 c75ab92e Christos Stavrakakis
def convert_api_faults(func):
232 c75ab92e Christos Stavrakakis
    @wraps(func)
233 c75ab92e Christos Stavrakakis
    def wrapper(*args, **kwargs):
234 c75ab92e Christos Stavrakakis
        try:
235 c75ab92e Christos Stavrakakis
            return func(*args, **kwargs)
236 c75ab92e Christos Stavrakakis
        except faults.Fault as e:
237 c75ab92e Christos Stavrakakis
            raise CommandError(e.message)
238 c75ab92e Christos Stavrakakis
    return wrapper
239 c75ab92e Christos Stavrakakis
240 c75ab92e Christos Stavrakakis
241 4500650c Stratos Psomadakis
class Omit(object):
242 4500650c Stratos Psomadakis
    pass
243 35f2fc07 Christos Stavrakakis
244 35f2fc07 Christos Stavrakakis
245 35f2fc07 Christos Stavrakakis
def wait_server_task(server, wait, stdout):
246 35f2fc07 Christos Stavrakakis
    jobID = server.task_job_id
247 35f2fc07 Christos Stavrakakis
    if wait:
248 35f2fc07 Christos Stavrakakis
        msg = "Issued job '%s'. Waiting to complete...\n"
249 35f2fc07 Christos Stavrakakis
        stdout.write(msg % jobID)
250 35f2fc07 Christos Stavrakakis
        client = server.get_client()
251 35f2fc07 Christos Stavrakakis
        wait_ganeti_job(client, jobID, stdout)
252 35f2fc07 Christos Stavrakakis
    else:
253 35f2fc07 Christos Stavrakakis
        msg = "Issued job '%s'.\n"
254 35f2fc07 Christos Stavrakakis
        stdout.write(msg % jobID)
255 35f2fc07 Christos Stavrakakis
256 35f2fc07 Christos Stavrakakis
257 35f2fc07 Christos Stavrakakis
def wait_ganeti_job(client, jobID, stdout):
258 35f2fc07 Christos Stavrakakis
    status, error = backend_mod.wait_for_job(client, jobID)
259 35f2fc07 Christos Stavrakakis
    if status == "success":
260 35f2fc07 Christos Stavrakakis
        stdout.write("Job finished successfully.\n")
261 35f2fc07 Christos Stavrakakis
    else:
262 35f2fc07 Christos Stavrakakis
        raise CommandError("Job failed! Error: %s\n" % error)
263 b48697f0 Christos Stavrakakis
264 b48697f0 Christos Stavrakakis
265 b48697f0 Christos Stavrakakis
def pool_table_from_type(type_):
266 b48697f0 Christos Stavrakakis
    if type_ == "mac-prefix":
267 b48697f0 Christos Stavrakakis
        return MacPrefixPoolTable
268 b48697f0 Christos Stavrakakis
    elif type_ == "bridge":
269 b48697f0 Christos Stavrakakis
        return BridgePoolTable
270 b48697f0 Christos Stavrakakis
    # elif type == "ip":
271 b48697f0 Christos Stavrakakis
    #     return IPPoolTable
272 b48697f0 Christos Stavrakakis
    else:
273 b48697f0 Christos Stavrakakis
        raise ValueError("Invalid pool type")