Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / management / common.py @ 2d30ccdd

History | View | Annotate | Download (9.1 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 b84ed662 Christos Stavrakakis
35 53b9ba10 Christos Stavrakakis
import ipaddr
36 11300d7b Giorgos Verigakis
from datetime import datetime
37 11300d7b Giorgos Verigakis
38 11300d7b Giorgos Verigakis
from django.utils.timesince import timesince, timeuntil
39 b84ed662 Christos Stavrakakis
40 53b9ba10 Christos Stavrakakis
from django.core.management import CommandError
41 b84ed662 Christos Stavrakakis
from synnefo.db.models import Backend, VirtualMachine, Network, Flavor
42 b84ed662 Christos Stavrakakis
from synnefo.api.util import get_image as backend_get_image
43 b84ed662 Christos Stavrakakis
from synnefo.api.faults import ItemNotFound
44 bad9404c Christos Stavrakakis
from django.core.exceptions import FieldError
45 bad9404c Christos Stavrakakis
46 53b9ba10 Christos Stavrakakis
from synnefo.api.util import validate_network_size
47 3170076a Stratos Psomadakis
from synnefo.settings import (MAX_CIDR_BLOCK, CYCLADES_ASTAKOS_SERVICE_TOKEN,
48 3170076a Stratos Psomadakis
                              ASTAKOS_URL)
49 2333a2c4 Christos Stavrakakis
from synnefo.logic.rapi import GanetiApiError, GanetiRapiClient
50 3170076a Stratos Psomadakis
from synnefo.lib import astakos
51 11300d7b Giorgos Verigakis
52 11300d7b Giorgos Verigakis
53 11300d7b Giorgos Verigakis
def format_bool(b):
54 11300d7b Giorgos Verigakis
    return 'YES' if b else 'NO'
55 11300d7b Giorgos Verigakis
56 11300d7b Giorgos Verigakis
57 f83ebc98 Christos Stavrakakis
def parse_bool(string):
58 f83ebc98 Christos Stavrakakis
    if string == "True":
59 f83ebc98 Christos Stavrakakis
        return True
60 f83ebc98 Christos Stavrakakis
    elif string == "False":
61 f83ebc98 Christos Stavrakakis
        return False
62 f83ebc98 Christos Stavrakakis
    else:
63 f83ebc98 Christos Stavrakakis
        raise Exception("Can not parse string %s to bool" % string)
64 f83ebc98 Christos Stavrakakis
65 f83ebc98 Christos Stavrakakis
66 11300d7b Giorgos Verigakis
def format_date(d):
67 11300d7b Giorgos Verigakis
    if not d:
68 11300d7b Giorgos Verigakis
        return ''
69 11300d7b Giorgos Verigakis
70 11300d7b Giorgos Verigakis
    if d < datetime.now():
71 11300d7b Giorgos Verigakis
        return timesince(d) + ' ago'
72 11300d7b Giorgos Verigakis
    else:
73 11300d7b Giorgos Verigakis
        return 'in ' + timeuntil(d)
74 f66d8b04 Christos Stavrakakis
75 f66d8b04 Christos Stavrakakis
76 f66d8b04 Christos Stavrakakis
def format_vm_state(vm):
77 f66d8b04 Christos Stavrakakis
    if vm.operstate == "BUILD":
78 f66d8b04 Christos Stavrakakis
        return "BUILD(" + str(vm.buildpercentage) + "%)"
79 f66d8b04 Christos Stavrakakis
    else:
80 f66d8b04 Christos Stavrakakis
        return vm.operstate
81 53b9ba10 Christos Stavrakakis
82 53b9ba10 Christos Stavrakakis
83 53b9ba10 Christos Stavrakakis
def validate_network_info(options):
84 53b9ba10 Christos Stavrakakis
    subnet = options['subnet']
85 53b9ba10 Christos Stavrakakis
    gateway = options['gateway']
86 53b9ba10 Christos Stavrakakis
    subnet6 = options['subnet6']
87 53b9ba10 Christos Stavrakakis
    gateway6 = options['gateway6']
88 53b9ba10 Christos Stavrakakis
89 53b9ba10 Christos Stavrakakis
    try:
90 53b9ba10 Christos Stavrakakis
        net = ipaddr.IPv4Network(subnet)
91 53b9ba10 Christos Stavrakakis
        prefix = net.prefixlen
92 53b9ba10 Christos Stavrakakis
        if not validate_network_size(prefix):
93 53b9ba10 Christos Stavrakakis
            raise CommandError("Unsupport network mask %d."
94 53b9ba10 Christos Stavrakakis
                               " Must be in range (%s,29] "
95 53b9ba10 Christos Stavrakakis
                               % (prefix, MAX_CIDR_BLOCK))
96 53b9ba10 Christos Stavrakakis
    except ValueError:
97 53b9ba10 Christos Stavrakakis
        raise CommandError('Malformed subnet')
98 53b9ba10 Christos Stavrakakis
    try:
99 53b9ba10 Christos Stavrakakis
        gateway and ipaddr.IPv4Address(gateway) or None
100 53b9ba10 Christos Stavrakakis
    except ValueError:
101 53b9ba10 Christos Stavrakakis
        raise CommandError('Malformed gateway')
102 53b9ba10 Christos Stavrakakis
103 53b9ba10 Christos Stavrakakis
    try:
104 53b9ba10 Christos Stavrakakis
        subnet6 and ipaddr.IPv6Network(subnet6) or None
105 53b9ba10 Christos Stavrakakis
    except ValueError:
106 53b9ba10 Christos Stavrakakis
        raise CommandError('Malformed subnet6')
107 53b9ba10 Christos Stavrakakis
108 53b9ba10 Christos Stavrakakis
    try:
109 53b9ba10 Christos Stavrakakis
        gateway6 and ipaddr.IPv6Address(gateway6) or None
110 53b9ba10 Christos Stavrakakis
    except ValueError:
111 53b9ba10 Christos Stavrakakis
        raise CommandError('Malformed gateway6')
112 53b9ba10 Christos Stavrakakis
113 53b9ba10 Christos Stavrakakis
    return subnet, gateway, subnet6, gateway6
114 b84ed662 Christos Stavrakakis
115 b84ed662 Christos Stavrakakis
116 b84ed662 Christos Stavrakakis
def get_backend(backend_id):
117 b84ed662 Christos Stavrakakis
    try:
118 b84ed662 Christos Stavrakakis
        backend_id = int(backend_id)
119 b84ed662 Christos Stavrakakis
        return Backend.objects.get(id=backend_id)
120 b84ed662 Christos Stavrakakis
    except ValueError:
121 b84ed662 Christos Stavrakakis
        raise CommandError("Invalid Backend ID: %s" % backend_id)
122 b84ed662 Christos Stavrakakis
    except Backend.DoesNotExist:
123 b84ed662 Christos Stavrakakis
        raise CommandError("Backend with ID %s not found in DB. "
124 b84ed662 Christos Stavrakakis
                           " Use snf-manage backend-list to find"
125 b84ed662 Christos Stavrakakis
                           " out available backend IDs." % backend_id)
126 b84ed662 Christos Stavrakakis
127 b84ed662 Christos Stavrakakis
128 b84ed662 Christos Stavrakakis
def get_image(image_id, user_id):
129 b84ed662 Christos Stavrakakis
    if image_id:
130 b84ed662 Christos Stavrakakis
        try:
131 b84ed662 Christos Stavrakakis
            return backend_get_image(image_id, user_id)
132 b84ed662 Christos Stavrakakis
        except ItemNotFound:
133 b84ed662 Christos Stavrakakis
            raise CommandError("Image with ID %s not found."
134 b84ed662 Christos Stavrakakis
                               " Use snf-manage image-list to find"
135 b84ed662 Christos Stavrakakis
                               " out available image IDs." % image_id)
136 b84ed662 Christos Stavrakakis
    else:
137 b84ed662 Christos Stavrakakis
        raise CommandError("image-id is mandatory")
138 b84ed662 Christos Stavrakakis
139 b84ed662 Christos Stavrakakis
140 b84ed662 Christos Stavrakakis
def get_vm(server_id):
141 b84ed662 Christos Stavrakakis
    try:
142 b84ed662 Christos Stavrakakis
        server_id = int(server_id)
143 b84ed662 Christos Stavrakakis
        return VirtualMachine.objects.get(id=server_id)
144 b84ed662 Christos Stavrakakis
    except ValueError:
145 b84ed662 Christos Stavrakakis
        raise CommandError("Invalid server ID: %s", server_id)
146 b84ed662 Christos Stavrakakis
    except VirtualMachine.DoesNotExist:
147 b84ed662 Christos Stavrakakis
        raise CommandError("Server with ID %s not found in DB."
148 b84ed662 Christos Stavrakakis
                           " Use snf-manage server-list to find out"
149 b84ed662 Christos Stavrakakis
                           " available server IDs." % server_id)
150 b84ed662 Christos Stavrakakis
151 b84ed662 Christos Stavrakakis
152 b84ed662 Christos Stavrakakis
def get_network(network_id):
153 b84ed662 Christos Stavrakakis
    try:
154 b84ed662 Christos Stavrakakis
        network_id = int(network_id)
155 b84ed662 Christos Stavrakakis
        return Network.objects.get(id=network_id)
156 b84ed662 Christos Stavrakakis
    except ValueError:
157 b84ed662 Christos Stavrakakis
        raise CommandError("Invalid network ID: %s", network_id)
158 b84ed662 Christos Stavrakakis
    except Network.DoesNotExist:
159 b84ed662 Christos Stavrakakis
        raise CommandError("Network with ID %s not found in DB."
160 b84ed662 Christos Stavrakakis
                           " Use snf-manage network-list to find out"
161 b84ed662 Christos Stavrakakis
                           " available network IDs." % network_id)
162 b84ed662 Christos Stavrakakis
163 b84ed662 Christos Stavrakakis
164 b84ed662 Christos Stavrakakis
def get_flavor(flavor_id):
165 b84ed662 Christos Stavrakakis
    try:
166 b84ed662 Christos Stavrakakis
        flavor_id = int(flavor_id)
167 b84ed662 Christos Stavrakakis
        return Flavor.objects.get(id=flavor_id)
168 b84ed662 Christos Stavrakakis
    except ValueError:
169 b84ed662 Christos Stavrakakis
        raise CommandError("Invalid flavor ID: %s", flavor_id)
170 b84ed662 Christos Stavrakakis
    except Flavor.DoesNotExist:
171 b84ed662 Christos Stavrakakis
        raise CommandError("Flavor with ID %s not found in DB."
172 b84ed662 Christos Stavrakakis
                           " Use snf-manage flavor-list to find out"
173 b84ed662 Christos Stavrakakis
                           " available flavor IDs." % flavor_id)
174 bad9404c Christos Stavrakakis
175 bad9404c Christos Stavrakakis
176 bad9404c Christos Stavrakakis
def filter_results(objects, filter_by):
177 bad9404c Christos Stavrakakis
    filter_list = filter_by.split(",")
178 bad9404c Christos Stavrakakis
    filter_dict = {}
179 bad9404c Christos Stavrakakis
    exclude_dict = {}
180 bad9404c Christos Stavrakakis
181 bad9404c Christos Stavrakakis
    def map_field_type(query):
182 bad9404c Christos Stavrakakis
        def fix_bool(val):
183 bad9404c Christos Stavrakakis
            if val.lower() in ("yes", "true", "t"):
184 bad9404c Christos Stavrakakis
                return True
185 bad9404c Christos Stavrakakis
            if val.lower() in ("no", "false", "f"):
186 bad9404c Christos Stavrakakis
                return False
187 bad9404c Christos Stavrakakis
            return val
188 bad9404c Christos Stavrakakis
189 bad9404c Christos Stavrakakis
        if "!=" in query:
190 bad9404c Christos Stavrakakis
            key, val = query.split("!=")
191 bad9404c Christos Stavrakakis
            exclude_dict[key] = fix_bool(val)
192 bad9404c Christos Stavrakakis
            return
193 bad9404c Christos Stavrakakis
        OP_MAP = {
194 bad9404c Christos Stavrakakis
            ">=": "__gte",
195 bad9404c Christos Stavrakakis
            "=>": "__gte",
196 bad9404c Christos Stavrakakis
            ">":  "__gt",
197 bad9404c Christos Stavrakakis
            "<=": "__lte",
198 bad9404c Christos Stavrakakis
            "=<": "__lte",
199 bad9404c Christos Stavrakakis
            "<":  "__lt",
200 2d30ccdd Stratos Psomadakis
            "=":  "",
201 bad9404c Christos Stavrakakis
        }
202 bad9404c Christos Stavrakakis
        for op, new_op in OP_MAP.items():
203 bad9404c Christos Stavrakakis
            if op in query:
204 bad9404c Christos Stavrakakis
                key, val = query.split(op)
205 bad9404c Christos Stavrakakis
                filter_dict[key + new_op] = fix_bool(val)
206 bad9404c Christos Stavrakakis
                return
207 bad9404c Christos Stavrakakis
208 bad9404c Christos Stavrakakis
    map(lambda x: map_field_type(x), filter_list)
209 bad9404c Christos Stavrakakis
210 bad9404c Christos Stavrakakis
    try:
211 bad9404c Christos Stavrakakis
        objects = objects.filter(**filter_dict)
212 bad9404c Christos Stavrakakis
        return objects.exclude(**exclude_dict)
213 bad9404c Christos Stavrakakis
    except FieldError as e:
214 bad9404c Christos Stavrakakis
        raise CommandError(e)
215 8b3e98f8 Christos Stavrakakis
    except Exception as e:
216 8b3e98f8 Christos Stavrakakis
        raise CommandError("Can not filter results: %s" % e)
217 2333a2c4 Christos Stavrakakis
218 2333a2c4 Christos Stavrakakis
219 2333a2c4 Christos Stavrakakis
def check_backend_credentials(clustername, port, username, password):
220 2333a2c4 Christos Stavrakakis
    try:
221 2333a2c4 Christos Stavrakakis
        client = GanetiRapiClient(clustername, port, username, password)
222 2333a2c4 Christos Stavrakakis
        # This command will raise an exception if there is no
223 2333a2c4 Christos Stavrakakis
        # write-access
224 2333a2c4 Christos Stavrakakis
        client.ModifyCluster()
225 2333a2c4 Christos Stavrakakis
    except GanetiApiError as e:
226 2333a2c4 Christos Stavrakakis
        raise CommandError(e)
227 2333a2c4 Christos Stavrakakis
228 2333a2c4 Christos Stavrakakis
    info = client.GetInfo()
229 2333a2c4 Christos Stavrakakis
    info_name = info['name']
230 2333a2c4 Christos Stavrakakis
    if info_name != clustername:
231 2333a2c4 Christos Stavrakakis
        raise CommandError("Invalid clustername value. Please use the"
232 2333a2c4 Christos Stavrakakis
                           " Ganeti Cluster name: %s" % info_name)
233 7a0aa449 Christos Stavrakakis
234 7a0aa449 Christos Stavrakakis
235 7a0aa449 Christos Stavrakakis
def pprint_table(out, table, headers=None, separator=None):
236 7a0aa449 Christos Stavrakakis
    """Print a pretty, aligned string representation of table.
237 7a0aa449 Christos Stavrakakis

238 7a0aa449 Christos Stavrakakis
    Works by finding out the max width of each column and padding to data
239 7a0aa449 Christos Stavrakakis
    to this value.
240 7a0aa449 Christos Stavrakakis
    """
241 7a0aa449 Christos Stavrakakis
242 7a0aa449 Christos Stavrakakis
    sep = separator if separator else "  "
243 7a0aa449 Christos Stavrakakis
244 7a0aa449 Christos Stavrakakis
    if headers:
245 7a0aa449 Christos Stavrakakis
        table.insert(0, headers)
246 7a0aa449 Christos Stavrakakis
247 7a0aa449 Christos Stavrakakis
    # Find out the max width of each column
248 7a0aa449 Christos Stavrakakis
    widths = [max(map(len, col)) for col in zip(*table)]
249 7a0aa449 Christos Stavrakakis
250 7a0aa449 Christos Stavrakakis
    t_length = sum(widths) + len(sep) * (len(widths) - 1)
251 7a0aa449 Christos Stavrakakis
    if headers:
252 7a0aa449 Christos Stavrakakis
        # pretty print the headers
253 7a0aa449 Christos Stavrakakis
        print >> out, sep.join((val.rjust(width) for val, width \
254 7a0aa449 Christos Stavrakakis
                                                 in zip(headers, widths)))
255 7a0aa449 Christos Stavrakakis
        print >> out, "-" * t_length
256 7a0aa449 Christos Stavrakakis
        # remove headers
257 7a0aa449 Christos Stavrakakis
        table = table[1:]
258 7a0aa449 Christos Stavrakakis
259 7a0aa449 Christos Stavrakakis
    # print the rest table
260 7a0aa449 Christos Stavrakakis
    for row in table:
261 7a0aa449 Christos Stavrakakis
        print >> out, sep.join((val.rjust(width).encode('utf8') \
262 7a0aa449 Christos Stavrakakis
                                for val, width in zip(row, widths)))
263 3170076a Stratos Psomadakis
264 3170076a Stratos Psomadakis
265 3170076a Stratos Psomadakis
class UUIDCache(object):
266 3fa01ebd Stratos Psomadakis
    """UUUID-to-email cache
267 3fa01ebd Stratos Psomadakis

268 3fa01ebd Stratos Psomadakis
    """
269 3fa01ebd Stratos Psomadakis
270 3fa01ebd Stratos Psomadakis
    astakos_url = ASTAKOS_URL.replace("im/authenticate",
271 3fa01ebd Stratos Psomadakis
                                      "service/api/user_catalogs")
272 3fa01ebd Stratos Psomadakis
273 3170076a Stratos Psomadakis
    def __init__(self):
274 3170076a Stratos Psomadakis
        self.users = {}
275 3170076a Stratos Psomadakis
276 3170076a Stratos Psomadakis
    def get_user(self, uuid):
277 3fa01ebd Stratos Psomadakis
        """Do the uuid-to-email resolving
278 3fa01ebd Stratos Psomadakis
        """
279 3fa01ebd Stratos Psomadakis
280 3170076a Stratos Psomadakis
        if not uuid in self.users:
281 3fa01ebd Stratos Psomadakis
            try:
282 3fa01ebd Stratos Psomadakis
                self.users[uuid] = \
283 3fa01ebd Stratos Psomadakis
                astakos.get_displayname(token=CYCLADES_ASTAKOS_SERVICE_TOKEN,
284 3fa01ebd Stratos Psomadakis
                                        url=UUIDCache.astakos_url, uuid=uuid)
285 3fa01ebd Stratos Psomadakis
            except Exception:
286 3fa01ebd Stratos Psomadakis
                return uuid
287 3170076a Stratos Psomadakis
288 3170076a Stratos Psomadakis
        return self.users[uuid]