Statistics
| Branch: | Tag: | Revision:

root / api / actions.py @ 7584d408

History | View | Annotate | Download (7.2 kB)

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

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

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

    
17

    
18
server_actions = {}
19

    
20
rapi = GanetiRapiClient(*settings.GANETI_CLUSTER_INFO)
21

    
22

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

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

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

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

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

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

    
76
    request_vnc_forwarding(sport, daddr, dport, passwd)
77
    vnc = { 'host': '62.217.120.67', 'port': sport, 'password': passwd }
78

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

    
87
    return HttpResponse(data, mimetype=mimetype, status=200)
88

    
89

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

    
107
    raise ServiceUnavailable()
108

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

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

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

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

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

    
162
    raise ServiceUnavailable()
163

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

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

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

    
210
    raise ResizeNotAllowed()