Statistics
| Branch: | Tag: | Revision:

root / api / actions.py @ b216cb77

History | View | Annotate | Download (7.2 kB)

1
#
2
# Copyright (c) 2010 Greek Research and Technology Network
3
#
4

    
5
from socket import getfqdn
6

    
7
from django.conf import settings
8
from django.http import HttpResponse
9
from django.template.loader import render_to_string
10
from django.utils import simplejson as json
11

    
12
from synnefo.api.faults import BadRequest, ResizeNotAllowed, ServiceUnavailable
13
from synnefo.api.util import random_password
14
from synnefo.util.rapi import GanetiRapiClient
15
from synnefo.util.vapclient import request_forwarding as request_vnc_forwarding
16
from synnefo.logic import backend
17
from synnefo.logic.utils import get_rsapi_state
18

    
19

    
20
server_actions = {}
21

    
22
rapi = GanetiRapiClient(*settings.GANETI_CLUSTER_INFO)
23

    
24

    
25
def server_action(name):
26
    '''Decorator for functions implementing server actions.
27
    
28
       `name` is the key in the dict passed by the client.
29
    '''
30
    
31
    def decorator(func):
32
        server_actions[name] = func
33
        return func
34
    return decorator
35

    
36
@server_action('console')
37
def get_console(request, vm, args):
38
    """Arrange for an OOB console of the specified type
39

40
    This method arranges for an OOB console of the specified type.
41
    Only "vnc" type consoles are supported for now.
42
    It uses a running instance of vncauthproxy to setup proper
43
    VNC forwarding with a random password, then returns the necessary
44
    VNC connection info to the caller.
45

46
    """
47
    # Normal Response Code: 200
48
    # Error Response Codes: computeFault (400, 500),
49
    #                       serviceUnavailable (503),
50
    #                       unauthorized (401),
51
    #                       badRequest (400),
52
    #                       badMediaType(415),
53
    #                       itemNotFound (404),
54
    #                       buildInProgress (409),
55
    #                       overLimit (413)
56
    try:
57
        console_type = args.get('type', '')
58
        if console_type != 'VNC':
59
            raise BadRequest(message="type can only be 'VNC'")
60
    except KeyError:
61
        raise BadRequest()
62

    
63
    # Use RAPI to get VNC console information for this instance
64
    if get_rsapi_state(vm) != 'ACTIVE':
65
        raise BadRequest(message="Server not in ACTIVE state")
66
    console_data = rapi.GetInstanceConsole(vm.backend_id)
67
    if console_data['kind'] != 'vnc':
68
        raise ServiceUnavailable()
69

    
70
    # Let vncauthproxy decide on the source port.
71
    # FIXME
72
    # sport = 0
73
    sport = console_data['port'] - 1000
74
    daddr = console_data['host']
75
    dport = console_data['port']
76
    passwd = random_password()
77

    
78
    request_vnc_forwarding(sport, daddr, dport, passwd)
79
    vnc = { 'host': getfqdn(), 'port': sport, 'password': passwd }
80

    
81
    # Format to be reviewed by [verigak], FIXME
82
    if request.serialization == 'xml':
83
        mimetype = 'application/xml'
84
        data = render_to_string('vnc.xml', {'vnc': vnc})
85
    else:
86
        mimetype = 'application/json'
87
        data = json.dumps(vnc)
88

    
89
    return HttpResponse(data, mimetype=mimetype, status=200)
90

    
91

    
92
@server_action('changePassword')
93
def change_password(request, vm, args):
94
    # Normal Response Code: 202
95
    # Error Response Codes: computeFault (400, 500),
96
    #                       serviceUnavailable (503),
97
    #                       unauthorized (401),
98
    #                       badRequest (400),
99
    #                       badMediaType(415),
100
    #                       itemNotFound (404),
101
    #                       buildInProgress (409),
102
    #                       overLimit (413)
103
    
104
    try:
105
        adminPass = args['adminPass']
106
    except KeyError:
107
        raise BadRequest()
108

    
109
    raise ServiceUnavailable()
110

    
111
@server_action('reboot')
112
def reboot(request, vm, args):
113
    # Normal Response Code: 202
114
    # Error Response Codes: computeFault (400, 500),
115
    #                       serviceUnavailable (503),
116
    #                       unauthorized (401),
117
    #                       badRequest (400),
118
    #                       badMediaType(415),
119
    #                       itemNotFound (404),
120
    #                       buildInProgress (409),
121
    #                       overLimit (413)
122
    
123
    reboot_type = args.get('type', '')
124
    if reboot_type not in ('SOFT', 'HARD'):
125
        raise BadRequest()
126
    
127
    backend.start_action(vm, 'REBOOT')
128
    rapi.RebootInstance(vm.backend_id, reboot_type.lower())
129
    return HttpResponse(status=202)
130

    
131
@server_action('start')
132
def start(request, vm, args):
133
    # Normal Response Code: 202
134
    # Error Response Codes: serviceUnavailable (503),
135
    #                       itemNotFound (404)
136

    
137
    backend.start_action(vm, 'START')
138
    rapi.StartupInstance(vm.backend_id)
139
    return HttpResponse(status=202)
140

    
141
@server_action('shutdown')
142
def shutdown(request, vm, args):
143
    # Normal Response Code: 202
144
    # Error Response Codes: serviceUnavailable (503),
145
    #                       itemNotFound (404)
146
    
147
    backend.start_action(vm, 'STOP')
148
    rapi.ShutdownInstance(vm.backend_id)
149
    return HttpResponse(status=202)
150

    
151
@server_action('rebuild')
152
def rebuild(request, vm, args):
153
    # Normal Response Code: 202
154
    # Error Response Codes: computeFault (400, 500),
155
    #                       serviceUnavailable (503),
156
    #                       unauthorized (401),
157
    #                       badRequest (400),
158
    #                       badMediaType(415),
159
    #                       itemNotFound (404),
160
    #                       buildInProgress (409),
161
    #                       serverCapacityUnavailable (503),
162
    #                       overLimit (413)
163

    
164
    raise ServiceUnavailable()
165

    
166
@server_action('resize')
167
def resize(request, vm, args):
168
    # Normal Response Code: 202
169
    # Error Response Codes: computeFault (400, 500),
170
    #                       serviceUnavailable (503),
171
    #                       unauthorized (401),
172
    #                       badRequest (400),
173
    #                       badMediaType(415),
174
    #                       itemNotFound (404),
175
    #                       buildInProgress (409),
176
    #                       serverCapacityUnavailable (503),
177
    #                       overLimit (413),
178
    #                       resizeNotAllowed (403)
179
    
180
    raise ResizeNotAllowed()
181

    
182
@server_action('confirmResize')
183
def confirm_resize(request, vm, args):
184
    # Normal Response Code: 204
185
    # Error Response Codes: computeFault (400, 500),
186
    #                       serviceUnavailable (503),
187
    #                       unauthorized (401),
188
    #                       badRequest (400),
189
    #                       badMediaType(415),
190
    #                       itemNotFound (404),
191
    #                       buildInProgress (409),
192
    #                       serverCapacityUnavailable (503),
193
    #                       overLimit (413),
194
    #                       resizeNotAllowed (403)
195
    
196
    raise ResizeNotAllowed()
197

    
198
@server_action('revertResize')
199
def revert_resize(request, vm, args):
200
    # Normal Response Code: 202
201
    # Error Response Codes: computeFault (400, 500),
202
    #                       serviceUnavailable (503),
203
    #                       unauthorized (401),
204
    #                       badRequest (400),
205
    #                       badMediaType(415),
206
    #                       itemNotFound (404),
207
    #                       buildInProgress (409),
208
    #                       serverCapacityUnavailable (503),
209
    #                       overLimit (413),
210
    #                       resizeNotAllowed (403)
211

    
212
    raise ResizeNotAllowed()