Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / management / common.py @ 9d1e6480

History | View | Annotate | Download (7.1 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,
36
                               Flavor, IPAddress)
37
from functools import wraps
38

    
39
from snf_django.lib.api import faults
40
from synnefo.api import util
41
from synnefo.logic import backend as backend_mod
42
from synnefo.logic.rapi import GanetiApiError, GanetiRapiClient
43
from synnefo.logic.utils import (id_from_instance_name,
44
                                 id_from_network_name)
45

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

    
49

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

    
56

    
57
def get_backend(backend_id):
58
    try:
59
        backend_id = int(backend_id)
60
        return Backend.objects.get(id=backend_id)
61
    except ValueError:
62
        raise CommandError("Invalid Backend ID: %s" % backend_id)
63
    except Backend.DoesNotExist:
64
        raise CommandError("Backend with ID %s not found in DB. "
65
                           " Use snf-manage backend-list to find"
66
                           " out available backend IDs." % backend_id)
67

    
68

    
69
def get_image(image_id, user_id):
70
    if image_id:
71
        try:
72
            return util.get_image_dict(image_id, user_id)
73
        except faults.ItemNotFound:
74
            raise CommandError("Image with ID %s not found."
75
                               " Use snf-manage image-list to find"
76
                               " out available image IDs." % image_id)
77
    else:
78
        raise CommandError("image-id is mandatory")
79

    
80

    
81
def get_vm(server_id):
82
    """Get a VirtualMachine object by its ID.
83

84
    @type server_id: int or string
85
    @param server_id: The server's DB id or the Ganeti name
86

87
    """
88
    try:
89
        server_id = int(server_id)
90
    except (ValueError, TypeError):
91
        try:
92
            server_id = id_from_instance_name(server_id)
93
        except VirtualMachine.InvalidBackendIdError:
94
            raise CommandError("Invalid server ID: %s" % server_id)
95

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

    
103

    
104
def get_network(network_id, for_update=True):
105
    """Get a Network object by its ID.
106

107
    @type network_id: int or string
108
    @param network_id: The networks DB id or the Ganeti name
109

110
    """
111

    
112
    try:
113
        network_id = int(network_id)
114
    except (ValueError, TypeError):
115
        try:
116
            network_id = id_from_network_name(network_id)
117
        except Network.InvalidBackendIdError:
118
            raise CommandError("Invalid network ID: %s" % network_id)
119

    
120
    networks = Network.objects
121
    if for_update:
122
        networks = networks.select_for_update()
123
    try:
124
        return networks.get(id=network_id)
125
    except Network.DoesNotExist:
126
        raise CommandError("Network with ID %s not found in DB."
127
                           " Use snf-manage network-list to find out"
128
                           " available network IDs." % network_id)
129

    
130

    
131
def get_subnet(subnet_id, for_update=True):
132
    """Get a Subnet object by its ID."""
133
    try:
134
        return Subnet.objects.get(id=subnet_id)
135
    except Subnet.DoesNotExist:
136
        raise CommandError("Subnet with ID %s not found in DB."
137
                           " Use snf-manage subnet-list to find out"
138
                           " available subnet IDs" % subnet_id)
139

    
140

    
141
def get_flavor(flavor_id):
142
    try:
143
        flavor_id = int(flavor_id)
144
        return Flavor.objects.get(id=flavor_id)
145
    except ValueError:
146
        raise CommandError("Invalid flavor ID: %s", flavor_id)
147
    except Flavor.DoesNotExist:
148
        raise CommandError("Flavor with ID %s not found in DB."
149
                           " Use snf-manage flavor-list to find out"
150
                           " available flavor IDs." % flavor_id)
151

    
152

    
153
def get_floating_ip_by_address(address, for_update=False):
154
    try:
155
        objects = IPAddress.objects
156
        if for_update:
157
            objects = objects.select_for_update()
158
        return objects.get(floating_ip=True, address=address, deleted=False)
159
    except IPAddress.DoesNotExist:
160
        raise CommandError("Floating IP does not exist.")
161

    
162

    
163
def check_backend_credentials(clustername, port, username, password):
164
    try:
165
        client = GanetiRapiClient(clustername, port, username, password)
166
        # This command will raise an exception if there is no
167
        # write-access
168
        client.ModifyCluster()
169
    except GanetiApiError as e:
170
        raise CommandError(e)
171

    
172
    info = client.GetInfo()
173
    info_name = info['name']
174
    if info_name != clustername:
175
        raise CommandError("Invalid clustername value. Please use the"
176
                           " Ganeti Cluster name: %s" % info_name)
177

    
178

    
179
def convert_api_faults(func):
180
    @wraps(func)
181
    def wrapper(*args, **kwargs):
182
        try:
183
            return func(*args, **kwargs)
184
        except faults.Fault as e:
185
            raise CommandError(e.message)
186
    return wrapper
187

    
188

    
189
class Omit(object):
190
    pass
191

    
192

    
193
def wait_server_task(server, wait, stdout):
194
    jobID = server.task_job_id
195
    if wait:
196
        msg = "Issued job '%s'. Waiting to complete...\n"
197
        stdout.write(msg % jobID)
198
        client = server.get_client()
199
        wait_ganeti_job(client, jobID, stdout)
200
    else:
201
        msg = "Issued job '%s'.\n"
202
        stdout.write(msg % jobID)
203

    
204

    
205
def wait_ganeti_job(client, jobID, stdout):
206
    status, error = backend_mod.wait_for_job(client, jobID)
207
    if status == "success":
208
        stdout.write("Job finished successfully.\n")
209
    else:
210
        raise CommandError("Job failed! Error: %s\n" % error)