Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / management / common.py @ 7a0aa449

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

225 7a0aa449 Christos Stavrakakis
    Works by finding out the max width of each column and padding to data
226 7a0aa449 Christos Stavrakakis
    to this value.
227 7a0aa449 Christos Stavrakakis
    """
228 7a0aa449 Christos Stavrakakis
229 7a0aa449 Christos Stavrakakis
    sep = separator if separator else "  "
230 7a0aa449 Christos Stavrakakis
231 7a0aa449 Christos Stavrakakis
    if headers:
232 7a0aa449 Christos Stavrakakis
        table.insert(0, headers)
233 7a0aa449 Christos Stavrakakis
234 7a0aa449 Christos Stavrakakis
    # Find out the max width of each column
235 7a0aa449 Christos Stavrakakis
    widths = [max(map(len, col)) for col in zip(*table)]
236 7a0aa449 Christos Stavrakakis
237 7a0aa449 Christos Stavrakakis
    t_length = sum(widths) + len(sep) * (len(widths) - 1)
238 7a0aa449 Christos Stavrakakis
    if headers:
239 7a0aa449 Christos Stavrakakis
        # pretty print the headers
240 7a0aa449 Christos Stavrakakis
        print >> out, sep.join((val.rjust(width) for val, width \
241 7a0aa449 Christos Stavrakakis
                                                 in zip(headers, widths)))
242 7a0aa449 Christos Stavrakakis
        print >> out, "-" * t_length
243 7a0aa449 Christos Stavrakakis
        # remove headers
244 7a0aa449 Christos Stavrakakis
        table = table[1:]
245 7a0aa449 Christos Stavrakakis
246 7a0aa449 Christos Stavrakakis
    # print the rest table
247 7a0aa449 Christos Stavrakakis
    for row in table:
248 7a0aa449 Christos Stavrakakis
        print >> out, sep.join((val.rjust(width).encode('utf8') \
249 7a0aa449 Christos Stavrakakis
                                for val, width in zip(row, widths)))