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

35
import os
36

37
from django.conf import settings
38
from django.utils.translation import gettext_lazy as _
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
39
from django.template import loader
Dimitris Moraitis's avatar
Dimitris Moraitis committed
40
from django.http import HttpResponse
Dimitris Moraitis's avatar
Dimitris Moraitis committed
41
from django.utils.translation import get_language
Markos Gogoulos's avatar
Markos Gogoulos committed
42
from django.utils import simplejson as json
43
from django.template.loader import render_to_string
44
from django.core.urlresolvers import reverse
45
from django.template import RequestContext
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
46

Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
47
from synnefo.util.version import get_component_version
48

49
from snf_django.lib.astakos import get_user
50

Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
51
SYNNEFO_JS_LIB_VERSION = get_component_version('app')
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
52
53
54
55

# api configuration
COMPUTE_API_URL = getattr(settings, 'COMPUTE_API_URL', '/api/v1.1')

56
57
# UI preferences settings
TIMEOUT = getattr(settings, "TIMEOUT", 10000)
58
UPDATE_INTERVAL = getattr(settings, "UI_UPDATE_INTERVAL", 5000)
59
CHANGES_SINCE_ALIGNMENT = getattr(settings, "UI_CHANGES_SINCE_ALIGNMENT", 0)
60
UPDATE_INTERVAL_INCREASE = getattr(settings, "UI_UPDATE_INTERVAL_INCREASE", 500)
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
61
62
UPDATE_INTERVAL_INCREASE_AFTER_CALLS_COUNT = \
    getattr(settings, "UI_UPDATE_INTERVAL_INCREASE_AFTER_CALLS_COUNT", 3)
63
64
UPDATE_INTERVAL_FAST = getattr(settings, "UI_UPDATE_INTERVAL_FAST", 2500)
UPDATE_INTERVAL_MAX = getattr(settings, "UI_UPDATE_INTERVAL_MAX", 10000)
65
QUOTAS_UPDATE_INTERVAL = getattr(settings, "UI_QUOTAS_UPDATE_INTERVAL", 10000)
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
66

67
# predefined values settings
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
68
69
VM_IMAGE_COMMON_METADATA = \
    getattr(settings, "UI_VM_IMAGE_COMMON_METADATA", ["OS", "users"])
70
SUGGESTED_FLAVORS_DEFAULT = {}
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
71
72
73
74
75
76
SUGGESTED_FLAVORS = getattr(settings, "VM_CREATE_SUGGESTED_FLAVORS",
                            SUGGESTED_FLAVORS_DEFAULT)
SUGGESTED_ROLES_DEFAULT = ["Database server", "File server", "Mail server",
                           "Web server", "Proxy"]
SUGGESTED_ROLES = getattr(settings, "VM_CREATE_SUGGESTED_ROLES",
                          SUGGESTED_ROLES_DEFAULT)
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
77
IMAGE_ICONS = settings.IMAGE_ICONS
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
78
79
80
81
IMAGE_DELETED_TITLE = \
    getattr(settings, 'UI_IMAGE_DELETED_TITLE', '(deleted)')
IMAGE_DELETED_SIZE_TITLE = \
    getattr(settings, 'UI_IMAGE_DELETED_SIZE_TITLE', '(none)')
82

83
84
SUPPORT_SSH_OS_LIST = getattr(settings, "UI_SUPPORT_SSH_OS_LIST",)
OS_CREATED_USERS = getattr(settings, "UI_OS_DEFAULT_USER_MAP")
85
86
87
LOGOUT_URL = getattr(settings, "UI_LOGOUT_URL", '/im/authenticate')
LOGIN_URL = getattr(settings, "UI_LOGIN_URL", '/im/login')
AUTH_COOKIE_NAME = getattr(settings, "UI_AUTH_COOKIE_NAME", 'synnefo_user')
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
88

89
90
91
# UI behaviour settings
DELAY_ON_BLUR = getattr(settings, "UI_DELAY_ON_BLUR", True)
UPDATE_HIDDEN_VIEWS = getattr(settings, "UI_UPDATE_HIDDEN_VIEWS", False)
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
92
93
HANDLE_WINDOW_EXCEPTIONS = \
    getattr(settings, "UI_HANDLE_WINDOW_EXCEPTIONS", True)
94
SKIP_TIMEOUTS = getattr(settings, "UI_SKIP_TIMEOUTS", 1)
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
95

96
97
# Additional settings
VM_NAME_TEMPLATE = getattr(settings, "VM_CREATE_NAME_TPL", "My {0} server")
98
VM_HOSTNAME_FORMAT = getattr(settings, "UI_VM_HOSTNAME_FORMAT",
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
99
                             'snf-%(id)s.vm.okeanos.grnet.gr')
100
101

if isinstance(VM_HOSTNAME_FORMAT, basestring):
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
102
    VM_HOSTNAME_FORMAT = VM_HOSTNAME_FORMAT % {'id': '{0}'}
103

104
MAX_SSH_KEYS_PER_USER = getattr(settings, "USERDATA_MAX_SSH_KEYS_PER_USER")
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
105
106
FLAVORS_DISK_TEMPLATES_INFO = \
    getattr(settings, "UI_FLAVORS_DISK_TEMPLATES_INFO", {})
107
SYSTEM_IMAGES_OWNERS = getattr(settings, "UI_SYSTEM_IMAGES_OWNERS", {})
108
CUSTOM_IMAGE_HELP_URL = getattr(settings, "UI_CUSTOM_IMAGE_HELP_URL", None)
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
109

110
# MEDIA PATHS
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
UI_MEDIA_URL = \
    getattr(settings, "UI_MEDIA_URL",
            "%ssnf-%s/" % (settings.MEDIA_URL, SYNNEFO_JS_LIB_VERSION))
UI_SYNNEFO_IMAGES_URL = \
    getattr(settings,
            "UI_SYNNEFO_IMAGES_URL", UI_MEDIA_URL + "images/")
UI_SYNNEFO_CSS_URL = \
    getattr(settings,
            "UI_SYNNEFO_CSS_URL", UI_MEDIA_URL + "css/")
UI_SYNNEFO_JS_URL = \
    getattr(settings,
            "UI_SYNNEFO_JS_URL", UI_MEDIA_URL + "js/")
UI_SYNNEFO_JS_LIB_URL = \
    getattr(settings,
            "UI_SYNNEFO_JS_LIB_URL", UI_SYNNEFO_JS_URL + "lib/")
UI_SYNNEFO_JS_WEB_URL = \
    getattr(settings, "UI_SYNNEFO_JS_WEB_URL", UI_SYNNEFO_JS_URL + "ui/web/")
128

Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
129
130
131
# extensions
ENABLE_GLANCE = getattr(settings, 'UI_ENABLE_GLANCE', True)
GLANCE_API_URL = getattr(settings, 'UI_GLANCE_API_URL', '/glance')
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
132
133
DIAGNOSTICS_UPDATE_INTERVAL = \
    getattr(settings, 'UI_DIAGNOSTICS_UPDATE_INTERVAL', 2000)
134

135
# network settings
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
136
137
138
139
140
DEFAULT_NETWORK_TYPES = {'MAC_FILTERED': 'mac-filtering',
                         'PHYSICAL_VLAN': 'physical-vlan'}
NETWORK_TYPES = \
    getattr(settings,
            'UI_NETWORK_AVAILABLE_NETWORK_TYPES', DEFAULT_NETWORK_TYPES)
141
DEFAULT_NETWORK_SUBNETS = ['10.0.0.0/24', '192.168.1.1/24']
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
142
143
144
145
146
147
148
149
150
151
152
153
NETWORK_SUBNETS = \
    getattr(settings,
            'UI_NETWORK_AVAILABLE_SUBNETS', DEFAULT_NETWORK_SUBNETS)
NETWORK_DUPLICATE_NICS = \
    getattr(settings,
            'UI_NETWORK_ALLOW_DUPLICATE_VM_NICS', False)
NETWORK_STRICT_DESTROY = \
    getattr(settings,
            'UI_NETWORK_STRICT_DESTROY', False)
NETWORK_ALLOW_MULTIPLE_DESTROY = \
    getattr(settings,
            'UI_NETWORK_ALLOW_MULTIPLE_DESTROY', False)
154
155
AUTOMATIC_NETWORK_RANGE_FORMAT = getattr(settings,
                                         'UI_AUTOMATIC_NETWORK_RANGE_FORMAT',
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
156
                                         "192.168.%d.0/24").replace("%d", "{0}")
157
GROUP_PUBLIC_NETWORKS = getattr(settings, 'UI_GROUP_PUBLIC_NETWORKS', True)
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
158
159
GROUPED_PUBLIC_NETWORK_NAME = \
    getattr(settings, 'UI_GROUPED_PUBLIC_NETWORK_NAME', 'Internet')
160

161
USER_CATALOG_URL = getattr(settings, 'UI_USER_CATALOG_URL', '/user_catalogs')
162
FEEDBACK_POST_URL = getattr(settings, 'UI_FEEDBACK_POST_URL', '/feedback')
163
164
TRANSLATE_UUIDS = not getattr(settings, 'TRANSLATE_UUIDS', False)

Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
165

166
def template(name, request, context):
Dimitris Moraitis's avatar
Dimitris Moraitis committed
167
    template_path = os.path.join(os.path.dirname(__file__), "templates/")
168
169
    current_template = template_path + name + '.html'
    t = loader.get_template(current_template)
170
    media_context = {
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
171
172
173
174
175
176
177
178
        'UI_MEDIA_URL': UI_MEDIA_URL,
        'SYNNEFO_JS_URL': UI_SYNNEFO_JS_URL,
        'SYNNEFO_JS_LIB_URL': UI_SYNNEFO_JS_LIB_URL,
        'SYNNEFO_JS_WEB_URL': UI_SYNNEFO_JS_WEB_URL,
        'SYNNEFO_IMAGES_URL': UI_SYNNEFO_IMAGES_URL,
        'SYNNEFO_CSS_URL': UI_SYNNEFO_CSS_URL,
        'SYNNEFO_JS_LIB_VERSION': SYNNEFO_JS_LIB_VERSION,
        'DEBUG': settings.DEBUG
179
180
    }
    context.update(media_context)
181
    return HttpResponse(t.render(RequestContext(request, context)))
Dimitris Moraitis's avatar
Dimitris Moraitis committed
182

Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
183

Dimitris Moraitis's avatar
Dimitris Moraitis committed
184
def home(request):
Dimitris Moraitis's avatar
Dimitris Moraitis committed
185
    context = {'timeout': TIMEOUT,
186
               'project': '+nefo',
Dimitris Moraitis's avatar
Dimitris Moraitis committed
187
               'request': request,
188
               'current_lang': get_language() or 'en',
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
189
               'compute_api_url': json.dumps(COMPUTE_API_URL),
190
               'user_catalog_url': json.dumps(USER_CATALOG_URL),
191
               'feedback_post_url': json.dumps(FEEDBACK_POST_URL),
192
               'translate_uuids': json.dumps(TRANSLATE_UUIDS),
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
193
               # update interval settings
194
               'update_interval': UPDATE_INTERVAL,
195
               'update_interval_increase': UPDATE_INTERVAL_INCREASE,
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
196
197
               'update_interval_increase_after_calls':
               UPDATE_INTERVAL_INCREASE_AFTER_CALLS_COUNT,
198
199
               'update_interval_fast': UPDATE_INTERVAL_FAST,
               'update_interval_max': UPDATE_INTERVAL_MAX,
200
               'changes_since_alignment': CHANGES_SINCE_ALIGNMENT,
201
               'quotas_update_interval': QUOTAS_UPDATE_INTERVAL,
202
               'image_icons': IMAGE_ICONS,
203
               'logout_redirect': LOGOUT_URL,
204
205
               'login_redirect': LOGIN_URL,
               'auth_cookie_name': AUTH_COOKIE_NAME,
206
               'suggested_flavors': json.dumps(SUGGESTED_FLAVORS),
207
               'suggested_roles': json.dumps(SUGGESTED_ROLES),
208
               'vm_image_common_metadata': json.dumps(VM_IMAGE_COMMON_METADATA),
209
               'synnefo_version': SYNNEFO_JS_LIB_VERSION,
210
211
212
213
               'delay_on_blur': json.dumps(DELAY_ON_BLUR),
               'update_hidden_views': json.dumps(UPDATE_HIDDEN_VIEWS),
               'handle_window_exceptions': json.dumps(HANDLE_WINDOW_EXCEPTIONS),
               'skip_timeouts': json.dumps(SKIP_TIMEOUTS),
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
214
               'vm_name_template': json.dumps(VM_NAME_TEMPLATE),
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
215
216
               'flavors_disk_templates_info':
               json.dumps(FLAVORS_DISK_TEMPLATES_INFO),
217
218
               'support_ssh_os_list': json.dumps(SUPPORT_SSH_OS_LIST),
               'os_created_users': json.dumps(OS_CREATED_USERS),
219
               'userdata_keys_limit': json.dumps(MAX_SSH_KEYS_PER_USER),
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
220
               'use_glance': json.dumps(ENABLE_GLANCE),
221
               'glance_api_url': json.dumps(GLANCE_API_URL),
222
               'system_images_owners': json.dumps(SYSTEM_IMAGES_OWNERS),
223
               'custom_image_help_url': CUSTOM_IMAGE_HELP_URL,
224
225
               'image_deleted_title': json.dumps(IMAGE_DELETED_TITLE),
               'image_deleted_size_title': json.dumps(IMAGE_DELETED_SIZE_TITLE),
226
227
               'network_suggested_subnets': json.dumps(NETWORK_SUBNETS),
               'network_available_types': json.dumps(NETWORK_TYPES),
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
228
229
               'network_allow_duplicate_vm_nics':
               json.dumps(NETWORK_DUPLICATE_NICS),
230
               'network_strict_destroy': json.dumps(NETWORK_STRICT_DESTROY),
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
231
232
233
234
235
236
               'network_allow_multiple_destroy':
               json.dumps(NETWORK_ALLOW_MULTIPLE_DESTROY),
               'automatic_network_range_format':
               json.dumps(AUTOMATIC_NETWORK_RANGE_FORMAT),
               'grouped_public_network_name':
               json.dumps(GROUPED_PUBLIC_NETWORK_NAME),
237
               'group_public_networks': json.dumps(GROUP_PUBLIC_NETWORKS),
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
238
239
               'diagnostics_update_interval':
               json.dumps(DIAGNOSTICS_UPDATE_INTERVAL),
240
               'vm_hostname_format': json.dumps(VM_HOSTNAME_FORMAT)
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
241
               }
242
    return template('home', request, context)
Dimitris Moraitis's avatar
Dimitris Moraitis committed
243

Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
244

245
def machines_console(request):
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
246
247
248
249
250
251
252
    host, port, password = ('', '', '')
    host = request.GET.get('host', '')
    port = request.GET.get('port', '')
    password = request.GET.get('password', '')
    machine = request.GET.get('machine', '')
    host_ip = request.GET.get('host_ip', '')
    host_ip_v6 = request.GET.get('host_ip_v6', '')
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
253
254
    context = {'host': host, 'port': port, 'password': password,
               'machine': machine, 'host_ip': host_ip, 'host_ip_v6': host_ip_v6}
255
    return template('machines_console', request, context)
Dimitris Moraitis's avatar
Dimitris Moraitis committed
256

Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
257

Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
258
def user_quota(request):
259
    get_user(request, settings.ASTAKOS_URL, usage=True)
260

261
    if request.user and 'usage' in request.user:
262
263
264
265
266
267
        response = json.dumps(request.user['usage'])
    else:
        # hmmm, old astakos ???
        # try to mimic astakos response using cyclades quota settings
        networks_limit_for_user = \
            settings.NETWORKS_USER_QUOTA.get(request.user_uniq,
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
268
                                             settings.MAX_NETWORKS_PER_USER)
269
270
        vms_limit_for_user = \
            settings.VMS_USER_QUOTA.get(request.user_uniq,
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
271
272
273
274
275
276
                                        settings.MAX_NETWORKS_PER_USER)
        usage = [{'name': 'cyclades.vm',
                  'maxValue': vms_limit_for_user},
                 {'name': 'cyclades.network.private',
                  'maxValue': networks_limit_for_user}]
        response = json.dumps(usage)
277

278
    return HttpResponse(response, mimetype="application/json")
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
279

Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
280

281
def js_tests(request):
282
    return template('tests', request, {})
283

Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

CONNECT_LINUX_LINUX_MESSAGE = \
    _("""A direct connection to this machine can be established using the
<a target="_blank" href="http://en.wikipedia.org/wiki/Secure_Shell">
SSH Protocol</a>.
To do so open a terminal and type the following at the prompt to connect
to your machine:""")
CONNECT_LINUX_WINDOWS_MESSAGE = \
    _("""A direct connection to this machine can be established using
<a target="_blank"
href="http://en.wikipedia.org/wiki/Remote_Desktop_Services">
Remote Desktop Service</a>.
To do so, open the following file with an appropriate remote desktop client.""")
CONNECT_LINUX_WINDOWS_SUBMESSAGE = \
    _("""If you don't have a Remote Desktop client already installed,
299
we suggest the use of <a target="_blank"
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
300
301
302
303
href=
"http://sourceforge.net/projects/tsclient/files/latest/download?source=files">
tsclient</a>.<br /><span class="important">IMPORTANT: It may take up to 15
minutes for your Windows VM to become available
304
after its creation.</span>""")
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
305
306
307
CONNECT_WINDOWS_LINUX_MESSAGE = \
    _("""A direct connection to this machine can be established using the
<a target="_blank"
308
href="http://en.wikipedia.org/wiki/Secure_Shell">SSH Protocol</a>.
309
Open an ssh client such as PuTTY and type the following:""")
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
310
311
312
313
314
315
316
317
CONNECT_WINDOWS_LINUX_SUBMESSAGE = \
    _("""If you do not have an ssh client already installed,
<a target="_blank"
href="http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe">
Download PuTTY</a>""")

CONNECT_WINDOWS_WINDOWS_MESSAGE = \
    _("""A direct connection to this machine can be
318
319
established using Remote Desktop. Click on the following link, and if asked
open it using "Remote Desktop Connection".
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
320
321
<br /><span class="important">
IMPORTANT: It may take up to 15 minutes for your Windows VM to become available
322
after its creation.</span>""")
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
323
324
CONNECT_WINDOWS_WINDOWS_SUBMESSAGE = \
    _("""Save this file to disk for future use.""")
325
326
327
328
329
330

# info/subinfo for all os combinations
#
# [0] info gets displayed on top of the message box
# [1] subinfo gets displayed on the bottom as extra info
# provided to the user when needed
331
CONNECT_PROMPT_MESSAGES = {
332
    'linux': {
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
333
334
335
336
        'linux': [CONNECT_LINUX_LINUX_MESSAGE, ""],
        'windows': [CONNECT_LINUX_WINDOWS_MESSAGE,
                    CONNECT_LINUX_WINDOWS_SUBMESSAGE],
        'ssh_message': "ssh %(user)s@%(hostname)s"
337
    },
338
    'windows': {
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
339
340
341
342
343
        'linux': [CONNECT_WINDOWS_LINUX_MESSAGE,
                  CONNECT_WINDOWS_LINUX_SUBMESSAGE],
        'windows': [CONNECT_WINDOWS_WINDOWS_MESSAGE,
                    CONNECT_WINDOWS_WINDOWS_SUBMESSAGE],
        'ssh_message': "%(user)s@%(hostname)s"
344
345
346
    },
}

Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
347
348
APPEND_CONNECT_PROMPT_MESSAGES = \
    getattr(settings, 'UI_CONNECT_PROMPT_MESSAGES', {})
349
350
for k, v in APPEND_CONNECT_PROMPT_MESSAGES.iteritems():
    CONNECT_PROMPT_MESSAGES[k].update(v)
351

352
# retrieve domain prefix from settings
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
353
354
DOMAIN_PREFIX = getattr(settings, 'MACHINE_DOMAIN_PREFIX', getattr(settings,
                        'BACKEND_PREFIX_ID', ""))
355
356
357
358

# domain template string
DOMAIN_TPL = "%s%%s" % DOMAIN_PREFIX

Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
359

360
def machines_connect(request):
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
361
362
363
    ip_address = request.GET.get('ip_address', '')
    hostname = request.GET.get('hostname', '')
    operating_system = metadata_os = request.GET.get('os', '')
364
    server_id = request.GET.get('srv', 0)
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
365
    host_os = request.GET.get('host_os', 'Linux').lower()
366
    username = request.GET.get('username', None)
367
    domain = request.GET.get("domain", DOMAIN_TPL % int(server_id))
368

369
    # guess host os
370
371
372
    if host_os != "windows":
        host_os = 'linux'

373
374
375
376
377
378
379
380
381
382
383
384
    # guess username
    if not username:
        username = "root"

        if metadata_os.lower() in ['ubuntu', 'kubuntu', 'fedora']:
            username = "user"

        if metadata_os.lower() == "windows":
            username = "Administrator"

    # operating system provides ssh access
    ssh = False
385
386
    if operating_system != "windows":
        operating_system = "linux"
387
        ssh = True
388

389
    # rdp param is set, the user requested rdp file
390
391
392
393
394
    # check if we are on windows
    if operating_system == 'windows' and request.GET.get("rdp", False):

        # UI sent domain info (from vm metadata) use this
        # otherwise use our default snf-<vm_id> domain
395
396
397
398
399
        EXTRA_RDP_CONTENT = getattr(settings, 'UI_EXTRA_RDP_CONTENT', '')
        if callable(EXTRA_RDP_CONTENT):
            extra_rdp_content = EXTRA_RDP_CONTENT(server_id, ip_address,
                                                  hostname, username)
        else:
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
400
401
402
            extra_rdp_content = EXTRA_RDP_CONTENT % \
                {
                    'server_id': server_id,
403
404
405
                    'ip_address': ip_address,
                    'hostname': hostname,
                    'user': username
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
406
                }
407

408
        rdp_context = {
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
409
410
411
412
413
            'username': username,
            'domain': domain,
            'ip_address': ip_address,
            'hostname': hostname,
            'extra_content': extra_rdp_content
414
415
416
417
        }

        rdp_file_data = render_to_string("synnefo-windows.rdp", rdp_context)
        response = HttpResponse(rdp_file_data, mimetype='application/x-rdp')
418
419

        # proper filename, use server id and ip address
420
        filename = "%d-%s.rdp" % (int(server_id), hostname)
421
        response['Content-Disposition'] = 'attachment; filename=%s' % filename
422
    else:
423
424
425
426
427
428
429
        ssh_message = CONNECT_PROMPT_MESSAGES['linux'].get('ssh_message')
        if host_os == 'windows':
            ssh_message = CONNECT_PROMPT_MESSAGES['windows'].get('ssh_message')
        if callable(ssh_message):
            link_title = ssh_message(server_id, ip_address, hostname, username)
        else:
            link_title = ssh_message % {
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
430
431
432
433
434
                'server_id': server_id,
                'ip_address': ip_address,
                'hostname': hostname,
                'user': username
            }
435
        if (operating_system != "windows"):
436
437
            link_url = None

438
439
        else:
            link_title = _("Remote desktop to %s") % ip_address
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
440
441
442
            link_url = \
                "%s?ip_address=%s&os=%s&rdp=1&srv=%d&username=%s&domain=%s" \
                "&hostname=%s" % (
443
                    reverse("ui_machines_connect"), ip_address,
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
444
445
                    operating_system, int(server_id), username,
                    domain, hostname)
446

447
448
        # try to find a specific message
        try:
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
449
450
            connect_message = \
                CONNECT_PROMPT_MESSAGES[host_os][operating_system][0]
451
            subinfo = CONNECT_PROMPT_MESSAGES[host_os][operating_system][1]
452
        except KeyError:
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
453
454
455
            connect_message = \
                _("You are trying to connect from a %s "
                  "machine to a %s machine") % (host_os, operating_system)
456
            subinfo = ""
457

458
        response_object = {
Ilias Tsitsimpis's avatar
Ilias Tsitsimpis committed
459
460
461
462
463
464
465
466
467
468
            'ip': ip_address,
            'os': operating_system,
            'ssh': ssh,
            'info': unicode(connect_message),
            'subinfo': unicode(subinfo),
            'link': {'title': unicode(link_title), 'url': link_url}
        }
        response = \
            HttpResponse(json.dumps(response_object),
                         mimetype='application/json')  # no windows, no rdp
469

470
    return response