Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / management / common.py @ 225cea18

History | View | Annotate | Download (7.2 kB)

1
# Copyright 2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from django.core.management import CommandError
35
from synnefo.db.models import Backend, VirtualMachine, Network, Flavor
36
from synnefo.api.util import get_image as backend_get_image
37
from synnefo.api.faults import ItemNotFound, BadRequest, OverLimit
38

    
39
from synnefo.api.util import validate_network_params
40
from synnefo.settings import (CYCLADES_ASTAKOS_SERVICE_TOKEN as ASTAKOS_TOKEN,
41
                              ASTAKOS_URL)
42
from synnefo.logic.rapi import GanetiApiError, GanetiRapiClient
43
from synnefo.lib import astakos
44

    
45
import logging
46
log = logging.getLogger(__name__)
47

    
48

    
49
def format_vm_state(vm):
50
    if vm.operstate == "BUILD":
51
        return "BUILD(" + str(vm.buildpercentage) + "%)"
52
    else:
53
        return vm.operstate
54

    
55

    
56
def validate_network_info(options):
57
    subnet = options['subnet']
58
    gateway = options['gateway']
59
    subnet6 = options['subnet6']
60
    gateway6 = options['gateway6']
61

    
62
    try:
63
        validate_network_params(subnet, gateway)
64
    except (BadRequest, OverLimit) as e:
65
        raise CommandError(e)
66

    
67
    return subnet, gateway, subnet6, gateway6
68

    
69

    
70
def get_backend(backend_id):
71
    try:
72
        backend_id = int(backend_id)
73
        return Backend.objects.get(id=backend_id)
74
    except ValueError:
75
        raise CommandError("Invalid Backend ID: %s" % backend_id)
76
    except Backend.DoesNotExist:
77
        raise CommandError("Backend with ID %s not found in DB. "
78
                           " Use snf-manage backend-list to find"
79
                           " out available backend IDs." % backend_id)
80

    
81

    
82
def get_image(image_id, user_id):
83
    if image_id:
84
        try:
85
            return backend_get_image(image_id, user_id)
86
        except ItemNotFound:
87
            raise CommandError("Image with ID %s not found."
88
                               " Use snf-manage image-list to find"
89
                               " out available image IDs." % image_id)
90
    else:
91
        raise CommandError("image-id is mandatory")
92

    
93

    
94
def get_vm(server_id):
95
    try:
96
        server_id = int(server_id)
97
        return VirtualMachine.objects.get(id=server_id)
98
    except ValueError:
99
        raise CommandError("Invalid server ID: %s", server_id)
100
    except VirtualMachine.DoesNotExist:
101
        raise CommandError("Server with ID %s not found in DB."
102
                           " Use snf-manage server-list to find out"
103
                           " available server IDs." % server_id)
104

    
105

    
106
def get_network(network_id):
107
    try:
108
        network_id = int(network_id)
109
        return Network.objects.get(id=network_id)
110
    except ValueError:
111
        raise CommandError("Invalid network ID: %s", network_id)
112
    except Network.DoesNotExist:
113
        raise CommandError("Network with ID %s not found in DB."
114
                           " Use snf-manage network-list to find out"
115
                           " available network IDs." % network_id)
116

    
117

    
118
def get_flavor(flavor_id):
119
    try:
120
        flavor_id = int(flavor_id)
121
        return Flavor.objects.get(id=flavor_id)
122
    except ValueError:
123
        raise CommandError("Invalid flavor ID: %s", flavor_id)
124
    except Flavor.DoesNotExist:
125
        raise CommandError("Flavor with ID %s not found in DB."
126
                           " Use snf-manage flavor-list to find out"
127
                           " available flavor IDs." % flavor_id)
128

    
129

    
130
def check_backend_credentials(clustername, port, username, password):
131
    try:
132
        client = GanetiRapiClient(clustername, port, username, password)
133
        # This command will raise an exception if there is no
134
        # write-access
135
        client.ModifyCluster()
136
    except GanetiApiError as e:
137
        raise CommandError(e)
138

    
139
    info = client.GetInfo()
140
    info_name = info['name']
141
    if info_name != clustername:
142
        raise CommandError("Invalid clustername value. Please use the"
143
                           " Ganeti Cluster name: %s" % info_name)
144

    
145

    
146
class UserCache(object):
147
    """uuid<->displayname user 'cache'"""
148

    
149
    user_catalogs_url = ASTAKOS_URL.replace("im/authenticate",
150
                                            "service/api/user_catalogs")
151

    
152
    def __init__(self, split=100):
153
        self.users = {}
154

    
155
        self.split = split
156
        assert(self.split > 0), "split must be positive"
157

    
158
    def fetch_names(self, uuid_list):
159
        total = len(uuid_list)
160
        split = self.split
161

    
162
        for start in range(0, total, split):
163
            end = start + split
164
            try:
165
                names = \
166
                    astakos.get_displaynames(token=ASTAKOS_TOKEN,
167
                                             url=UserCache.user_catalogs_url,
168
                                             uuids=uuid_list[start:end])
169
                self.users.update(names)
170
            except Exception as e:
171
                log.error("Failed to fetch names: %s",  e)
172

    
173
    def get_uuid(self, name):
174
        if not name in self.users:
175
            try:
176
                self.users[name] = \
177
                    astakos.get_user_uuid(token=ASTAKOS_TOKEN,
178
                                          url=UserCache.user_catalogs_url,
179
                                          displayname=name)
180
            except Exception as e:
181
                log.error("Can not get uuid for name %s: %s", name, e)
182
                self.users[name] = name
183

    
184
        return self.users[name]
185

    
186
    def get_name(self, uuid):
187
        """Do the uuid-to-email resolving"""
188

    
189
        if not uuid in self.users:
190
            try:
191
                self.users[uuid] = \
192
                    astakos.get_displayname(token=ASTAKOS_TOKEN,
193
                                            url=UserCache.user_catalogs_url,
194
                                            uuid=uuid)
195
            except Exception as e:
196
                log.error("Can not get display name for uuid %s: %s", uuid, e)
197
                self.users[uuid] = "-"
198

    
199
        return self.users[uuid]
200

    
201

    
202
class Omit(object):
203
    pass