views.py 19.1 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 _
39
from django.template import Context, 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.shortcuts import render_to_response
44
from django.template.loader import render_to_string
45
from django.core.urlresolvers import reverse
46
from django.core.mail import send_mail
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
47
from django.http import Http404
48
from django.template import RequestContext
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
49

Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
50
from synnefo.util.version import get_component_version
51

52
53
from synnefo.lib.astakos import get_user

Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
54
SYNNEFO_JS_LIB_VERSION = get_component_version('app')
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
55
56
57
58

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

59
60
# UI preferences settings
TIMEOUT = getattr(settings, "TIMEOUT", 10000)
61
UPDATE_INTERVAL = getattr(settings, "UI_UPDATE_INTERVAL", 5000)
62
CHANGES_SINCE_ALIGNMENT = getattr(settings, "UI_CHANGES_SINCE_ALIGNMENT", 0)
63
64
UPDATE_INTERVAL_INCREASE = getattr(settings, "UI_UPDATE_INTERVAL_INCREASE", 500)
UPDATE_INTERVAL_INCREASE_AFTER_CALLS_COUNT = getattr(settings,
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
65
66
                                "UI_UPDATE_INTERVAL_INCREASE_AFTER_CALLS_COUNT",
                                3)
67
68
UPDATE_INTERVAL_FAST = getattr(settings, "UI_UPDATE_INTERVAL_FAST", 2500)
UPDATE_INTERVAL_MAX = getattr(settings, "UI_UPDATE_INTERVAL_MAX", 10000)
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
69

70
# predefined values settings
71
VM_IMAGE_COMMON_METADATA = getattr(settings, "UI_VM_IMAGE_COMMON_METADATA", ["OS", "users"])
72
SUGGESTED_FLAVORS_DEFAULT = {}
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
73
74
75
76
77
78
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
79
IMAGE_ICONS = settings.IMAGE_ICONS
80
IMAGE_DELETED_TITLE = getattr(settings, 'UI_IMAGE_DELETED_TITLE',
81
                            '(deleted)')
82
83
IMAGE_DELETED_SIZE_TITLE = getattr(settings, 'UI_IMAGE_DELETED_SIZE_TITLE',
                            '(none)')
84

85
86
SUPPORT_SSH_OS_LIST = getattr(settings, "UI_SUPPORT_SSH_OS_LIST",)
OS_CREATED_USERS = getattr(settings, "UI_OS_DEFAULT_USER_MAP")
87
88
89
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
90

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

97
98
# Additional settings
VM_NAME_TEMPLATE = getattr(settings, "VM_CREATE_NAME_TPL", "My {0} server")
99
100
VM_HOSTNAME_FORMAT = getattr(settings, "UI_VM_HOSTNAME_FORMAT",
                                    'snf-%(id)s.vm.okeanos.grnet.gr')
101
102
MAX_SSH_KEYS_PER_USER = getattr(settings, "USERDATA_MAX_SSH_KEYS_PER_USER")
FLAVORS_DISK_TEMPLATES_INFO = getattr(settings, "UI_FLAVORS_DISK_TEMPLATES_INFO", {})
103
SYSTEM_IMAGES_OWNERS = getattr(settings, "UI_SYSTEM_IMAGES_OWNERS", {})
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
104

105
# MEDIA PATHS
106
107
UI_MEDIA_URL = getattr(settings, "UI_MEDIA_URL",
                    "%ssnf-%s/" % (settings.MEDIA_URL, SYNNEFO_JS_LIB_VERSION))
108
UI_SYNNEFO_IMAGES_URL = getattr(settings,
109
                    "UI_SYNNEFO_IMAGES_URL", UI_MEDIA_URL + "images/")
110
UI_SYNNEFO_CSS_URL = getattr(settings,
111
                    "UI_SYNNEFO_CSS_URL", UI_MEDIA_URL + "css/")
112
UI_SYNNEFO_JS_URL = getattr(settings,
113
                    "UI_SYNNEFO_JS_URL", UI_MEDIA_URL + "js/")
114
115
116
117
118
119
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/")

Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
120
121
122
123
124
# extensions
ENABLE_GLANCE = getattr(settings, 'UI_ENABLE_GLANCE', True)
GLANCE_API_URL = getattr(settings, 'UI_GLANCE_API_URL', '/glance')
FEEDBACK_CONTACTS = getattr(settings, "FEEDBACK_CONTACTS", [])
FEEDBACK_EMAIL_FROM = settings.FEEDBACK_EMAIL_FROM
125
126
DIAGNOSTICS_UPDATE_INTERVAL = getattr(settings,
                'UI_DIAGNOSTICS_UPDATE_INTERVAL', 2000)
127

128
129
130
131
132
133
134
135
136
137
138
139
140
# network settings
DEFAULT_NETWORK_TYPES = {'PRIVATE_FILTERED': 'mac-filtering'}
NETWORK_TYPES = getattr(settings,
                    'UI_NETWORK_AVAILABLE_NETWORK_TYPES', DEFAULT_NETWORK_TYPES)
DEFAULT_NETWORK_SUBNETS = ['10.0.0.0/24', '192.168.1.1/24']
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)
141
GROUP_PUBLIC_NETWORKS = getattr(settings, 'UI_GROUP_PUBLIC_NETWORKS', True)
142
GROUPED_PUBLIC_NETWORK_NAME = getattr(settings, 'UI_GROUPED_PUBLIC_NETWORK_NAME', 'Internet')
143

144
def template(name, request, context):
Dimitris Moraitis's avatar
Dimitris Moraitis committed
145
    template_path = os.path.join(os.path.dirname(__file__), "templates/")
146
147
    current_template = template_path + name + '.html'
    t = loader.get_template(current_template)
148
149
150
151
152
153
154
155
156
157
158
    media_context = {
       '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
    }
    context.update(media_context)
159
    return HttpResponse(t.render(RequestContext(request, context)))
Dimitris Moraitis's avatar
Dimitris Moraitis committed
160
161

def home(request):
Dimitris Moraitis's avatar
Dimitris Moraitis committed
162
    context = {'timeout': TIMEOUT,
163
               'project': '+nefo',
Dimitris Moraitis's avatar
Dimitris Moraitis committed
164
               'request': request,
165
               'current_lang': get_language() or 'en',
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
166
               'compute_api_url': json.dumps(COMPUTE_API_URL),
167
                # update interval settings
168
               'update_interval': UPDATE_INTERVAL,
169
170
171
172
               'update_interval_increase': UPDATE_INTERVAL_INCREASE,
               'update_interval_increase_after_calls': UPDATE_INTERVAL_INCREASE_AFTER_CALLS_COUNT,
               'update_interval_fast': UPDATE_INTERVAL_FAST,
               'update_interval_max': UPDATE_INTERVAL_MAX,
173
               'changes_since_alignment': CHANGES_SINCE_ALIGNMENT,
174
                # additional settings
175
               'image_icons': IMAGE_ICONS,
176
               'logout_redirect': LOGOUT_URL,
177
178
               'login_redirect': LOGIN_URL,
               'auth_cookie_name': AUTH_COOKIE_NAME,
179
               'suggested_flavors': json.dumps(SUGGESTED_FLAVORS),
180
               'suggested_roles': json.dumps(SUGGESTED_ROLES),
181
               'vm_image_common_metadata': json.dumps(VM_IMAGE_COMMON_METADATA),
182
               'synnefo_version': SYNNEFO_JS_LIB_VERSION,
183
184
185
186
               '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
187
               'vm_name_template': json.dumps(VM_NAME_TEMPLATE),
188
               'flavors_disk_templates_info': json.dumps(FLAVORS_DISK_TEMPLATES_INFO),
189
190
               'support_ssh_os_list': json.dumps(SUPPORT_SSH_OS_LIST),
               'os_created_users': json.dumps(OS_CREATED_USERS),
191
               'userdata_keys_limit': json.dumps(MAX_SSH_KEYS_PER_USER),
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
192
               'use_glance': json.dumps(ENABLE_GLANCE),
193
               'glance_api_url': json.dumps(GLANCE_API_URL),
194
195
196
               'system_images_owners': json.dumps(SYSTEM_IMAGES_OWNERS),
               'image_deleted_title': json.dumps(IMAGE_DELETED_TITLE),
               'image_deleted_size_title': json.dumps(IMAGE_DELETED_SIZE_TITLE),
197
198
199
200
               'network_suggested_subnets': json.dumps(NETWORK_SUBNETS),
               'network_available_types': json.dumps(NETWORK_TYPES),
               'network_allow_duplicate_vm_nics': json.dumps(NETWORK_DUPLICATE_NICS),
               'network_strict_destroy': json.dumps(NETWORK_STRICT_DESTROY),
201
               'network_allow_multiple_destroy': json.dumps(NETWORK_ALLOW_MULTIPLE_DESTROY),
202
               'grouped_public_network_name': json.dumps(GROUPED_PUBLIC_NETWORK_NAME),
203
               'group_public_networks': json.dumps(GROUP_PUBLIC_NETWORKS),
204
205
               'diagnostics_update_interval': json.dumps(DIAGNOSTICS_UPDATE_INTERVAL),
               'vm_hostname_format': json.dumps(VM_HOSTNAME_FORMAT % {'id':'{0}'})
206
    }
207
    return template('home', request, context)
Dimitris Moraitis's avatar
Dimitris Moraitis committed
208

209
def machines_console(request):
Markos Gogoulos's avatar
Markos Gogoulos committed
210
    host, port, password = ('','','')
211
212
213
    host = request.GET.get('host','')
    port = request.GET.get('port','')
    password = request.GET.get('password','')
214
215
    machine = request.GET.get('machine','')
    host_ip = request.GET.get('host_ip','')
216
    host_ip_v6 = request.GET.get('host_ip_v6','')
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
217
218
    context = {'host': host, 'port': port, 'password': password,
               'machine': machine, 'host_ip': host_ip, 'host_ip_v6': host_ip_v6}
219
    return template('machines_console', request, context)
Dimitris Moraitis's avatar
Dimitris Moraitis committed
220

Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
221
222
223
224
225
226
227
228
229
230
231
232
233
def user_quota(request):
    get_user(request, settings.ASTAKOS_URL)
    vms_limit_for_user = \
        settings.VMS_USER_QUOTA.get(request.user_uniq,
                settings.MAX_VMS_PER_USER)

    networks_limit_for_user = \
        settings.NETWORKS_USER_QUOTA.get(request.user_uniq,
                settings.MAX_NETWORKS_PER_USER)
    return HttpResponse('{"vms_quota":%d, "networks_quota":%d}' % (vms_limit_for_user,
                                                               networks_limit_for_user),
                        mimetype="application/json")

234
def js_tests(request):
235
    return template('tests', request, {})
236

237
238
239
240
241
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>.
242
To do so, open the following file with an appropriate remote desktop client.
243
""")
244
245
CONNECT_LINUX_WINDOWS_SUBMESSAGE = _("""If you don't have a Remote Desktop client already installed,
we suggest the use of <a target="_blank"
246
247
248
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
after its creation.</span>""")
249
250
CONNECT_WINDOWS_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>.
251
Open an ssh client such as PuTTY and type the following:""")
252
253
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>""")
254

255
CONNECT_WINDOWS_WINDOWS_MESSAGE = _("""A direct connection to this machine can be
256
257
established using Remote Desktop. Click on the following link, and if asked
open it using "Remote Desktop Connection".
258
259
260
<br /><span class="important">IMPORTANT: It may take up to 15 minutes for your Windows VM to become available
after its creation.</span>""")
CONNECT_WINDOWS_WINDOWS_SUBMESSAGE = _("""Save this file to disk for future use.""")
261
262
263
264
265
266

# 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
267
CONNECT_PROMPT_MESSAGES = {
268
    'linux': {
269
            'linux': [CONNECT_LINUX_LINUX_MESSAGE, ""],
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
270
            'windows': [CONNECT_LINUX_WINDOWS_MESSAGE,
271
272
273
                        CONNECT_LINUX_WINDOWS_SUBMESSAGE],
            'ssh_message': "ssh %(user)s@%(hostname)s"
    },
274
    'windows': {
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
275
276
277
            'linux': [CONNECT_WINDOWS_LINUX_MESSAGE,
                      CONNECT_WINDOWS_LINUX_SUBMESSAGE],
            'windows': [CONNECT_WINDOWS_WINDOWS_MESSAGE,
278
279
280
281
282
283
284
285
286
                        CONNECT_WINDOWS_WINDOWS_SUBMESSAGE],
            'ssh_message': "%(user)s@%(hostname)s"
    },
}

APPEND_CONNECT_PROMPT_MESSAGES = getattr(settings, 'UI_CONNECT_PROMPT_MESSAGES',
                                       {})
for k, v in APPEND_CONNECT_PROMPT_MESSAGES.iteritems():
    CONNECT_PROMPT_MESSAGES[k].update(v)
287

288
# retrieve domain prefix from settings
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
289
290
DOMAIN_PREFIX = getattr(settings, 'MACHINE_DOMAIN_PREFIX', getattr(settings,
                        'BACKEND_PREFIX_ID', ""))
291
292
293
294

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

295
296
def machines_connect(request):
    ip_address = request.GET.get('ip_address','')
297
    hostname = request.GET.get('hostname','')
298
    operating_system = metadata_os = request.GET.get('os','')
299
    server_id = request.GET.get('srv', 0)
300
    host_os = request.GET.get('host_os','Linux').lower()
301
    username = request.GET.get('username', None)
302
    domain = request.GET.get("domain", DOMAIN_TPL % int(server_id))
303

304
    # guess host os
305
306
307
    if host_os != "windows":
        host_os = 'linux'

308
309
310
311
312
313
314
315
316
317
318
319
    # 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
320
321
    if operating_system != "windows":
        operating_system = "linux"
322
        ssh = True
323

324
    # rdp param is set, the user requested rdp file
325
326
327
328
329
    # 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
330
331
332
333
334
335
336
337
338
339
340
341
        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:
            extra_rdp_content = EXTRA_RDP_CONTENT % {
                    'server_id':server_id,
                    'ip_address': ip_address,
                    'hostname': hostname,
                    'user': username
                  }

342
343
344
        rdp_context = {
                'username': username,
                'domain': domain,
345
346
                'ip_address': ip_address,
                'extra_content': extra_rdp_content
347
348
349
350
        }

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

        # proper filename, use server id and ip address
353
        filename = "%d-%s.rdp" % (int(server_id), hostname)
354
        response['Content-Disposition'] = 'attachment; filename=%s' % filename
355
    else:
356
357
358
359
360
361
362
363
364
365
366
367
        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 % {
                    'server_id':server_id,
                    'ip_address': ip_address,
                    'hostname': hostname,
                    'user': username
                  }
368
        if (operating_system != "windows"):
369
370
            link_url = None

371
372
373
374
375
        else:
            link_title = _("Remote desktop to %s") % ip_address
            link_url = "%s?ip_address=%s&os=%s&rdp=1&srv=%d&username=%s&domain=%s&hostname=%s" % (
                    reverse("ui_machines_connect"), ip_address,
                    operating_system, int(server_id), username, domain, hostname)
376

377
378
        # try to find a specific message
        try:
379
380
            connect_message = CONNECT_PROMPT_MESSAGES[host_os][operating_system][0]
            subinfo = CONNECT_PROMPT_MESSAGES[host_os][operating_system][1]
381
        except KeyError:
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
382
383
            connect_message = _("You are trying to connect from a %s "
                                "machine to a %s machine") % (host_os, operating_system)
384
            subinfo = ""
385

386
387
388
389
        response_object = {
                'ip': ip_address,
                'os': operating_system,
                'ssh': ssh,
390
                'info': unicode(connect_message),
391
                'subinfo': unicode(subinfo),
392
393
                'link': {'title': unicode(link_title), 'url': link_url}
            }
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
394
395
        response = HttpResponse(json.dumps(response_object),
                                mimetype='application/json')  #no windows, no rdp
396

397
398
    return response

399
def feedback_submit(request):
Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
400
401
402
    if not request.method == "POST":
        raise Http404

403
404
405
    # fill request object with astakos user information
    get_user(request, settings.ASTAKOS_URL)

406
407
408
409
410
411
    message = request.POST.get("feedback-msg")
    data = request.POST.get("feedback-data")

    # default to True (calls from error pages)
    allow_data_send = request.POST.get("feedback-submit-data", True)

Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
412
    mail_subject = unicode(_("Feedback from synnefo application"))
413

Kostas Papadimitriou's avatar
Kostas Papadimitriou committed
414
415
    mail_context = {'message': message, 'data': data,
                    'allow_data_send': allow_data_send, 'request': request}
416
417
    mail_content = render_to_string("feedback_mail.txt", mail_context)

418
419
    send_mail(mail_subject, mail_content, FEEDBACK_EMAIL_FROM,
            dict(FEEDBACK_CONTACTS).values(), fail_silently=False)
420

421
    return HttpResponse('{"status":"send"}');
422