Statistics
| Branch: | Tag: | Revision:

root / api / actions.py @ 7584d408

History | View | Annotate | Download (7.2 kB)

1 b016b476 Giorgos Verigakis
#
2 b016b476 Giorgos Verigakis
# Copyright (c) 2010 Greek Research and Technology Network
3 b016b476 Giorgos Verigakis
#
4 b016b476 Giorgos Verigakis
5 b016b476 Giorgos Verigakis
from django.conf import settings
6 b016b476 Giorgos Verigakis
from django.http import HttpResponse
7 09471611 Vangelis Koukis
from django.template.loader import render_to_string
8 09471611 Vangelis Koukis
from django.utils import simplejson as json
9 b016b476 Giorgos Verigakis
10 d8e50a39 Giorgos Verigakis
from synnefo.api.faults import BadRequest, ResizeNotAllowed, ServiceUnavailable
11 09471611 Vangelis Koukis
from synnefo.api.util import random_password
12 0971fa71 Markos Gogoulos
from synnefo.util.rapi import GanetiRapiClient
13 09471611 Vangelis Koukis
from synnefo.util.vapclient import request_forwarding as request_vnc_forwarding
14 d8e50a39 Giorgos Verigakis
from synnefo.logic import backend
15 20a51b1e Giorgos Verigakis
from synnefo.logic.utils import get_rsapi_state
16 d8e50a39 Giorgos Verigakis
17 0971fa71 Markos Gogoulos
18 b016b476 Giorgos Verigakis
server_actions = {}
19 b016b476 Giorgos Verigakis
20 b016b476 Giorgos Verigakis
rapi = GanetiRapiClient(*settings.GANETI_CLUSTER_INFO)
21 b016b476 Giorgos Verigakis
22 b016b476 Giorgos Verigakis
23 b016b476 Giorgos Verigakis
def server_action(name):
24 d8e50a39 Giorgos Verigakis
    '''Decorator for functions implementing server actions.
25 d8e50a39 Giorgos Verigakis
    
26 d8e50a39 Giorgos Verigakis
       `name` is the key in the dict passed by the client.
27 d8e50a39 Giorgos Verigakis
    '''
28 d8e50a39 Giorgos Verigakis
    
29 b016b476 Giorgos Verigakis
    def decorator(func):
30 b016b476 Giorgos Verigakis
        server_actions[name] = func
31 b016b476 Giorgos Verigakis
        return func
32 b016b476 Giorgos Verigakis
    return decorator
33 b016b476 Giorgos Verigakis
34 09471611 Vangelis Koukis
@server_action('console')
35 20a51b1e Giorgos Verigakis
def get_console(request, vm, args):
36 09471611 Vangelis Koukis
    """Arrange for an OOB console of the specified type
37 09471611 Vangelis Koukis

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

44 09471611 Vangelis Koukis
    """
45 09471611 Vangelis Koukis
    # Normal Response Code: 200
46 09471611 Vangelis Koukis
    # Error Response Codes: computeFault (400, 500),
47 09471611 Vangelis Koukis
    #                       serviceUnavailable (503),
48 09471611 Vangelis Koukis
    #                       unauthorized (401),
49 09471611 Vangelis Koukis
    #                       badRequest (400),
50 09471611 Vangelis Koukis
    #                       badMediaType(415),
51 09471611 Vangelis Koukis
    #                       itemNotFound (404),
52 09471611 Vangelis Koukis
    #                       buildInProgress (409),
53 09471611 Vangelis Koukis
    #                       overLimit (413)
54 09471611 Vangelis Koukis
    try:
55 09471611 Vangelis Koukis
        console_type = args.get('type', '')
56 09471611 Vangelis Koukis
        if console_type != 'VNC':
57 09471611 Vangelis Koukis
            raise BadRequest(message="type can only be 'VNC'")
58 09471611 Vangelis Koukis
    except KeyError:
59 09471611 Vangelis Koukis
        raise BadRequest()
60 09471611 Vangelis Koukis
61 09471611 Vangelis Koukis
    # Use RAPI to get VNC console information for this instance
62 20a51b1e Giorgos Verigakis
    if get_rsapi_state(vm) != 'ACTIVE':
63 09471611 Vangelis Koukis
        raise BadRequest(message="Server not in ACTIVE state")
64 20a51b1e Giorgos Verigakis
    console_data = rapi.GetInstanceConsole(vm.backend_id)
65 09471611 Vangelis Koukis
    if console_data['kind'] != 'vnc':
66 09471611 Vangelis Koukis
        raise ServiceUnavailable()
67 09471611 Vangelis Koukis
68 09471611 Vangelis Koukis
    # Let vncauthproxy decide on the source port.
69 09471611 Vangelis Koukis
    # FIXME
70 09471611 Vangelis Koukis
    # sport = 0
71 09471611 Vangelis Koukis
    sport = console_data['port'] - 1000
72 09471611 Vangelis Koukis
    daddr = console_data['host']
73 09471611 Vangelis Koukis
    dport = console_data['port']
74 09471611 Vangelis Koukis
    passwd = random_password()
75 09471611 Vangelis Koukis
76 09471611 Vangelis Koukis
    request_vnc_forwarding(sport, daddr, dport, passwd)
77 09471611 Vangelis Koukis
    vnc = { 'host': '62.217.120.67', 'port': sport, 'password': passwd }
78 09471611 Vangelis Koukis
79 09471611 Vangelis Koukis
    # Format to be reviewed by [verigak], FIXME
80 09471611 Vangelis Koukis
    if request.type == 'xml':
81 09471611 Vangelis Koukis
        mimetype = 'application/xml'
82 09471611 Vangelis Koukis
        data = render_to_string('vnc.xml', {'vnc': vnc})
83 09471611 Vangelis Koukis
    else:
84 09471611 Vangelis Koukis
        mimetype = 'application/json'
85 09471611 Vangelis Koukis
        data = json.dumps(vnc)
86 09471611 Vangelis Koukis
87 09471611 Vangelis Koukis
    return HttpResponse(data, mimetype=mimetype, status=200)
88 09471611 Vangelis Koukis
89 b016b476 Giorgos Verigakis
90 b016b476 Giorgos Verigakis
@server_action('changePassword')
91 20a51b1e Giorgos Verigakis
def change_password(request, vm, args):
92 b016b476 Giorgos Verigakis
    # Normal Response Code: 202
93 b016b476 Giorgos Verigakis
    # Error Response Codes: computeFault (400, 500),
94 b016b476 Giorgos Verigakis
    #                       serviceUnavailable (503),
95 b016b476 Giorgos Verigakis
    #                       unauthorized (401),
96 b016b476 Giorgos Verigakis
    #                       badRequest (400),
97 b016b476 Giorgos Verigakis
    #                       badMediaType(415),
98 b016b476 Giorgos Verigakis
    #                       itemNotFound (404),
99 b016b476 Giorgos Verigakis
    #                       buildInProgress (409),
100 b016b476 Giorgos Verigakis
    #                       overLimit (413)
101 b016b476 Giorgos Verigakis
    
102 b016b476 Giorgos Verigakis
    try:
103 b016b476 Giorgos Verigakis
        adminPass = args['adminPass']
104 b016b476 Giorgos Verigakis
    except KeyError:
105 b016b476 Giorgos Verigakis
        raise BadRequest()
106 b016b476 Giorgos Verigakis
107 b016b476 Giorgos Verigakis
    raise ServiceUnavailable()
108 b016b476 Giorgos Verigakis
109 b016b476 Giorgos Verigakis
@server_action('reboot')
110 20a51b1e Giorgos Verigakis
def reboot(request, vm, args):
111 b016b476 Giorgos Verigakis
    # Normal Response Code: 202
112 b016b476 Giorgos Verigakis
    # Error Response Codes: computeFault (400, 500),
113 b016b476 Giorgos Verigakis
    #                       serviceUnavailable (503),
114 b016b476 Giorgos Verigakis
    #                       unauthorized (401),
115 b016b476 Giorgos Verigakis
    #                       badRequest (400),
116 b016b476 Giorgos Verigakis
    #                       badMediaType(415),
117 b016b476 Giorgos Verigakis
    #                       itemNotFound (404),
118 b016b476 Giorgos Verigakis
    #                       buildInProgress (409),
119 b016b476 Giorgos Verigakis
    #                       overLimit (413)
120 b016b476 Giorgos Verigakis
    
121 0971fa71 Markos Gogoulos
    reboot_type = args.get('type', '')
122 0971fa71 Markos Gogoulos
    if reboot_type not in ('SOFT', 'HARD'):
123 b016b476 Giorgos Verigakis
        raise BadRequest()
124 b016b476 Giorgos Verigakis
    
125 d8e50a39 Giorgos Verigakis
    backend.start_action(vm, 'REBOOT')
126 d8e50a39 Giorgos Verigakis
    rapi.RebootInstance(vm.backend_id, reboot_type.lower())
127 b016b476 Giorgos Verigakis
    return HttpResponse(status=202)
128 b016b476 Giorgos Verigakis
129 b016b476 Giorgos Verigakis
@server_action('start')
130 20a51b1e Giorgos Verigakis
def start(request, vm, args):
131 b016b476 Giorgos Verigakis
    # Normal Response Code: 202
132 d8e50a39 Giorgos Verigakis
    # Error Response Codes: serviceUnavailable (503),
133 d8e50a39 Giorgos Verigakis
    #                       itemNotFound (404)
134 b016b476 Giorgos Verigakis
135 d8e50a39 Giorgos Verigakis
    backend.start_action(vm, 'START')
136 d8e50a39 Giorgos Verigakis
    rapi.StartupInstance(vm.backend_id)
137 b016b476 Giorgos Verigakis
    return HttpResponse(status=202)
138 b016b476 Giorgos Verigakis
139 b016b476 Giorgos Verigakis
@server_action('shutdown')
140 20a51b1e Giorgos Verigakis
def shutdown(request, vm, args):
141 b016b476 Giorgos Verigakis
    # Normal Response Code: 202
142 d8e50a39 Giorgos Verigakis
    # Error Response Codes: serviceUnavailable (503),
143 d8e50a39 Giorgos Verigakis
    #                       itemNotFound (404)
144 b016b476 Giorgos Verigakis
    
145 d8e50a39 Giorgos Verigakis
    backend.start_action(vm, 'STOP')
146 d8e50a39 Giorgos Verigakis
    rapi.ShutdownInstance(vm.backend_id)
147 b016b476 Giorgos Verigakis
    return HttpResponse(status=202)
148 b016b476 Giorgos Verigakis
149 b016b476 Giorgos Verigakis
@server_action('rebuild')
150 20a51b1e Giorgos Verigakis
def rebuild(request, vm, args):
151 b016b476 Giorgos Verigakis
    # Normal Response Code: 202
152 b016b476 Giorgos Verigakis
    # Error Response Codes: computeFault (400, 500),
153 b016b476 Giorgos Verigakis
    #                       serviceUnavailable (503),
154 b016b476 Giorgos Verigakis
    #                       unauthorized (401),
155 b016b476 Giorgos Verigakis
    #                       badRequest (400),
156 b016b476 Giorgos Verigakis
    #                       badMediaType(415),
157 b016b476 Giorgos Verigakis
    #                       itemNotFound (404),
158 b016b476 Giorgos Verigakis
    #                       buildInProgress (409),
159 b016b476 Giorgos Verigakis
    #                       serverCapacityUnavailable (503),
160 b016b476 Giorgos Verigakis
    #                       overLimit (413)
161 b016b476 Giorgos Verigakis
162 b016b476 Giorgos Verigakis
    raise ServiceUnavailable()
163 b016b476 Giorgos Verigakis
164 b016b476 Giorgos Verigakis
@server_action('resize')
165 20a51b1e Giorgos Verigakis
def resize(request, vm, args):
166 b016b476 Giorgos Verigakis
    # Normal Response Code: 202
167 b016b476 Giorgos Verigakis
    # Error Response Codes: computeFault (400, 500),
168 b016b476 Giorgos Verigakis
    #                       serviceUnavailable (503),
169 b016b476 Giorgos Verigakis
    #                       unauthorized (401),
170 b016b476 Giorgos Verigakis
    #                       badRequest (400),
171 b016b476 Giorgos Verigakis
    #                       badMediaType(415),
172 b016b476 Giorgos Verigakis
    #                       itemNotFound (404),
173 b016b476 Giorgos Verigakis
    #                       buildInProgress (409),
174 b016b476 Giorgos Verigakis
    #                       serverCapacityUnavailable (503),
175 b016b476 Giorgos Verigakis
    #                       overLimit (413),
176 b016b476 Giorgos Verigakis
    #                       resizeNotAllowed (403)
177 b016b476 Giorgos Verigakis
    
178 b016b476 Giorgos Verigakis
    raise ResizeNotAllowed()
179 b016b476 Giorgos Verigakis
180 b016b476 Giorgos Verigakis
@server_action('confirmResize')
181 20a51b1e Giorgos Verigakis
def confirm_resize(request, vm, args):
182 b016b476 Giorgos Verigakis
    # Normal Response Code: 204
183 b016b476 Giorgos Verigakis
    # Error Response Codes: computeFault (400, 500),
184 b016b476 Giorgos Verigakis
    #                       serviceUnavailable (503),
185 b016b476 Giorgos Verigakis
    #                       unauthorized (401),
186 b016b476 Giorgos Verigakis
    #                       badRequest (400),
187 b016b476 Giorgos Verigakis
    #                       badMediaType(415),
188 b016b476 Giorgos Verigakis
    #                       itemNotFound (404),
189 b016b476 Giorgos Verigakis
    #                       buildInProgress (409),
190 b016b476 Giorgos Verigakis
    #                       serverCapacityUnavailable (503),
191 b016b476 Giorgos Verigakis
    #                       overLimit (413),
192 b016b476 Giorgos Verigakis
    #                       resizeNotAllowed (403)
193 b016b476 Giorgos Verigakis
    
194 b016b476 Giorgos Verigakis
    raise ResizeNotAllowed()
195 b016b476 Giorgos Verigakis
196 b016b476 Giorgos Verigakis
@server_action('revertResize')
197 20a51b1e Giorgos Verigakis
def revert_resize(request, vm, args):
198 b016b476 Giorgos Verigakis
    # Normal Response Code: 202
199 b016b476 Giorgos Verigakis
    # Error Response Codes: computeFault (400, 500),
200 b016b476 Giorgos Verigakis
    #                       serviceUnavailable (503),
201 b016b476 Giorgos Verigakis
    #                       unauthorized (401),
202 b016b476 Giorgos Verigakis
    #                       badRequest (400),
203 b016b476 Giorgos Verigakis
    #                       badMediaType(415),
204 b016b476 Giorgos Verigakis
    #                       itemNotFound (404),
205 b016b476 Giorgos Verigakis
    #                       buildInProgress (409),
206 b016b476 Giorgos Verigakis
    #                       serverCapacityUnavailable (503),
207 b016b476 Giorgos Verigakis
    #                       overLimit (413),
208 b016b476 Giorgos Verigakis
    #                       resizeNotAllowed (403)
209 b016b476 Giorgos Verigakis
210 b016b476 Giorgos Verigakis
    raise ResizeNotAllowed()