├── COPYRIGHT
├── Changelog
├── README.md
├── _version.py
├── accounts
├── __init__.py
├── admin.py
├── forms.py
├── management
│ ├── __init__.py
│ └── commands
│ │ ├── __init__.py
│ │ └── idle_accounts.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20161020_1643.py
│ └── __init__.py
├── models.py
├── tests.py
├── urls.py
└── views.py
├── apply
├── __init__.py
├── admin.py
├── apps.py
├── decorators.py
├── forms.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20161024_1512.py
│ └── __init__.py
├── models.py
├── south_migrations
│ └── 0012_auto__add_field_organization_synced.py
├── tests.py
├── urls
│ ├── __init__.py
│ ├── application.py
│ └── user.py
├── utils.py
└── views
│ ├── __init__.py
│ └── user.py
├── auditlog
├── __init__.py
├── admin.py
├── migrations
│ ├── 0001_initial.py
│ └── __init__.py
├── models.py
├── signals.py
├── tests.py
├── urls.py
├── utils.py
└── views.py
├── context
├── __init__.py
├── global_vars.py
├── pending_notifications.py
└── session_remaining.py
├── contrib
├── CONTENTS
├── default
│ └── ganetimgr-watcher
├── fabric
│ ├── fabfile.py
│ ├── requirements.txt
│ └── utils
│ │ ├── __init__.py
│ │ ├── database.py
│ │ ├── django.py
│ │ ├── git.py
│ │ ├── operations.py
│ │ └── services.py
├── gunicorn
│ ├── ganetimgr_jessie
│ └── ganetimgr_wheezy
├── init.d
│ └── ganetimgr-watcher
├── jquery-1.5.2.js
├── jquery-ui
│ ├── jquery.effects.blind.js
│ ├── jquery.effects.bounce.js
│ ├── jquery.effects.clip.js
│ ├── jquery.effects.core.js
│ ├── jquery.effects.drop.js
│ ├── jquery.effects.explode.js
│ ├── jquery.effects.fade.js
│ ├── jquery.effects.fold.js
│ ├── jquery.effects.highlight.js
│ ├── jquery.effects.pulsate.js
│ ├── jquery.effects.scale.js
│ ├── jquery.effects.shake.js
│ ├── jquery.effects.slide.js
│ ├── jquery.effects.transfer.js
│ ├── jquery.ui.accordion.js
│ ├── jquery.ui.autocomplete.js
│ ├── jquery.ui.button.js
│ ├── jquery.ui.core.js
│ ├── jquery.ui.datepicker.js
│ ├── jquery.ui.dialog.js
│ ├── jquery.ui.draggable.js
│ ├── jquery.ui.droppable.js
│ ├── jquery.ui.mouse.js
│ ├── jquery.ui.position.js
│ ├── jquery.ui.progressbar.js
│ ├── jquery.ui.resizable.js
│ ├── jquery.ui.selectable.js
│ ├── jquery.ui.slider.js
│ ├── jquery.ui.sortable.js
│ ├── jquery.ui.tabs.js
│ └── jquery.ui.widget.js
├── nginx
│ └── ganetimgr_vhost
├── vima_policy.py
└── vnc_javasrc
│ ├── AuthPanel.java
│ ├── ButtonPanel.java
│ ├── CapabilityInfo.java
│ ├── CapsContainer.java
│ ├── ChangeLog
│ ├── ClipboardFrame.java
│ ├── DesCipher.java
│ ├── HTTPConnectSocket.java
│ ├── HTTPConnectSocketFactory.java
│ ├── InStream.java
│ ├── LICENCE.TXT
│ ├── MANIFEST.MF
│ ├── Makefile
│ ├── MemInStream.java
│ ├── OptionsFrame.java
│ ├── README
│ ├── RecordingFrame.java
│ ├── ReloginPanel.java
│ ├── RfbProto.java
│ ├── SessionRecorder.java
│ ├── SocketFactory.java
│ ├── VncCanvas.java
│ ├── VncCanvas2.java
│ ├── VncViewer.java
│ ├── WhatsNew
│ ├── ZlibInStream.java
│ ├── index.html
│ └── index.vnc
├── docs
├── Makefile
└── source
│ ├── _static
│ └── images
│ │ ├── applications.png
│ │ ├── audit-log.png
│ │ ├── cluster_info.png
│ │ ├── ganetimgr_create_instance.png
│ │ ├── graphs.png
│ │ ├── history.png
│ │ ├── image00.png
│ │ ├── image01.png
│ │ ├── image02.png
│ │ ├── image03.png
│ │ ├── image04.png
│ │ ├── instance-owners.png
│ │ ├── instance_details.png
│ │ ├── jobs.png
│ │ ├── node_groups.png
│ │ ├── ss_01_main.png
│ │ ├── ss_02_user_main_view.png
│ │ ├── ss_03_user_statistics.png
│ │ ├── ss_04_user_profile.png
│ │ ├── ss_05_user_application.png
│ │ ├── ss_06_vm_info.png
│ │ ├── ss_07_vm_graphs.png
│ │ ├── ss_08_vm_conf.png
│ │ ├── ss_09_vm_actions.png
│ │ ├── ss_10_admin_node.png
│ │ ├── ss_11_admin_stats.png
│ │ ├── ss_12_admin_jobs.png
│ │ ├── ss_14_admin_application.png
│ │ └── ss_15_admin_mail.png
│ ├── admin.rst
│ ├── conf.py
│ ├── devel.rst
│ ├── index.rst
│ ├── install.rst
│ ├── interface.rst
│ ├── patches.rst
│ ├── upgrade.rst
│ ├── version2.md
│ └── vnc.rst
├── ganeti
├── __init__.py
├── admin.py
├── decorators
│ └── __init__.py
├── fixtures
│ └── flatpages.json
├── forms.py
├── management
│ ├── __init__.py
│ └── commands
│ │ ├── __init__.py
│ │ └── refresh_cluster_instances.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_custompermission.py
│ ├── 0003_auto_20170807_1459.py
│ └── __init__.py
├── models.py
├── templatetags
│ ├── __init__.py
│ ├── applicationstatus.py
│ ├── bootstrappercent.py
│ ├── days_since.py
│ ├── disksizes.py
│ ├── noderole.py
│ ├── truncatedchars.py
│ └── widget_tweaks.py
├── tests.py
├── urls
│ ├── __init__.py
│ ├── clusters.py
│ ├── graphs.py
│ ├── instances.py
│ ├── jobs.py
│ └── nodegroup.py
├── utils.py
└── views
│ ├── __init__.py
│ ├── clusters.py
│ ├── discovery.py
│ ├── graphs.py
│ ├── instances.py
│ ├── jobs.py
│ └── nodegroup.py
├── ganetimgr
├── __init__.py
├── settings-test.py
├── settings.py.dist
├── urls.py
├── urls
│ └── __init__.py
└── wsgi.py
├── locale
└── el
│ └── LC_MESSAGES
│ ├── django.mo
│ └── django.po
├── manage.py
├── middleware
├── ForceLogout.py
├── MobileDetectionMiddleware.py
├── UserMessages.py
└── __init__.py
├── notifications
├── __init__.py
├── admin.py
├── forms.py
├── migrations
│ ├── 0001_initial.py
│ └── __init__.py
├── models.py
├── tests.py
├── urls.py
├── utils.py
└── views.py
├── readthedocs-requirements.txt
├── requirements.txt
├── static
├── branding
│ ├── logo.png
│ └── logo.xcf
├── flatpagesassets
│ ├── ownership.png
│ ├── ownership_dropdown.png
│ └── user_screen.png
├── ganetimgr
│ ├── css
│ │ ├── base.css
│ │ ├── includes
│ │ │ ├── bootstrap-responsive.min.css
│ │ │ ├── bootstrap-switch.css
│ │ │ ├── bootstrap.min.css
│ │ │ ├── daterangepicker.css
│ │ │ ├── feedek.css
│ │ │ ├── font-awesome.min.css
│ │ │ ├── img-on-top.css
│ │ │ ├── nprogress.css
│ │ │ ├── resp-modal.css
│ │ │ ├── select2-spinner.gif
│ │ │ ├── select2.css
│ │ │ ├── select2.png
│ │ │ └── select2x2.png
│ │ ├── smoothness
│ │ │ └── images
│ │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png
│ │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png
│ │ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png
│ │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png
│ │ │ │ ├── ui-bg_glass_75_dadada_1x400.png
│ │ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png
│ │ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png
│ │ │ │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png
│ │ │ │ ├── ui-icons_222222_256x240.png
│ │ │ │ ├── ui-icons_2e83ff_256x240.png
│ │ │ │ ├── ui-icons_454545_256x240.png
│ │ │ │ ├── ui-icons_888888_256x240.png
│ │ │ │ └── ui-icons_cd0a0a_256x240.png
│ │ └── theme.css
│ ├── fonts
│ │ ├── fontawesome-webfont.eot
│ │ ├── fontawesome-webfont.svg
│ │ ├── fontawesome-webfont.ttf
│ │ └── fontawesome-webfont.woff
│ ├── img
│ │ ├── background_grnet.png
│ │ ├── favicon.ico
│ │ ├── gifs
│ │ │ └── ajax-loader.gif
│ │ ├── learnmore.png
│ │ ├── logo.png
│ │ ├── nodata.jpg
│ │ ├── rule.png
│ │ ├── sprites
│ │ │ ├── glyphicons-halflings-white.png
│ │ │ └── glyphicons-halflings.png
│ │ └── video-crop.png
│ └── js
│ │ ├── includes
│ │ ├── bootstrap-switch.min.js
│ │ ├── bootstrap.min.js
│ │ ├── daterangepicker.js
│ │ ├── feedek.js
│ │ ├── highcharts.js
│ │ ├── jquery-1.10.1.min.js
│ │ ├── jquery-1.10.1.min.map
│ │ ├── jquery.cookie.js
│ │ ├── jquery.dataTables.bootstrap.js
│ │ ├── jquery.dataTables.min.js
│ │ ├── jquery.min.js
│ │ ├── jquery.sparkline.min.js
│ │ ├── moment.min.js
│ │ ├── nprogress.js
│ │ └── select2.js
│ │ ├── jquery_csrf_protect.js
│ │ └── messages.js
├── javavnc
│ └── VncViewer.jar
└── noVNC
│ ├── .gitmodules
│ ├── LICENSE.txt
│ ├── README.md
│ ├── docs
│ ├── LICENSE.Apache-2.0
│ ├── LICENSE.BSD-2-Clause
│ ├── LICENSE.BSD-3-Clause
│ ├── LICENSE.GPL-3
│ ├── LICENSE.LGPL-3
│ ├── LICENSE.MPL-2.0
│ ├── LICENSE.OFL-1.1
│ ├── LICENSE.zlib
│ ├── VERSION
│ ├── flash_policy.txt
│ ├── links
│ ├── notes
│ ├── packaging.txt
│ ├── release.txt
│ ├── rfb_notes
│ ├── rfbproto-3.3.pdf
│ ├── rfbproto-3.7.pdf
│ └── rfbproto-3.8.pdf
│ └── include
│ ├── Orbitron700.ttf
│ ├── Orbitron700.woff
│ ├── base.css
│ ├── base64.js
│ ├── black.css
│ ├── blue.css
│ ├── chrome-app
│ └── tcp-client.js
│ ├── des.js
│ ├── display.js
│ ├── input.js
│ ├── jsunzip.js
│ ├── keyboard.js
│ ├── keysym.js
│ ├── keysymdef.js
│ ├── logo.js
│ ├── playback.js
│ ├── rfb.js
│ ├── ui.js
│ ├── util.js
│ ├── web-socket-js
│ ├── README.txt
│ ├── WebSocketMain.swf
│ ├── swfobject.js
│ └── web_socket.js
│ ├── websock.js
│ ├── websock_old.js
│ └── webutil.js
├── stats
├── __init__.py
├── models.py
├── tests.py
├── urls.py
└── views.py
├── templates
├── 403.html
├── 404.html
├── 500.html
├── apply
│ ├── admin_apply.html
│ ├── application_list.html
│ ├── apply.html
│ ├── emails
│ │ ├── application_rejected_mail.txt
│ │ └── apply_mail.txt
│ └── review.html
├── auditlog
│ └── auditlog.html
├── base.html
├── clusters
│ ├── cluster_nodes.html
│ ├── cluster_nodes_pjax.html
│ └── clusters.html
├── flatpages
│ ├── default.html
│ └── faq.html
├── graphs
│ └── nodes-graphs.html
├── includes
│ ├── analytics.html.dist
│ └── banners.html
├── instances
│ ├── emails
│ │ ├── instance_created_mail.txt
│ │ └── reinstall_mail.txt
│ ├── includes
│ │ ├── console-module.html
│ │ └── instance_status.html
│ ├── instance.html
│ ├── instance_actions.html
│ ├── instance_popup.html
│ ├── novnc.html
│ ├── rename_instance.html
│ ├── user_instances_json.html
│ ├── verify_action.html
│ └── vnc.html
├── jobs
│ ├── job_details.html
│ └── jobs.html
├── news
│ └── news.html
├── notifications
│ ├── create.html
│ ├── create_ajax.html
│ ├── create_body.html
│ ├── create_script.html
│ └── detail.html
├── registration
│ ├── activate.html
│ ├── activation_complete_admin_pending.html
│ ├── activation_complete_admin_pending.txt
│ ├── activation_email.txt
│ ├── activation_email_subject.txt
│ ├── admin_approve.html
│ ├── admin_approve_complete.html
│ ├── admin_approve_complete_email.txt
│ ├── admin_approve_email.txt
│ ├── admin_approve_email_subject.txt
│ ├── password_change_form.html
│ ├── password_reset_complete.html
│ ├── password_reset_confirm.html
│ ├── password_reset_done.html
│ ├── password_reset_email.html
│ ├── password_reset_form.html
│ ├── registration_complete.html
│ ├── registration_form.html
│ └── validation_expired.html
├── stats
│ └── statistics.html
├── tagging
│ ├── isolate.html
│ ├── itags.html
│ └── lock.html
└── users
│ ├── emails
│ ├── idle_account.txt
│ └── pass_change_notify_mail.txt
│ ├── idle_accounts.html
│ ├── login.html
│ ├── mail_change.html
│ ├── name_change.html
│ ├── other_change.html
│ ├── pass_change.html
│ ├── pass_change_done.html
│ ├── profile.html
│ ├── user_info.html
│ └── user_keys.html
├── util
├── __init__.py
├── client.py
└── vapclient.py
├── version
└── watcher.py
/README.md:
--------------------------------------------------------------------------------
1 | # Ganetimgr
2 | [](https://gitter.im/grnet/ganetimgr?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
3 | [](https://readthedocs.org/projects/ganetimgr/?badge=latest)
4 |
5 | `Ganetimgr` is a web platform that eases the provisioning of virtual machines over multiple `ganeti` clusters.
6 | It leverages Ganeti's RAPI functionality to administer the clusters, and is stateless from the VM perspective.
7 | The project is written in `Django` and uses Bootstrap for the frontend.
8 | In essence, ganetimgr aims to be the frontend of a VPS service.
9 |
10 | ## Development
11 |
12 | - 2010-2012 Apollon Oikonomopoulos (@apoikos)
13 | - 2011-2014 Leonidas Poulopoulos (@leopoul)
14 | - 2014-2015 Stavros Kroustouris (@kroustou)
15 | - 2015-2017 Sergios Aftsidis (@sergafts)
16 | - 2017 John Paraskevopoulos (@ioparaskev)
17 |
18 | ## Contribution
19 |
20 | ### Code
21 | - Brian Candler (@candlerb)
22 | - Mike Gabriel (@sunweaver)
23 | - Dimitris Bliablias (@dblia)
24 |
25 | ### Documentation
26 | - 2014 Alex Kiousis (@alexkiousis)
27 | - 2014 Nikos Kokkalis (@nkokkalis)
28 | - 2013 George Kargiotakis (@kargig)
29 |
30 | ## Instructions
31 | For detailed instructions, go to our [readthedocs](http://ganetimgr.readthedocs.org/en/latest/) page.
32 |
33 |
34 | ## Contact Information
35 |
36 | User discussions: ganetimgr-users@lists.grnet.gr
37 |
38 | =====================================================================
39 |
40 | ## Copyright and license
41 |
42 | Copyright © 2010-2018 Greek Research and Technology Network (GRNET S.A.)
43 |
44 | This program is free software: you can redistribute it and/or modify
45 | it under the terms of the GNU General Public License as published by
46 | the Free Software Foundation, either version 3 of the License, or
47 | (at your option) any later version.
48 |
49 | This program is distributed in the hope that it will be useful,
50 | but WITHOUT ANY WARRANTY; without even the implied warranty of
51 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52 | GNU General Public License for more details.
53 |
54 | You should have received a copy of the GNU General Public License
55 | along with this program. If not, see .
56 |
--------------------------------------------------------------------------------
/_version.py:
--------------------------------------------------------------------------------
1 | VERSION = '2.0.0'
2 |
3 | if __name__ == "__main__":
4 | print VERSION
5 |
--------------------------------------------------------------------------------
/accounts/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/accounts/__init__.py
--------------------------------------------------------------------------------
/accounts/admin.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 |
19 | from django.contrib import admin
20 | from accounts.models import UserProfile
21 | from registration.models import RegistrationProfile
22 |
23 |
24 | admin.site.register(UserProfile)
25 | # This unregisters the default RegistrationProfile so that we
26 | # can use our own
27 | admin.site.unregister(RegistrationProfile)
28 |
--------------------------------------------------------------------------------
/accounts/forms.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 | from django import forms
18 | from django.utils.translation import ugettext_lazy as _
19 | from django.contrib.auth.forms import PasswordResetForm
20 | from registration.forms import RegistrationFormUniqueEmail as _RegistrationForm
21 | from apply.models import Organization
22 | from nocaptcha_recaptcha.fields import NoReCaptchaField
23 |
24 |
25 | class RegistrationForm(_RegistrationForm):
26 | name = forms.CharField()
27 | surname = forms.CharField()
28 | phone = forms.CharField(required=False)
29 | organization = forms.ModelChoiceField(
30 | queryset=Organization.objects.all(),
31 | required=False,
32 | label=_("Organization")
33 | )
34 | recaptcha = NoReCaptchaField()
35 |
36 |
37 | class PasswordResetFormPatched(PasswordResetForm):
38 | error_messages = {
39 | 'unknown': _("That e-mail address doesn't have an associated "
40 | "user account or the account has not been activated yet. Are you sure you've registered?"),
41 | 'unusable': _("The user account associated with this e-mail "
42 | "address cannot reset the password."),
43 | }
44 |
--------------------------------------------------------------------------------
/accounts/management/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/accounts/management/__init__.py
--------------------------------------------------------------------------------
/accounts/management/commands/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/accounts/management/commands/__init__.py
--------------------------------------------------------------------------------
/accounts/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models, migrations
5 | from django.conf import settings
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12 | ('registration', '0004_supervisedregistrationprofile'),
13 | ('apply', '0001_initial'),
14 | ]
15 |
16 | operations = [
17 | migrations.CreateModel(
18 | name='CustomRegistrationProfile',
19 | fields=[
20 | ('registrationprofile_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='registration.RegistrationProfile')),
21 | ('admin_activation_key', models.CharField(max_length=40, verbose_name='admin activation key')),
22 | ('validated', models.BooleanField(default=False)),
23 | ],
24 | options={
25 | 'verbose_name': 'registration profile',
26 | 'verbose_name_plural': 'registration profiles',
27 | },
28 | bases=('registration.registrationprofile',),
29 | ),
30 | migrations.CreateModel(
31 | name='UserProfile',
32 | fields=[
33 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
34 | ('first_login', models.BooleanField(default=True)),
35 | ('force_logout_date', models.DateTimeField(null=True, blank=True)),
36 | ('telephone', models.CharField(max_length=13, null=True, blank=True)),
37 | ('organization', models.ForeignKey(blank=True, to='apply.Organization', null=True)),
38 | ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)),
39 | ],
40 | ),
41 | ]
42 |
--------------------------------------------------------------------------------
/accounts/migrations/0002_auto_20161020_1643.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models, migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('accounts', '0001_initial'),
11 | ]
12 |
13 | operations = [
14 | migrations.RemoveField(
15 | model_name='customregistrationprofile',
16 | name='registrationprofile_ptr',
17 | ),
18 | migrations.DeleteModel(
19 | name='CustomRegistrationProfile',
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/accounts/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/accounts/migrations/__init__.py
--------------------------------------------------------------------------------
/accounts/models.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | import datetime
19 |
20 | from apply.models import Organization
21 |
22 | from django.contrib.auth.models import User
23 | from django.contrib.auth.signals import user_logged_in
24 | from django.db import models
25 | from django.db.models.signals import post_save
26 |
27 | try:
28 | from django.utils.timezone import now as datetime_now
29 | except ImportError:
30 | datetime_now = datetime.datetime.now
31 |
32 |
33 | class UserProfile(models.Model):
34 | user = models.OneToOneField(User)
35 | first_login = models.BooleanField(default=True)
36 | force_logout_date = models.DateTimeField(null=True, blank=True)
37 | organization = models.ForeignKey(Organization, blank=True, null=True)
38 | telephone = models.CharField(max_length=13, blank=True, null=True)
39 |
40 | def force_logout(self):
41 | self.force_logout_date = datetime.datetime.now()
42 | self.save()
43 |
44 | def is_owner(self, instance):
45 | if self.user in instance.users:
46 | return True
47 | else:
48 | for group in self.user.groups.all():
49 | if group in instance.groups:
50 | return True
51 | return False
52 |
53 | def __unicode__(self):
54 | return "%s profile" % self.user
55 |
56 |
57 | # Signals
58 | def create_user_profile(sender, instance, created, **kwargs):
59 | if created and not kwargs.get('raw', False):
60 | UserProfile.objects.create(user=instance)
61 | post_save.connect(
62 | create_user_profile, sender=User, dispatch_uid='create_UserProfile')
63 |
64 |
65 | def update_session_last_login(sender, user, request, **kwargs):
66 | if request:
67 | request.session['LAST_LOGIN_DATE'] = datetime.datetime.now()
68 | user_logged_in.connect(update_session_last_login)
69 |
--------------------------------------------------------------------------------
/accounts/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase, Client
2 | from django.core.urlresolvers import reverse
3 | from django.conf import settings
4 | from django.contrib.auth.models import User
5 |
6 |
7 | class AccountsTestCase(TestCase):
8 | def setUp(self):
9 | self.client = Client()
10 | # create a user
11 | self.user = User(
12 | email='test@test.com',
13 | username='test',
14 | )
15 | self.user.save()
16 |
17 | def test_registration_url(self):
18 | res = self.client.get(reverse('registration_register'))
19 | self.assertEqual(res.status_code, 200)
20 |
21 | def test_login_url(self):
22 | res = self.client.get(settings.LOGIN_URL, follow=True)
23 | self.assertEqual(res.status_code, 200)
24 |
25 | def test_activate_url(self):
26 | res = self.client.get(
27 | reverse(
28 | 'registration_activate',
29 | kwargs={'activation_key': 'test'}
30 | )
31 | )
32 | self.assertEqual(res.status_code, 200)
33 |
34 | def test_register(self):
35 | data = {
36 | 'name': 'test2',
37 | 'surname': 'Test2',
38 | 'phone': '1212',
39 | 'email': 'test2@test.com',
40 | 'username': 'test2',
41 | 'recaptcha': 'test',
42 | 'password1': 'test',
43 | 'password2': 'test',
44 | }
45 | res = self.client.post(reverse('registration_register'), data)
46 | # make sure the user is redirected - form is valid
47 | self.assertEqual(res.status_code, 302)
48 |
49 | # there should be the user we just created in the db
50 | user = User.objects.get(email='test2@test.com')
51 |
52 | # make sure this new user is not active
53 | self.assertFalse(user.is_active)
54 |
55 | def test_user_profile(self):
56 | # there should also be a user profile
57 | self.user.userprofile.first_login
58 |
--------------------------------------------------------------------------------
/accounts/urls.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from accounts.forms import PasswordResetFormPatched
19 | from django.conf.urls import url, include
20 | from django.contrib.auth import views as auth_views
21 | from .views import CustomRegistrationView as RegistrationView
22 |
23 |
24 | urlpatterns = [
25 | url(
26 | r'^register/$',
27 | RegistrationView.as_view(),
28 | name='registration_register'
29 | ),
30 | url(
31 | r'^password/reset/$',
32 | auth_views.password_reset,
33 | {
34 | 'password_reset_form':
35 | PasswordResetFormPatched,
36 | },
37 | name='password_reset'
38 | ),
39 | url(r'^reset/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
40 | auth_views.password_reset_confirm, name='password_reset_confirm'),
41 | url(r'^reset/done/$', auth_views.password_reset_complete, name='password_reset_complete'),
42 | url(
43 | r'^password_reset/done/$',
44 | auth_views.password_reset_done,
45 | name='password_reset_done'
46 | ),
47 | url(r'^', include('registration.backends.admin_approval.urls')),
48 | ]
49 |
--------------------------------------------------------------------------------
/accounts/views.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from registration.backends.admin_approval.views import RegistrationView
19 | from apply.models import Organization
20 | from accounts.models import UserProfile
21 |
22 |
23 | class CustomRegistrationView(RegistrationView):
24 |
25 | def register(self, form):
26 |
27 | new_user = super(RegistrationView, self).register(form)
28 |
29 | telephone = form.cleaned_data['phone']
30 | organization = form.cleaned_data['organization']
31 |
32 | profile, created = UserProfile.objects.get_or_create(user=new_user)
33 | try:
34 | organization = Organization.objects.get(title=organization)
35 | profile.organization = organization
36 | except Organization.DoesNotExist:
37 | profile.organization = None
38 |
39 | profile.telephone = telephone
40 | profile.user = new_user
41 | profile.save()
42 |
43 | new_user.first_name = form.cleaned_data['name']
44 | new_user.last_name = form.cleaned_data['surname']
45 | new_user.save()
46 |
47 | return new_user
48 |
--------------------------------------------------------------------------------
/apply/__init__.py:
--------------------------------------------------------------------------------
1 | # default_app_config = 'apply.apps.ApplyConfig'
2 |
--------------------------------------------------------------------------------
/apply/admin.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 | import functools
18 |
19 | from django.contrib import admin
20 |
21 | from apply.models import Organization, InstanceApplication
22 |
23 | class InstanceApplicationAdmin(admin.ModelAdmin):
24 | list_display = ["hostname", "applicant", "organization", "cluster",
25 | "status", "filed"]
26 | list_filter = ["status", "organization"]
27 | search_fields = [
28 | "hostname", "applicant__username", "organization__title", "status", "filed"
29 | ]
30 | list_editable = ["organization"]
31 | readonly_fields = ["job_id", "backend_message", "reviewer"]
32 | ordering = ["-filed", "hostname"]
33 | fieldsets = [
34 | ('Instance Information', {'fields': ('hostname', 'memory', 'disk_size',
35 | 'vcpus', 'operating_system',
36 | 'hosts_mail_server')}),
37 | ('Placement', {'fields': ('instance_params',)}),
38 | ('Owner Information', {'fields': ('applicant', 'organization',
39 | 'admin_contact_name',
40 | 'admin_contact_phone',
41 | 'admin_contact_email')}),
42 | ('Backend Information', {'fields': ('status', 'job_id',
43 | 'backend_message', 'reviewer')})
44 | ]
45 |
46 |
47 | admin.site.register(Organization)
48 | admin.site.register(InstanceApplication, InstanceApplicationAdmin)
49 |
--------------------------------------------------------------------------------
/apply/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ApplyConfig(AppConfig):
5 | name = 'apply'
6 | label = 'ganetimgrapply'
7 | verbose_name = "Apply"
8 |
--------------------------------------------------------------------------------
/apply/decorators.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.decorators import user_passes_test
2 |
3 |
4 | def any_permission_required(*args):
5 | def test_func(user):
6 | for perm in args:
7 | if user.has_perm(perm):
8 | return True
9 | return False
10 | return user_passes_test(test_func)
11 |
--------------------------------------------------------------------------------
/apply/migrations/0002_auto_20161024_1512.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models, migrations
5 | from django.conf import settings
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('apply', '0001_initial'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='organization',
17 | name='users',
18 | field=models.ManyToManyField(to=settings.AUTH_USER_MODEL, blank=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/apply/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/apply/migrations/__init__.py
--------------------------------------------------------------------------------
/apply/urls/__init__.py:
--------------------------------------------------------------------------------
1 | from application import *
2 | from user import *
3 |
--------------------------------------------------------------------------------
/apply/urls/application.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf.urls import url
19 | from apply import views
20 |
21 | urlpatterns = [
22 | url(r'^apply/?$', views.apply, name="apply"),
23 | url(r'^list/?$', views.application_list, name="application-list"),
24 | # this url is accessible only if a superuser tries to create
25 | # an instance by himself
26 | url(r'^save/', views.review_application, name="application-save"),
27 | url(r'^(?P\d+)/review/$', views.review_application, name="application-review"),
28 | url(r'^(?P\d+)/(?P\w+)/ssh_keys', views.instance_ssh_keys, name="instance-ssh-keys"),
29 | ]
30 |
--------------------------------------------------------------------------------
/apply/urls/user.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf.urls import url
19 | from apply import views
20 | from django.contrib.auth.views import login, logout, password_change, password_change_done
21 | from ganeti.forms import PickyAuthenticationForm
22 |
23 | urlpatterns = [
24 | url(r'^info/(?P\w+)/(?P[\w\.\@-]+)/?$', views.user_info, name="user-info"),
25 | url(r'^details/$', views.detail_api, name="user-details-json"),
26 | url(r'^idle/$', views.idle_accounts, name="idle_accounts"),
27 | url(r'^profile/$', views.profile, name="profile"),
28 | url(r'^mail_change/$', views.mail_change, name="mail-change"),
29 | url(r'^name_change/$', views.name_change, name="name-change"),
30 | url(r'^other_change/$', views.other_change, name="other-change"),
31 | url(r'^keys/$', views.user_keys, name="user-keys"),
32 | url(r'^keys/delete/(?P\d+)?$', views.delete_key, name="delete-key"),
33 | url(r'^login/', login, {'template_name': 'users/login.html',
34 | 'authentication_form': PickyAuthenticationForm},
35 | name="login"),
36 | url(r'^logout/', logout, {'next_page': '/'}, name="logout"),
37 | url(r'^pass_change/$', password_change, {'template_name':'users/pass_change.html', 'post_change_redirect':'pass_change_done'}, name="pass_change"),
38 | url(r'^pass_change/done/$', password_change_done, {'template_name':'users/pass_change_done.html'}, name="pass_change_done" ),
39 | url(r'^pass_change/notify/$', views.pass_notify, name="pass_change_notify"),
40 | ]
41 |
--------------------------------------------------------------------------------
/apply/utils.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 | from ganeti.models import InstanceAction
18 |
19 |
20 | def check_mail_change_pending(user):
21 | actions = []
22 | pending_actions = InstanceAction.objects.filter(applicant=user, action=4)
23 | for pending in pending_actions:
24 | if pending.activation_key_expired():
25 | continue
26 | actions.append(pending)
27 | if len(actions) == 0:
28 | return False
29 | elif len(actions) == 1:
30 | return True
31 | else:
32 | return False
33 |
34 |
--------------------------------------------------------------------------------
/auditlog/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/auditlog/__init__.py
--------------------------------------------------------------------------------
/auditlog/admin.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.contrib import admin
19 | from models import AuditEntry
20 |
21 |
22 | class AuditEntryAdmin(admin.ModelAdmin):
23 | list_display = (
24 | 'requester',
25 | 'action',
26 | 'instance',
27 | 'cluster',
28 | 'job_id',
29 | 'last_updated'
30 | )
31 | list_filter = ('cluster', 'action', 'last_updated')
32 |
33 | admin.site.register(AuditEntry, AuditEntryAdmin)
34 |
35 |
36 |
--------------------------------------------------------------------------------
/auditlog/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models, migrations
5 | from django.conf import settings
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12 | ]
13 |
14 | operations = [
15 | migrations.CreateModel(
16 | name='AuditEntry',
17 | fields=[
18 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
19 | ('ipaddress', models.CharField(max_length=255, null=True, blank=True)),
20 | ('action', models.CharField(max_length=255)),
21 | ('instance', models.CharField(max_length=255)),
22 | ('cluster', models.CharField(max_length=50)),
23 | ('job_id', models.IntegerField(null=True, blank=True)),
24 | ('recorded', models.DateTimeField(auto_now_add=True)),
25 | ('last_updated', models.DateTimeField(auto_now=True)),
26 | ('is_authorized', models.BooleanField(default=True)),
27 | ('requester', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
28 | ],
29 | ),
30 | ]
31 |
--------------------------------------------------------------------------------
/auditlog/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/auditlog/migrations/__init__.py
--------------------------------------------------------------------------------
/auditlog/models.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.db import models
19 | from django.contrib.auth.models import User
20 |
21 |
22 | class AuditEntry(models.Model):
23 | requester = models.ForeignKey(User)
24 | ipaddress = models.CharField(max_length=255, null=True, blank=True)
25 | action = models.CharField(max_length=255)
26 | instance = models.CharField(max_length=255)
27 | cluster = models.CharField(max_length=50)
28 | job_id = models.IntegerField(null=True, blank=True)
29 | recorded = models.DateTimeField(auto_now_add=True)
30 | last_updated = models.DateTimeField(auto_now=True)
31 | is_authorized = models.BooleanField(default=True)
32 |
33 | def __unicode__(self):
34 | return "%s %s %s" % (self.requester, self.action, self.instance)
35 |
36 | def update(self, **kwargs):
37 | for k, v in kwargs.iteritems():
38 | setattr(self, k, v)
39 | self.save()
40 |
--------------------------------------------------------------------------------
/auditlog/signals.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Copyright (C) 2010-2014 GRNET S.A.
4 | #
5 | # This program is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # This program is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with this program. If not, see .
17 | #
18 | import django.dispatch
19 | from django.contrib.auth.models import User
20 | from auditlog.models import AuditEntry
21 | audit_entry = django.dispatch.Signal()
22 |
23 |
24 | def store_audit_entry(sender, *args, **kwargs):
25 | if 'user' in kwargs.keys():
26 | user = kwargs['user']
27 | if 'ipaddress' in kwargs.keys():
28 | ipaddress = kwargs['ipaddress']
29 | if 'action' in kwargs.keys():
30 | action = kwargs['action']
31 | if 'instance' in kwargs.keys():
32 | instance = kwargs['instance']
33 | if 'cluster' in kwargs.keys():
34 | cluster = kwargs['cluster']
35 | auditlog = AuditEntry(
36 | requester=User.objects.get(pk=user),
37 | ipaddress=ipaddress,
38 | action=action,
39 | instance=instance,
40 | cluster=cluster
41 | )
42 | auditlog.save
43 |
44 | audit_entry.connect(store_audit_entry)
45 |
46 |
47 | def get_client_ip(request):
48 | x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
49 | if x_forwarded_for:
50 | ip = x_forwarded_for.split(',')[0]
51 | else:
52 | ip = request.META.get('REMOTE_ADDR')
53 | return ip
54 |
--------------------------------------------------------------------------------
/auditlog/urls.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf.urls import url
19 | from auditlog import views
20 |
21 | urlpatterns = [
22 | url(r'^$', views.auditlog, name='auditlog'),
23 | url(r'^json/$', views.auditlog_json, name='auditlog_json'),
24 | ]
25 |
--------------------------------------------------------------------------------
/auditlog/utils.py:
--------------------------------------------------------------------------------
1 | from auditlog.models import AuditEntry
2 | from django.contrib.auth.models import User
3 |
4 |
5 | def get_client_ip(request):
6 | x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
7 | if x_forwarded_for:
8 | ip = x_forwarded_for.split(',')[0]
9 | else:
10 | ip = request.META.get('REMOTE_ADDR')
11 | return ip
12 |
13 |
14 | def auditlog_entry(request, action, instance,
15 | cluster, save=True, authorized=True):
16 | entry = AuditEntry(
17 | requester=User.objects.get(pk=request.user.id),
18 | ipaddress=get_client_ip(request),
19 | action=action,
20 | instance=instance,
21 | cluster=cluster,
22 | is_authorized=authorized
23 | )
24 | if save:
25 | entry.save()
26 | return entry
27 |
--------------------------------------------------------------------------------
/context/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/context/__init__.py
--------------------------------------------------------------------------------
/context/global_vars.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf import settings
19 |
20 |
21 | def settings_vars(context):
22 | # return the value you want as a dictionary. you may add multiple
23 | # values in there. Also check if these values exist in settings.py
24 |
25 | return {
26 | 'HELPDESK_INTEGRATION_JAVASCRIPT_URL': settings.HELPDESK_INTEGRATION_JAVASCRIPT_URL if hasattr(settings, 'HELPDESK_INTEGRATION_JAVASCRIPT_URL') else '',
27 | 'HELPDESK_INTEGRATION_JAVASCRIPT_PARAMS': settings.HELPDESK_INTEGRATION_JAVASCRIPT_PARAMS if hasattr(settings, 'HELPDESK_INTEGRATION_JAVASCRIPT_PARAMS') else '',
28 | 'VERSION': settings.SW_VERSION if hasattr(settings, 'SW_VERSION') else '',
29 | 'WEBSOCK_VNC_ENABLED': settings.WEBSOCK_VNC_ENABLED if hasattr(settings, 'WEBSOCK_VNC_ENABLED') else '',
30 | 'LEGACY_VNC_ENABLED': getattr(settings, 'LEGACY_VNC_ENABLED', ''),
31 | 'BRANDING': settings.BRANDING if hasattr(settings, 'BRANDING') else '',
32 | 'FLATPAGES': settings.FLATPAGES if hasattr(settings, 'FLATPAGES') else '',
33 | 'COLLECTD_URL': settings.COLLECTD_URL if hasattr(settings, 'COLLECTD_URL') else ''
34 | }
35 |
--------------------------------------------------------------------------------
/context/pending_notifications.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 | from apply.models import InstanceApplication, STATUS_PENDING
18 | from django.core.cache import cache
19 |
20 |
21 | def notify(request):
22 | res = {}
23 | if request.user:
24 | if request.user.has_perm("apply.change_instanceapplication"):
25 | res.update(can_handle_applications=True)
26 | elif request.user.has_perm("apply.view_applications"):
27 | res.update(can_view_applications=True)
28 | else:
29 | return res
30 | cres = cache.get('pendingapplications')
31 | if cres is None:
32 | pend = InstanceApplication.objects.filter(status=STATUS_PENDING)
33 | res.update(pending_count=pend.count())
34 | cache.set('pendingapplications', res, 45)
35 | else:
36 | res = cres
37 | return res
38 |
--------------------------------------------------------------------------------
/context/session_remaining.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf import settings
19 | import datetime
20 |
21 |
22 | def seconds(request):
23 | remaining = False
24 | if (
25 | request.user.is_authenticated() and
26 | request.user.userprofile.force_logout_date and
27 | (
28 | 'LAST_LOGIN_DATE' not in request.session or
29 | request.session['LAST_LOGIN_DATE'] < request.user.userprofile.force_logout_date
30 | )
31 | ):
32 | remaining = 2
33 | if not request.user.is_anonymous():
34 | if 'LAST_LOGIN_DATE' in request.session:
35 | last_login = request.session['LAST_LOGIN_DATE']
36 | now = datetime.datetime.now()
37 | if now > last_login:
38 | elapsed = (now - last_login).seconds
39 | remaining = settings.SESSION_COOKIE_AGE - elapsed
40 | if remaining < 0:
41 | remaining = 2
42 | else:
43 | remaining = 2
44 | return {"session_remaining": remaining}
45 |
--------------------------------------------------------------------------------
/contrib/CONTENTS:
--------------------------------------------------------------------------------
1 | 3rd party sources
2 |
3 | vnc_javasrc: the source used to build /static/javavnc/VncViewer.jar
4 |
5 | init.d: init script to start ganetimgr-watcher
6 |
7 | default: sample defaults file for ganetimgr-watcher (use with init script)
8 |
--------------------------------------------------------------------------------
/contrib/default/ganetimgr-watcher:
--------------------------------------------------------------------------------
1 | RUN=yes
2 |
--------------------------------------------------------------------------------
/contrib/fabric/requirements.txt:
--------------------------------------------------------------------------------
1 | Fabric==1.10.2
2 |
--------------------------------------------------------------------------------
/contrib/fabric/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/contrib/fabric/utils/__init__.py
--------------------------------------------------------------------------------
/contrib/fabric/utils/database.py:
--------------------------------------------------------------------------------
1 | from fabric.api import run
2 | from fabric.operations import sudo
3 |
4 |
5 | def dump_mysql(settings, target):
6 | try:
7 | sudo('mysqldump -u %s --password=%s %s -h %s -P %s > %s' % (
8 | settings.get('USER'),
9 | settings.get('PASSWORD'),
10 | settings.get('NAME'),
11 | settings.get('HOST') or 'localhost',
12 | settings.get('PORT') or '13306',
13 | target
14 | ))
15 | except:
16 | return False
17 | else:
18 | return True
19 |
20 |
21 | def drop_mysql(settings):
22 | sudo("mysql -u %s --password=%s -h %s -P %s -e 'DROP DATABASE %s'" % (
23 | settings.get('USER'),
24 | settings.get('PASSWORD'),
25 | settings.get('HOST') or 'localhost',
26 | settings.get('PORT') or '13306',
27 | settings.get('NAME')
28 | ))
29 |
30 |
31 | def create_mysql(settings):
32 | sudo("mysql -u %s --password=%s -h %s -P %s -e 'CREATE DATABASE %s'" % (
33 | settings.get('USER'),
34 | settings.get('PASSWORD'),
35 | settings.get('HOST') or 'localhost',
36 | settings.get('PORT') or '13306',
37 | settings.get('NAME'),
38 | ))
39 |
40 |
41 | def import_mysql(settings, dump_path):
42 | run('mysql -u %s --password=%s -h %s -P %s %s < %s' %
43 | (
44 | settings.get('USER'),
45 | settings.get('PASSWORD'),
46 | settings.get('HOST') or 'localhost',
47 | settings.get('PORT') or '13306',
48 | settings.get('NAME'),
49 | dump_path
50 | ))
51 |
52 |
53 | def recreate_mysql(settings):
54 | drop_mysql(settings)
55 | create_mysql(settings)
56 |
--------------------------------------------------------------------------------
/contrib/fabric/utils/django.py:
--------------------------------------------------------------------------------
1 | from fabric.api import cd, run, prefix
2 | from utils.operations import try_to_execute
3 | from fabric.operations import sudo
4 |
5 |
6 | def collectstatic(path, venv=False):
7 | with cd(path):
8 | if venv:
9 | with prefix(venv):
10 | try_to_execute('./manage.py collectstatic --noinput')
11 | else:
12 | try_to_execute('./manage.py collectstatic --noinput')
13 |
14 |
15 | def clean_pyc(path):
16 | with cd(path):
17 | sudo('find -name "*.pyc" -delete')
18 |
19 |
20 | def db_config(settings):
21 | # grep the database settings from settings.py
22 | database_settings = run(" grep -A10 '\DATABASES = {' %s | grep -E 'NAME|ENGINE|PASSWO|HOST|PORT|USER'" % settings)
23 | db_settings = {}
24 | for s in database_settings.split('\n'):
25 | s = s.strip().split(',')[0].split(':')
26 | db_settings.update({s[0].split('\'')[1]: s[1].split('\'')[1]})
27 | return db_settings
28 |
--------------------------------------------------------------------------------
/contrib/fabric/utils/git.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from datetime import datetime
4 |
5 | from fabric.api import cd, run, abort
6 | from fabric.contrib.files import exists
7 | from fabric.operations import sudo
8 |
9 |
10 | def get_new_version(project_name, target, repository, tag):
11 | '''
12 | Fetches selected tag and puts it under the selected
13 | directory
14 | '''
15 | dir_name = '%s-%s' % (project_name, datetime.today().strftime('%Y%m%d%H%M'))
16 | with cd('/tmp'):
17 | # remove junk dirs
18 | if exists(project_name):
19 | run('rm -rf %s' % project_name)
20 | if exists(dir_name):
21 | run('rm -rf %s' % dir_name)
22 | # fresh clone
23 | run('git clone %s --quiet' % repository)
24 | with cd(project_name):
25 | try:
26 | # archive tag
27 | run('git archive --format=tar --prefix=%s/ %s | (cd /tmp/ && tar xf -) ' % (dir_name, tag))
28 | except:
29 | abort('Make sure %s exists in the repository.' % tag)
30 | # rm cloned code
31 | run('rm -rf %s' % project_name)
32 | # move into the proper dir
33 | if exists(os.path.join(target, dir_name)):
34 | sudo('rm -r %s' % os.path.join(target, dir_name))
35 | sudo('mv %s %s' % (dir_name, target))
36 | return os.path.join(target, dir_name)
37 |
--------------------------------------------------------------------------------
/contrib/fabric/utils/operations.py:
--------------------------------------------------------------------------------
1 | import os
2 | from fabric.api import run
3 | from fabric.contrib.files import exists
4 | from fabric.operations import sudo
5 | from fabric.context_managers import settings
6 |
7 |
8 | def get_real_path(project_dir, project):
9 | link = run('ls -la %s' % os.path.join(project_dir, project))
10 | return link.split('-> ')[-1]
11 |
12 |
13 | def new_symlink(new_path, project_dir, project):
14 | if exists(os.path.join(project_dir, project)):
15 | sudo('rm %s' % os.path.join(project_dir, project))
16 | sudo('ln -s %s %s' % (new_path, os.path.join(project_dir, project)))
17 |
18 |
19 | def try_to_execute(cmd):
20 | # in case of an error raises exception with
21 | # the error message
22 | with settings(warn_only=True):
23 | result = sudo(cmd)
24 | if result.failed:
25 | raise Exception(result.stdout)
26 |
--------------------------------------------------------------------------------
/contrib/fabric/utils/services.py:
--------------------------------------------------------------------------------
1 | from fabric.operations import sudo
2 |
3 |
4 | def stop_beanstalk():
5 | sudo('service beanstalkd stop')
6 |
7 |
8 | def start_beanstalk():
9 | sudo('service beanstalkd start')
10 |
11 |
12 | def restart_beanstalk():
13 | stop_beanstalk()
14 | start_beanstalk()
15 |
16 |
17 | def stop_redis():
18 | sudo('service redis-server stop')
19 |
20 |
21 | def start_redis():
22 | sudo('service redis-server start')
23 |
24 |
25 | def restart_redis():
26 | stop_redis()
27 | start_redis()
28 |
29 |
30 | def stop_nginx():
31 | sudo('/etc/init.d/nginx stop')
32 |
33 |
34 | def start_nginx():
35 | sudo('/etc/init.d/nginx start')
36 |
37 |
38 | def restart_nginx():
39 | stop_nginx()
40 | start_nginx()
41 |
42 |
43 | def stop_gunicorn():
44 | sudo('/etc/init.d/gunicorn stop')
45 |
46 |
47 | def start_gunicorn(app=None):
48 | sudo('/etc/init.d/gunicorn start %s' % (app or ''))
49 |
50 |
51 | def restart_gunicorn(app=None):
52 | stop_gunicorn()
53 | start_gunicorn(app)
54 |
55 |
56 | def stop_uwsgi(app=None):
57 | sudo('/etc/init.d/uwsgi stop %s' % (app or ''))
58 |
59 |
60 | def start_uwsgi(app=None):
61 | sudo('/etc/init.d/uwsgi stop %s' % (app or ''))
62 |
63 |
64 | def restart_uwsgi(app=None):
65 | stop_uwsgi(app)
66 | start_uwsgi(app)
67 |
--------------------------------------------------------------------------------
/contrib/gunicorn/ganetimgr_jessie:
--------------------------------------------------------------------------------
1 | CONFIG = {
2 | 'mode': 'wsgi',
3 | 'user': 'www-data',
4 | 'group': 'www-data',
5 | 'args': (
6 | '--chdir=/srv/www/ganetimgr',
7 | '--bind=127.0.0.1:8088',
8 | '--workers=2',
9 | '--worker-class=gevent',
10 | '--timeout=30',
11 | '--log-file=/var/log/ganetimgr.log',
12 | 'ganetimgr.wsgi:application',
13 | ),
14 | }
15 |
--------------------------------------------------------------------------------
/contrib/gunicorn/ganetimgr_wheezy:
--------------------------------------------------------------------------------
1 | CONFIG = {
2 | 'mode': 'django',
3 | 'working_dir': '/srv/ganetimgr',
4 | 'user': 'www-data',
5 | 'group': 'www-data',
6 | 'args': (
7 | '--bind=127.0.0.1:8088',
8 | '--workers=2',
9 | '--worker-class=egg:gunicorn#gevent',
10 | '--timeout=30',
11 | '--log-file=/var/log/ganetimgr/ganetimgr.log',
12 | ),
13 | }
14 |
--------------------------------------------------------------------------------
/contrib/jquery-ui/jquery.effects.blind.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Effects Blind @VERSION
3 | *
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 | * Dual licensed under the MIT or GPL Version 2 licenses.
6 | * http://jquery.org/license
7 | *
8 | * http://docs.jquery.com/UI/Effects/Blind
9 | *
10 | * Depends:
11 | * jquery.effects.core.js
12 | */
13 | (function( $, undefined ) {
14 |
15 | $.effects.blind = function(o) {
16 |
17 | return this.queue(function() {
18 |
19 | // Create element
20 | var el = $(this), props = ['position','top','bottom','left','right'];
21 |
22 | // Set options
23 | var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
24 | var direction = o.options.direction || 'vertical'; // Default direction
25 |
26 | // Adjust
27 | $.effects.save(el, props); el.show(); // Save & Show
28 | var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
29 | var ref = (direction == 'vertical') ? 'height' : 'width';
30 | var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
31 | if(mode == 'show') wrapper.css(ref, 0); // Shift
32 |
33 | // Animation
34 | var animation = {};
35 | animation[ref] = mode == 'show' ? distance : 0;
36 |
37 | // Animate
38 | wrapper.animate(animation, o.duration, o.options.easing, function() {
39 | if(mode == 'hide') el.hide(); // Hide
40 | $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
41 | if(o.callback) o.callback.apply(el[0], arguments); // Callback
42 | el.dequeue();
43 | });
44 |
45 | });
46 |
47 | };
48 |
49 | })(jQuery);
50 |
--------------------------------------------------------------------------------
/contrib/jquery-ui/jquery.effects.clip.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Effects Clip @VERSION
3 | *
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 | * Dual licensed under the MIT or GPL Version 2 licenses.
6 | * http://jquery.org/license
7 | *
8 | * http://docs.jquery.com/UI/Effects/Clip
9 | *
10 | * Depends:
11 | * jquery.effects.core.js
12 | */
13 | (function( $, undefined ) {
14 |
15 | $.effects.clip = function(o) {
16 |
17 | return this.queue(function() {
18 |
19 | // Create element
20 | var el = $(this), props = ['position','top','bottom','left','right','height','width'];
21 |
22 | // Set options
23 | var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
24 | var direction = o.options.direction || 'vertical'; // Default direction
25 |
26 | // Adjust
27 | $.effects.save(el, props); el.show(); // Save & Show
28 | var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
29 | var animate = el[0].tagName == 'IMG' ? wrapper : el;
30 | var ref = {
31 | size: (direction == 'vertical') ? 'height' : 'width',
32 | position: (direction == 'vertical') ? 'top' : 'left'
33 | };
34 | var distance = (direction == 'vertical') ? animate.height() : animate.width();
35 | if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
36 |
37 | // Animation
38 | var animation = {};
39 | animation[ref.size] = mode == 'show' ? distance : 0;
40 | animation[ref.position] = mode == 'show' ? 0 : distance / 2;
41 |
42 | // Animate
43 | animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
44 | if(mode == 'hide') el.hide(); // Hide
45 | $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
46 | if(o.callback) o.callback.apply(el[0], arguments); // Callback
47 | el.dequeue();
48 | }});
49 |
50 | });
51 |
52 | };
53 |
54 | })(jQuery);
55 |
--------------------------------------------------------------------------------
/contrib/jquery-ui/jquery.effects.drop.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Effects Drop @VERSION
3 | *
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 | * Dual licensed under the MIT or GPL Version 2 licenses.
6 | * http://jquery.org/license
7 | *
8 | * http://docs.jquery.com/UI/Effects/Drop
9 | *
10 | * Depends:
11 | * jquery.effects.core.js
12 | */
13 | (function( $, undefined ) {
14 |
15 | $.effects.drop = function(o) {
16 |
17 | return this.queue(function() {
18 |
19 | // Create element
20 | var el = $(this), props = ['position','top','bottom','left','right','opacity'];
21 |
22 | // Set options
23 | var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
24 | var direction = o.options.direction || 'left'; // Default Direction
25 |
26 | // Adjust
27 | $.effects.save(el, props); el.show(); // Save & Show
28 | $.effects.createWrapper(el); // Create Wrapper
29 | var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
30 | var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
31 | var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
32 | if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
33 |
34 | // Animation
35 | var animation = {opacity: mode == 'show' ? 1 : 0};
36 | animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
37 |
38 | // Animate
39 | el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
40 | if(mode == 'hide') el.hide(); // Hide
41 | $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
42 | if(o.callback) o.callback.apply(this, arguments); // Callback
43 | el.dequeue();
44 | }});
45 |
46 | });
47 |
48 | };
49 |
50 | })(jQuery);
51 |
--------------------------------------------------------------------------------
/contrib/jquery-ui/jquery.effects.fade.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Effects Fade @VERSION
3 | *
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 | * Dual licensed under the MIT or GPL Version 2 licenses.
6 | * http://jquery.org/license
7 | *
8 | * http://docs.jquery.com/UI/Effects/Fade
9 | *
10 | * Depends:
11 | * jquery.effects.core.js
12 | */
13 | (function( $, undefined ) {
14 |
15 | $.effects.fade = function(o) {
16 | return this.queue(function() {
17 | var elem = $(this),
18 | mode = $.effects.setMode(elem, o.options.mode || 'hide');
19 |
20 | elem.animate({ opacity: mode }, {
21 | queue: false,
22 | duration: o.duration,
23 | easing: o.options.easing,
24 | complete: function() {
25 | (o.callback && o.callback.apply(this, arguments));
26 | elem.dequeue();
27 | }
28 | });
29 | });
30 | };
31 |
32 | })(jQuery);
33 |
--------------------------------------------------------------------------------
/contrib/jquery-ui/jquery.effects.fold.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Effects Fold @VERSION
3 | *
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 | * Dual licensed under the MIT or GPL Version 2 licenses.
6 | * http://jquery.org/license
7 | *
8 | * http://docs.jquery.com/UI/Effects/Fold
9 | *
10 | * Depends:
11 | * jquery.effects.core.js
12 | */
13 | (function( $, undefined ) {
14 |
15 | $.effects.fold = function(o) {
16 |
17 | return this.queue(function() {
18 |
19 | // Create element
20 | var el = $(this), props = ['position','top','bottom','left','right'];
21 |
22 | // Set options
23 | var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
24 | var size = o.options.size || 15; // Default fold size
25 | var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
26 | var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
27 |
28 | // Adjust
29 | $.effects.save(el, props); el.show(); // Save & Show
30 | var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
31 | var widthFirst = ((mode == 'show') != horizFirst);
32 | var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
33 | var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
34 | var percent = /([0-9]+)%/.exec(size);
35 | if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
36 | if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
37 |
38 | // Animation
39 | var animation1 = {}, animation2 = {};
40 | animation1[ref[0]] = mode == 'show' ? distance[0] : size;
41 | animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
42 |
43 | // Animate
44 | wrapper.animate(animation1, duration, o.options.easing)
45 | .animate(animation2, duration, o.options.easing, function() {
46 | if(mode == 'hide') el.hide(); // Hide
47 | $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
48 | if(o.callback) o.callback.apply(el[0], arguments); // Callback
49 | el.dequeue();
50 | });
51 |
52 | });
53 |
54 | };
55 |
56 | })(jQuery);
57 |
--------------------------------------------------------------------------------
/contrib/jquery-ui/jquery.effects.highlight.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Effects Highlight @VERSION
3 | *
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 | * Dual licensed under the MIT or GPL Version 2 licenses.
6 | * http://jquery.org/license
7 | *
8 | * http://docs.jquery.com/UI/Effects/Highlight
9 | *
10 | * Depends:
11 | * jquery.effects.core.js
12 | */
13 | (function( $, undefined ) {
14 |
15 | $.effects.highlight = function(o) {
16 | return this.queue(function() {
17 | var elem = $(this),
18 | props = ['backgroundImage', 'backgroundColor', 'opacity'],
19 | mode = $.effects.setMode(elem, o.options.mode || 'show'),
20 | animation = {
21 | backgroundColor: elem.css('backgroundColor')
22 | };
23 |
24 | if (mode == 'hide') {
25 | animation.opacity = 0;
26 | }
27 |
28 | $.effects.save(elem, props);
29 | elem
30 | .show()
31 | .css({
32 | backgroundImage: 'none',
33 | backgroundColor: o.options.color || '#ffff99'
34 | })
35 | .animate(animation, {
36 | queue: false,
37 | duration: o.duration,
38 | easing: o.options.easing,
39 | complete: function() {
40 | (mode == 'hide' && elem.hide());
41 | $.effects.restore(elem, props);
42 | (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
43 | (o.callback && o.callback.apply(this, arguments));
44 | elem.dequeue();
45 | }
46 | });
47 | });
48 | };
49 |
50 | })(jQuery);
51 |
--------------------------------------------------------------------------------
/contrib/jquery-ui/jquery.effects.pulsate.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Effects Pulsate @VERSION
3 | *
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 | * Dual licensed under the MIT or GPL Version 2 licenses.
6 | * http://jquery.org/license
7 | *
8 | * http://docs.jquery.com/UI/Effects/Pulsate
9 | *
10 | * Depends:
11 | * jquery.effects.core.js
12 | */
13 | (function( $, undefined ) {
14 |
15 | $.effects.pulsate = function(o) {
16 | return this.queue(function() {
17 | var elem = $(this),
18 | mode = $.effects.setMode(elem, o.options.mode || 'show');
19 | times = ((o.options.times || 5) * 2) - 1;
20 | duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
21 | isVisible = elem.is(':visible'),
22 | animateTo = 0;
23 |
24 | if (!isVisible) {
25 | elem.css('opacity', 0).show();
26 | animateTo = 1;
27 | }
28 |
29 | if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
30 | times--;
31 | }
32 |
33 | for (var i = 0; i < times; i++) {
34 | elem.animate({ opacity: animateTo }, duration, o.options.easing);
35 | animateTo = (animateTo + 1) % 2;
36 | }
37 |
38 | elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
39 | if (animateTo == 0) {
40 | elem.hide();
41 | }
42 | (o.callback && o.callback.apply(this, arguments));
43 | });
44 |
45 | elem
46 | .queue('fx', function() { elem.dequeue(); })
47 | .dequeue();
48 | });
49 | };
50 |
51 | })(jQuery);
52 |
--------------------------------------------------------------------------------
/contrib/jquery-ui/jquery.effects.shake.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Effects Shake @VERSION
3 | *
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 | * Dual licensed under the MIT or GPL Version 2 licenses.
6 | * http://jquery.org/license
7 | *
8 | * http://docs.jquery.com/UI/Effects/Shake
9 | *
10 | * Depends:
11 | * jquery.effects.core.js
12 | */
13 | (function( $, undefined ) {
14 |
15 | $.effects.shake = function(o) {
16 |
17 | return this.queue(function() {
18 |
19 | // Create element
20 | var el = $(this), props = ['position','top','bottom','left','right'];
21 |
22 | // Set options
23 | var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
24 | var direction = o.options.direction || 'left'; // Default direction
25 | var distance = o.options.distance || 20; // Default distance
26 | var times = o.options.times || 3; // Default # of times
27 | var speed = o.duration || o.options.duration || 140; // Default speed per shake
28 |
29 | // Adjust
30 | $.effects.save(el, props); el.show(); // Save & Show
31 | $.effects.createWrapper(el); // Create Wrapper
32 | var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
33 | var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
34 |
35 | // Animation
36 | var animation = {}, animation1 = {}, animation2 = {};
37 | animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
38 | animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2;
39 | animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2;
40 |
41 | // Animate
42 | el.animate(animation, speed, o.options.easing);
43 | for (var i = 1; i < times; i++) { // Shakes
44 | el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
45 | };
46 | el.animate(animation1, speed, o.options.easing).
47 | animate(animation, speed / 2, o.options.easing, function(){ // Last shake
48 | $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
49 | if(o.callback) o.callback.apply(this, arguments); // Callback
50 | });
51 | el.queue('fx', function() { el.dequeue(); });
52 | el.dequeue();
53 | });
54 |
55 | };
56 |
57 | })(jQuery);
58 |
--------------------------------------------------------------------------------
/contrib/jquery-ui/jquery.effects.slide.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Effects Slide @VERSION
3 | *
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 | * Dual licensed under the MIT or GPL Version 2 licenses.
6 | * http://jquery.org/license
7 | *
8 | * http://docs.jquery.com/UI/Effects/Slide
9 | *
10 | * Depends:
11 | * jquery.effects.core.js
12 | */
13 | (function( $, undefined ) {
14 |
15 | $.effects.slide = function(o) {
16 |
17 | return this.queue(function() {
18 |
19 | // Create element
20 | var el = $(this), props = ['position','top','bottom','left','right'];
21 |
22 | // Set options
23 | var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
24 | var direction = o.options.direction || 'left'; // Default Direction
25 |
26 | // Adjust
27 | $.effects.save(el, props); el.show(); // Save & Show
28 | $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
29 | var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
30 | var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
31 | var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
32 | if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
33 |
34 | // Animation
35 | var animation = {};
36 | animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
37 |
38 | // Animate
39 | el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
40 | if(mode == 'hide') el.hide(); // Hide
41 | $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
42 | if(o.callback) o.callback.apply(this, arguments); // Callback
43 | el.dequeue();
44 | }});
45 |
46 | });
47 |
48 | };
49 |
50 | })(jQuery);
51 |
--------------------------------------------------------------------------------
/contrib/jquery-ui/jquery.effects.transfer.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Effects Transfer @VERSION
3 | *
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 | * Dual licensed under the MIT or GPL Version 2 licenses.
6 | * http://jquery.org/license
7 | *
8 | * http://docs.jquery.com/UI/Effects/Transfer
9 | *
10 | * Depends:
11 | * jquery.effects.core.js
12 | */
13 | (function( $, undefined ) {
14 |
15 | $.effects.transfer = function(o) {
16 | return this.queue(function() {
17 | var elem = $(this),
18 | target = $(o.options.to),
19 | endPosition = target.offset(),
20 | animation = {
21 | top: endPosition.top,
22 | left: endPosition.left,
23 | height: target.innerHeight(),
24 | width: target.innerWidth()
25 | },
26 | startPosition = elem.offset(),
27 | transfer = $('
')
28 | .appendTo(document.body)
29 | .addClass(o.options.className)
30 | .css({
31 | top: startPosition.top,
32 | left: startPosition.left,
33 | height: elem.innerHeight(),
34 | width: elem.innerWidth(),
35 | position: 'absolute'
36 | })
37 | .animate(animation, o.duration, o.options.easing, function() {
38 | transfer.remove();
39 | (o.callback && o.callback.apply(elem[0], arguments));
40 | elem.dequeue();
41 | });
42 | });
43 | };
44 |
45 | })(jQuery);
46 |
--------------------------------------------------------------------------------
/contrib/vnc_javasrc/HTTPConnectSocket.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved.
3 | //
4 | // This is free software; you can redistribute it and/or modify
5 | // it under the terms of the GNU General Public License as published by
6 | // the Free Software Foundation; either version 2 of the License, or
7 | // (at your option) any later version.
8 | //
9 | // This software is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | // GNU General Public License for more details.
13 | //
14 | // You should have received a copy of the GNU General Public License
15 | // along with this software; if not, write to the Free Software
16 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 | // USA.
18 | //
19 |
20 | //
21 | // HTTPConnectSocket.java together with HTTPConnectSocketFactory.java
22 | // implement an alternate way to connect to VNC servers via one or two
23 | // HTTP proxies supporting the HTTP CONNECT method.
24 | //
25 |
26 | import java.net.*;
27 | import java.io.*;
28 |
29 | class HTTPConnectSocket extends Socket {
30 |
31 | public HTTPConnectSocket(String host, int port,
32 | String proxyHost, int proxyPort)
33 | throws IOException {
34 |
35 | // Connect to the specified HTTP proxy
36 | super(proxyHost, proxyPort);
37 |
38 | // Send the CONNECT request
39 | getOutputStream().write(("CONNECT " + host + ":" + port +
40 | " HTTP/1.0\r\n\r\n").getBytes());
41 |
42 | // Read the first line of the response
43 | DataInputStream is = new DataInputStream(getInputStream());
44 | String str = is.readLine();
45 |
46 | // Check the HTTP error code -- it should be "200" on success
47 | if (!str.startsWith("HTTP/1.0 200 ")) {
48 | if (str.startsWith("HTTP/1.0 "))
49 | str = str.substring(9);
50 | throw new IOException("Proxy reports \"" + str + "\"");
51 | }
52 |
53 | // Success -- skip remaining HTTP headers
54 | do {
55 | str = is.readLine();
56 | } while (str.length() != 0);
57 | }
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/contrib/vnc_javasrc/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: VncViewer
3 |
--------------------------------------------------------------------------------
/contrib/vnc_javasrc/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Making the VNC applet.
3 | #
4 |
5 | CP = cp
6 | JC = javac
7 | JCFLAGS = -target 1.1 -source 1.2
8 | JAR = jar
9 | ARCHIVE = VncViewer.jar
10 | MANIFEST = MANIFEST.MF
11 | PAGES = index.vnc
12 | INSTALL_DIR = /usr/local/vnc/classes
13 |
14 | CLASSES = VncViewer.class RfbProto.class AuthPanel.class VncCanvas.class \
15 | VncCanvas2.class \
16 | OptionsFrame.class ClipboardFrame.class ButtonPanel.class \
17 | DesCipher.class CapabilityInfo.class CapsContainer.class \
18 | RecordingFrame.class SessionRecorder.class \
19 | SocketFactory.class HTTPConnectSocketFactory.class \
20 | HTTPConnectSocket.class ReloginPanel.class \
21 | InStream.class MemInStream.class ZlibInStream.class
22 |
23 | SOURCES = VncViewer.java RfbProto.java AuthPanel.java VncCanvas.java \
24 | VncCanvas2.java \
25 | OptionsFrame.java ClipboardFrame.java ButtonPanel.java \
26 | DesCipher.java CapabilityInfo.java CapsContainer.java \
27 | RecordingFrame.java SessionRecorder.java \
28 | SocketFactory.java HTTPConnectSocketFactory.java \
29 | HTTPConnectSocket.java ReloginPanel.java \
30 | InStream.java MemInStream.java ZlibInStream.java
31 |
32 | all: $(CLASSES) $(ARCHIVE)
33 |
34 | $(CLASSES): $(SOURCES)
35 | $(JC) $(JCFLAGS) -O $(SOURCES)
36 |
37 | $(ARCHIVE): $(CLASSES) $(MANIFEST)
38 | $(JAR) cfm $(ARCHIVE) $(MANIFEST) $(CLASSES)
39 |
40 | install: $(CLASSES) $(ARCHIVE)
41 | $(CP) $(CLASSES) $(ARCHIVE) $(PAGES) $(INSTALL_DIR)
42 |
43 | export:: $(CLASSES) $(ARCHIVE) $(PAGES)
44 | @$(ExportJavaClasses)
45 |
46 | clean::
47 | $(RM) *.class *.jar
48 |
--------------------------------------------------------------------------------
/contrib/vnc_javasrc/MemInStream.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 | *
3 | * This is free software; you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation; either version 2 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This software is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this software; if not, write to the Free Software
15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 | * USA.
17 | */
18 |
19 | public class MemInStream extends InStream {
20 |
21 | public MemInStream(byte[] data, int offset, int len) {
22 | b = data;
23 | ptr = offset;
24 | end = offset + len;
25 | }
26 |
27 | public int pos() { return ptr; }
28 |
29 | protected int overrun(int itemSize, int nItems) throws Exception {
30 | throw new Exception("MemInStream overrun: end of stream");
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/contrib/vnc_javasrc/ReloginPanel.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (C) 2002 Cendio Systems. All Rights Reserved.
3 | // Copyright (C) 2002 Constantin Kaplinsky. All Rights Reserved.
4 | //
5 | // This is free software; you can redistribute it and/or modify
6 | // it under the terms of the GNU General Public License as published by
7 | // the Free Software Foundation; either version 2 of the License, or
8 | // (at your option) any later version.
9 | //
10 | // This software is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | // GNU General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU General Public License
16 | // along with this software; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18 | // USA.
19 | //
20 |
21 | //
22 | // ReloginPanel class implements panel with a button for logging in again,
23 | // after fatal errors or disconnect
24 | //
25 |
26 |
27 | import java.awt.*;
28 | import java.awt.event.*;
29 | import java.applet.*;
30 |
31 | //
32 | // The panel which implements the Relogin button
33 | //
34 |
35 | class ReloginPanel extends Panel implements ActionListener {
36 | Button reloginButton;
37 | Button closeButton;
38 | VncViewer viewer;
39 |
40 | //
41 | // Constructor.
42 | //
43 | public ReloginPanel(VncViewer v) {
44 | viewer = v;
45 | setLayout(new FlowLayout(FlowLayout.CENTER));
46 | reloginButton = new Button("Login again");
47 | add(reloginButton);
48 | reloginButton.addActionListener(this);
49 | if (viewer.inSeparateFrame) {
50 | closeButton = new Button("Close window");
51 | add(closeButton);
52 | closeButton.addActionListener(this);
53 | }
54 | }
55 |
56 | //
57 | // This method is called when a button is pressed.
58 | //
59 | public synchronized void actionPerformed(ActionEvent evt) {
60 | if (viewer.inSeparateFrame)
61 | viewer.vncFrame.dispose();
62 | if (evt.getSource() == reloginButton)
63 | viewer.getAppletContext().showDocument(viewer.getDocumentBase());
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/contrib/vnc_javasrc/SocketFactory.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (C) 2002 HorizonLive.com, Inc. All Rights Reserved.
3 | //
4 | // This is free software; you can redistribute it and/or modify
5 | // it under the terms of the GNU General Public License as published by
6 | // the Free Software Foundation; either version 2 of the License, or
7 | // (at your option) any later version.
8 | //
9 | // This software is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | // GNU General Public License for more details.
13 | //
14 | // You should have received a copy of the GNU General Public License
15 | // along with this software; if not, write to the Free Software
16 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 | // USA.
18 | //
19 |
20 | //
21 | // SocketFactory.java describes an interface used to substitute the
22 | // standard Socket class by its alternative implementations.
23 | //
24 |
25 | import java.applet.*;
26 | import java.net.*;
27 | import java.io.*;
28 |
29 | public interface SocketFactory {
30 |
31 | public Socket createSocket(String host, int port, Applet applet)
32 | throws IOException;
33 |
34 | public Socket createSocket(String host, int port, String[] args)
35 | throws IOException;
36 | }
37 |
--------------------------------------------------------------------------------
/contrib/vnc_javasrc/VncCanvas2.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (C) 2006 Constantin Kaplinsky. All Rights Reserved.
3 | //
4 | // This is free software; you can redistribute it and/or modify
5 | // it under the terms of the GNU General Public License as published by
6 | // the Free Software Foundation; either version 2 of the License, or
7 | // (at your option) any later version.
8 | //
9 | // This software is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | // GNU General Public License for more details.
13 | //
14 | // You should have received a copy of the GNU General Public License
15 | // along with this software; if not, write to the Free Software
16 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 | // USA.
18 | //
19 |
20 | import java.awt.*;
21 | import java.io.*;
22 |
23 | //
24 | // VncCanvas2 is a special version of VncCanvas which may use Java 2 API.
25 | //
26 |
27 | class VncCanvas2 extends VncCanvas {
28 |
29 | public VncCanvas2(VncViewer v) throws IOException {
30 | super(v);
31 | disableFocusTraversalKeys();
32 | }
33 |
34 | public VncCanvas2(VncViewer v, int maxWidth_, int maxHeight_)
35 | throws IOException {
36 |
37 | super(v, maxWidth_, maxHeight_);
38 | disableFocusTraversalKeys();
39 | }
40 |
41 | public void paintScaledFrameBuffer(Graphics g) {
42 | Graphics2D g2d = (Graphics2D)g;
43 | g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
44 | RenderingHints.VALUE_RENDER_QUALITY);
45 | g2d.drawImage(memImage, 0, 0, scaledWidth, scaledHeight, null);
46 | }
47 |
48 | //
49 | // Try to disable focus traversal keys (JVMs 1.4 and higher).
50 | //
51 |
52 | private void disableFocusTraversalKeys() {
53 | try {
54 | Class[] argClasses = { Boolean.TYPE };
55 | java.lang.reflect.Method method =
56 | getClass().getMethod("setFocusTraversalKeysEnabled", argClasses);
57 | Object[] argObjects = { new Boolean(false) };
58 | method.invoke(this, argObjects);
59 | } catch (Exception e) {}
60 | }
61 |
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/contrib/vnc_javasrc/index.html:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 | TightVNC desktop
22 |
23 |
25 |
26 |
27 |
28 | TightVNC site
29 |
30 |
--------------------------------------------------------------------------------
/contrib/vnc_javasrc/index.vnc:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 | $USER's $DESKTOP desktop ($DISPLAY)
17 |
18 |
20 |
21 | $PARAMS
22 |
23 |
24 | TightVNC site
25 |
26 |
--------------------------------------------------------------------------------
/docs/source/_static/images/applications.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/applications.png
--------------------------------------------------------------------------------
/docs/source/_static/images/audit-log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/audit-log.png
--------------------------------------------------------------------------------
/docs/source/_static/images/cluster_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/cluster_info.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ganetimgr_create_instance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ganetimgr_create_instance.png
--------------------------------------------------------------------------------
/docs/source/_static/images/graphs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/graphs.png
--------------------------------------------------------------------------------
/docs/source/_static/images/history.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/history.png
--------------------------------------------------------------------------------
/docs/source/_static/images/image00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/image00.png
--------------------------------------------------------------------------------
/docs/source/_static/images/image01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/image01.png
--------------------------------------------------------------------------------
/docs/source/_static/images/image02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/image02.png
--------------------------------------------------------------------------------
/docs/source/_static/images/image03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/image03.png
--------------------------------------------------------------------------------
/docs/source/_static/images/image04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/image04.png
--------------------------------------------------------------------------------
/docs/source/_static/images/instance-owners.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/instance-owners.png
--------------------------------------------------------------------------------
/docs/source/_static/images/instance_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/instance_details.png
--------------------------------------------------------------------------------
/docs/source/_static/images/jobs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/jobs.png
--------------------------------------------------------------------------------
/docs/source/_static/images/node_groups.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/node_groups.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_01_main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_01_main.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_02_user_main_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_02_user_main_view.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_03_user_statistics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_03_user_statistics.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_04_user_profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_04_user_profile.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_05_user_application.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_05_user_application.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_06_vm_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_06_vm_info.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_07_vm_graphs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_07_vm_graphs.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_08_vm_conf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_08_vm_conf.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_09_vm_actions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_09_vm_actions.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_10_admin_node.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_10_admin_node.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_11_admin_stats.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_11_admin_stats.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_12_admin_jobs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_12_admin_jobs.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_14_admin_application.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_14_admin_application.png
--------------------------------------------------------------------------------
/docs/source/_static/images/ss_15_admin_mail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/docs/source/_static/images/ss_15_admin_mail.png
--------------------------------------------------------------------------------
/docs/source/devel.rst:
--------------------------------------------------------------------------------
1 | *************************
2 | Development documentation
3 | *************************
4 |
5 | The following instructions are meant *only* for developers. Do NOT use them to setup a production ganetimgr service.
6 |
7 | python packages
8 | ###############
9 |
10 | A requirements.txt file is included in order to help you install the required python dependencies.
11 | You can do that by running::
12 |
13 | pip install -r requirements.txt
14 |
15 | How to update/test
16 | ##################
17 |
18 | We have created a fabric sript in order to set up and deploy ganetimgr. It is included under "contrib/fabric/". One can use it by running::
19 |
20 | fab deploy:tag='v1.6.0' -H ganetimgr.example.com -u user
21 |
22 | You will need to have fabric installed though.
23 |
24 | This scrip will connect to the specified server and try to set up ganetimgr under "/srv/ganetimgr" which will be a symlink to the actual directory.
25 |
26 | In general it performs the following steps:
27 |
28 | - stop redis, beanstalk, touch "/srv/maintenance.on"
29 | - git clone, git archive under "/tmp" and move to "/srv/ganetimgr"
30 | - check if there is an old installation under /srv/ganetimgr and get all the dist files in order to compare them with the newer version
31 | - create a buckup of the database
32 | - If no differences have been found between the two versions of ganetimgr, the old configuration files (whatever has also a dist file) will be copied to the new installation.
33 | - "/srv/ganetimgr" will be point to the new installation
34 | - management commands (migrate, collectstatic) will be run
35 | - fabric will ask your permission to remove old installations
36 | - restart nginx, gunicorn, redis, beanstalk, rm "maintenance.on"
37 | - in case something goes wrong it will try to make a rollback
38 | - in case no older installations exist or the dist files, it will ask you to log in the server and edit the settings, while waiting for your input.
39 |
--------------------------------------------------------------------------------
/docs/source/patches.rst:
--------------------------------------------------------------------------------
1 | ====================
2 | Ganeti Modifications
3 | ====================
4 |
5 | For the time being, ganetimgr requires using some patched ganeti packages to enable all ganetimgr's features. We are working on merging those changes upstream so that it works on vanilla software.
6 | The following software needs to be installed on the ganeti nodes/clusters.
7 |
8 | .. note::
9 | All patches that enabled special ganetimgr's features have been merged upstream since Ganeti 2.12. If you're using Ganeti 2.12 or newer you
10 | don't need a patched ganeti any more.
11 |
12 | Repository
13 | ----------
14 |
15 | We provide Debian packages for all the different software listed here. To get them you need to use our public repository.
16 |
17 | Add our repository to your sources.list::
18 |
19 | echo 'deb http://repo.noc.grnet.gr/ wheezy main backports' > /etc/apt/sources.list.d/grnet.list
20 |
21 | Add our gpg key to apt's keyring::
22 |
23 | wget -O - http://repo.noc.grnet.gr/grnet.gpg.key| apt-key add -
24 |
25 | And refresh the package list to discover the new packages::
26 |
27 | apt-get update
28 |
29 |
30 | ganeti-instance-image
31 | ---------------------
32 |
33 | This is a forked version of the [ganeti-instance-image](https://code.osuosl.org/projects/ganeti-image) OS provider written by UOSL::
34 |
35 | apt-get install ganeti-instance-image
36 |
37 |
38 | It uses the Ganeti OS API v20 to specify runtime osparams so we can specify the instance os during instance creation. It also injects the ssh key of the user inside the instance.
39 | The code from which the package is built can be found [here](https://github.com/grnet/ganeti-instance-image).
40 | You can find a sample Debian 7 Wheezy image [here](http://repo.noc.grnet.gr/debian-wheezy-x86_64.tgz)
41 |
42 |
43 | Ganeti
44 | ------
45 | .. note::
46 | This feature has been merged upstream since Ganeti version 2.12.
47 |
48 | If you want to use the ``boot from url`` feature of ganetimgr, you will need our ganeti package::
49 |
50 | apt-get install ganeti ganeti-htools
51 |
52 | Our package version has *+grnet* appended to the version string.
53 |
--------------------------------------------------------------------------------
/ganeti/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/ganeti/__init__.py
--------------------------------------------------------------------------------
/ganeti/admin.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.contrib import admin
19 | from models import Cluster, Network, InstanceAction
20 |
21 |
22 | def enable(modeladmin, request, queryset):
23 | queryset.update(disabled=False)
24 | enable.short_description = "Enable clusters"
25 |
26 |
27 | def disable(modeladmin, request, queryset):
28 | queryset.update(disabled=True)
29 |
30 | disable.short_description = "Disable clusters"
31 |
32 |
33 | class ClusterAdmin(admin.ModelAdmin):
34 | list_display = ('hostname', 'description', 'disabled')
35 | list_editable = ('disabled',)
36 | prepopulated_fields = {'slug': ('hostname',)}
37 | exclude = ('fast_create', 'use_gnt_network')
38 | actions = [enable, disable]
39 | search_fields = ('hostname', 'slug', 'description')
40 |
41 |
42 | class NetworkAdmin(admin.ModelAdmin):
43 | list_display = (
44 | 'description',
45 | 'cluster',
46 | 'cluster_default',
47 | 'mode',
48 | 'link'
49 | )
50 | list_filter = ('cluster',)
51 |
52 |
53 | class InstanceActionAdmin(admin.ModelAdmin):
54 | list_display = (
55 | 'instance',
56 | 'cluster',
57 | 'action',
58 | 'action_value',
59 | 'activation_key'
60 | )
61 | list_filter = ('instance',)
62 |
63 | admin.site.register(Cluster, ClusterAdmin)
64 | admin.site.register(Network, NetworkAdmin)
65 | admin.site.register(InstanceAction, InstanceActionAdmin)
66 |
67 |
--------------------------------------------------------------------------------
/ganeti/fixtures/flatpages.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "pk": 5,
4 | "model": "flatpages.flatpage",
5 | "fields": {
6 | "registration_required": true,
7 | "title": "Frequently Asked Questions",
8 | "url": "/about/faq/el/",
9 | "template_name": "flatpages/faq.html",
10 | "sites": [
11 | 1
12 | ],
13 | "content": "FAQ placeholder",
14 | "enable_comments": false
15 | }
16 | },
17 | {
18 | "pk": 6,
19 | "model": "flatpages.flatpage",
20 | "fields": {
21 | "registration_required": true,
22 | "title": "Frequently Asked Questions",
23 | "url": "/about/faq/en/",
24 | "template_name": "flatpages/faq.html",
25 | "sites": [
26 | 1
27 | ],
28 | "content": "FAQ placeholder",
29 | "enable_comments": false
30 | }
31 | },
32 | {
33 | "pk": 4,
34 | "model": "flatpages.flatpage",
35 | "fields": {
36 | "registration_required": false,
37 | "title": "Info Title placeholder",
38 | "url": "/about/info/el/",
39 | "template_name": "",
40 | "sites": [
41 | 1
42 | ],
43 | "content": "
ganetimgr info page
",
44 | "enable_comments": false
45 | }
46 | },
47 | {
48 | "pk": 3,
49 | "model": "flatpages.flatpage",
50 | "fields": {
51 | "registration_required": false,
52 | "title": "Info Title placeholder",
53 | "url": "/about/info/en/",
54 | "template_name": "",
55 | "sites": [
56 | 1
57 | ],
58 | "content": "
ganetimgr info page ",
59 | "enable_comments": false
60 | }
61 | },
62 | {
63 | "pk": 1,
64 | "model": "flatpages.flatpage",
65 | "fields": {
66 | "registration_required": false,
67 | "title": "ToS placeholer",
68 | "url": "/about/terms-of-service/el/",
69 | "template_name": "",
70 | "sites": [
71 | 1
72 | ],
73 | "content": "
ganetimgr ToS page ",
74 | "enable_comments": false
75 | }
76 | },
77 | {
78 | "pk": 2,
79 | "model": "flatpages.flatpage",
80 | "fields": {
81 | "registration_required": false,
82 | "title": "ToS placeholer",
83 | "url": "/about/terms-of-service/en/",
84 | "template_name": "",
85 | "sites": [
86 | 1
87 | ],
88 | "content": "
ganetimgr ToS page ",
89 | "enable_comments": false
90 | }
91 | }
92 | ]
--------------------------------------------------------------------------------
/ganeti/management/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/ganeti/management/__init__.py
--------------------------------------------------------------------------------
/ganeti/management/commands/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/ganeti/management/commands/__init__.py
--------------------------------------------------------------------------------
/ganeti/management/commands/refresh_cluster_instances.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import logging
3 | from django.core.management.base import BaseCommand
4 | from ganeti.models import Cluster
5 |
6 |
7 | logger = logging.getLogger('refresh_logger')
8 |
9 |
10 | class Command(BaseCommand):
11 | help = "Updates cache cluster instances for specific/all clusters"
12 |
13 | @staticmethod
14 | def add_arguments(parser):
15 | parser.add_argument("clusters", nargs="*")
16 | parser.add_argument("seconds", nargs="?", type=int)
17 |
18 | @staticmethod
19 | def fetch_clusters(cluster_hostnames=None):
20 | if not cluster_hostnames:
21 | return Cluster.objects.all()
22 | return Cluster.objects.filter(hostname__in=cluster_hostnames)
23 |
24 | @staticmethod
25 | def refresh(cluster, seconds):
26 | if seconds:
27 | cluster.refresh_instances(seconds=seconds)
28 | cluster.refresh_nodes(seconds=seconds)
29 | else:
30 | cluster.refresh_instances()
31 | cluster.refresh_nodes()
32 |
33 | def handle(self, *args, **options):
34 | exit_code = 0
35 | for cluster in self.fetch_clusters(options.get("clusters")):
36 | print("Refreshing cache for cluster: {0}".format(cluster))
37 | try:
38 | self.refresh(cluster, options.get("seconds"))
39 | except Exception as err:
40 | logger.info("Error while refreshing cache for cluster {0}: {1}"
41 | .format(cluster, err))
42 | exit_code = 1
43 |
44 | sys.exit(exit_code)
45 |
--------------------------------------------------------------------------------
/ganeti/migrations/0002_custompermission.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models, migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('ganeti', '0001_initial'),
11 | ]
12 |
13 | operations = [
14 | migrations.CreateModel(
15 | name='CustomPermission',
16 | fields=[
17 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
18 | ],
19 | options={
20 | 'managed': False,
21 | 'permissions': (('view_all_graphs', 'Can view all graphs'),),
22 | },
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/ganeti/migrations/0003_auto_20170807_1459.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models, migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('ganeti', '0002_custompermission'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterModelOptions(
15 | name='custompermission',
16 | options={'managed': False, 'permissions': (('view_all_graphs', 'Can view all graphs'), ('can_isolate', 'Can Isolate'), ('can_lock', 'Can Lock'))},
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/ganeti/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/ganeti/migrations/__init__.py
--------------------------------------------------------------------------------
/ganeti/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/ganeti/templatetags/__init__.py
--------------------------------------------------------------------------------
/ganeti/templatetags/applicationstatus.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django import template
19 |
20 | register = template.Library()
21 |
22 |
23 | @register.filter
24 | def appstatus(value):
25 | if value == "pending":
26 | return "info"
27 | if value == "approved":
28 | return "success"
29 | if value == "failed":
30 | return "important"
31 | if value == "refused":
32 | return "warning"
33 | return "info"
34 |
--------------------------------------------------------------------------------
/ganeti/templatetags/bootstrappercent.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django import template
19 |
20 | register = template.Library()
21 |
22 |
23 | @register.filter
24 | def perctobootstrap(value):
25 | if value < 50:
26 | return "success"
27 | if value >= 50 and value < 80:
28 | return "warning"
29 | if value >= 80:
30 | return "danger"
31 |
32 |
33 | @register.filter
34 | def perctobootstrapbadge(value):
35 | if value < 50:
36 | return "success"
37 | if value >= 50 and value < 80:
38 | return "warning"
39 | if value >= 80:
40 | return "important"
41 |
--------------------------------------------------------------------------------
/ganeti/templatetags/days_since.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django import template
19 | register = template.Library()
20 |
21 | import datetime
22 |
23 | @register.filter(name='days_since')
24 | def days_since(value):
25 | since = 0
26 | try:
27 | since = (datetime.datetime.now() - value).days
28 | except:
29 | pass
30 | return since
--------------------------------------------------------------------------------
/ganeti/templatetags/disksizes.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django import template
19 | from django.template.defaultfilters import filesizeformat
20 |
21 | register = template.Library()
22 |
23 | @register.filter
24 | def disksizes(value):
25 | return [filesizeformat(v * 1024**2) for v in value]
26 |
27 | @register.filter
28 | def memsize(value):
29 | return filesizeformat(value * 1024**2)
30 |
--------------------------------------------------------------------------------
/ganeti/templatetags/noderole.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django import template
19 |
20 | register = template.Library()
21 |
22 | @register.filter
23 | def noderole(value):
24 | if value == "M":
25 | return "Master"
26 | if value == "C":
27 | return "Candidate"
28 | if value == "R":
29 | return "Regular"
30 | if value == "D":
31 | return "Drained"
32 | if value == "O":
33 | return "Offline"
34 |
35 | @register.filter
36 | def nodelabel(value):
37 | if value == "M":
38 | return "success"
39 | if value == "C":
40 | return "info"
41 | if value == "R":
42 | return ""
43 | if value == "D":
44 | return "warning"
45 | if value == "O":
46 | return "important"
47 |
--------------------------------------------------------------------------------
/ganeti/templatetags/truncatedchars.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django import template
19 |
20 | register = template.Library()
21 |
22 | @register.filter
23 | # truncate after a certain number of characters
24 | def truncchar(value, arg):
25 | if len(value) < arg:
26 | return value
27 | else:
28 | return value[:arg] + '...'
29 |
--------------------------------------------------------------------------------
/ganeti/urls/__init__.py:
--------------------------------------------------------------------------------
1 | # proxy
2 | from graphs import *
3 | from instances import *
4 | from jobs import *
5 | from nodegroup import *
6 | from clusters import *
7 |
--------------------------------------------------------------------------------
/ganeti/urls/clusters.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf.urls import url
19 | from ganeti import views
20 |
21 | urlpatterns = [
22 | # this view lives in jobs.py
23 | url(r'^jobdetails/?$', views.job_details, name="jobdets-popup"),
24 | url(r'^popup/?', views.instance_popup, name="instance-popup"),
25 | url(r'^nodes/$', views.get_clusternodes, name="cluster-nodes"),
26 | url(r'^nodes/pjax/$', views.get_clusternodes_pjax, name="cluster-nodes-pjax"),
27 | url(r'^jnodes/(?P[0-9]+)/$', views.clusternodes_json, name="cluster-nodes-json"),
28 | url(r'^jnodes/$', views.clusternodes_json, name="cluster-nodes-json"),
29 | url(r'^instance/destreinst/(?P\w+)/(?P\d+)/$', views.reinstalldestreview, name='reinstall-destroy-review'),
30 | url(r'^detail/$', views.clusterdetails, name="clusterdetails"),
31 | url(r'^detail/json/$', views.clusterdetails_json, name="clusterdetails_json"),
32 |
33 | ]
34 |
--------------------------------------------------------------------------------
/ganeti/urls/graphs.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf.urls import url
19 | from ganeti import views
20 |
21 | urlpatterns = [
22 | url(r'^(?P[^/]+)/(?P[^/]+)/(?P[^/]+)(/(?P[\\:\w\d\s\.+-]+),(?P[\\:\w\d\s\.+-]+))?(/(?Peth\d+))?$', views.graph, name='graph'),
23 | url(r'^all/$', views.cluster_nodes_graphs, name="cluster-get-nodes-graphs"),
24 | url(r'^(?P[^/]+)/instances/$', views.cluster_nodes_graphs, name="cluster-get-nodes-graphs"),
25 | ]
26 |
--------------------------------------------------------------------------------
/ganeti/urls/instances.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf.urls import url
19 |
20 | from ganeti import views
21 |
22 | urlpatterns = [
23 | url(r'^list/$', views.list_user_instances, name='instances-list'),
24 | url(r'^tags/(?P[^/]+)?$', views.tagInstance, name="instance-tags"),
25 | url(r'^json/$', views.user_index_json, name="user-instances-json"),
26 | url(r'^stats/json/$', views.user_sum_stats, name="user-stats-json"),
27 | url(r'^lock/(?P[^/]+)?$', views.lock, name="lock"),
28 | url(r'^isolate/(?P[^/]+)?$', views.isolate, name="isolate"),
29 | url(r'^(?P[^/]+)/(?P[^/]+)/poll/?$', views.poll, name="instance-poll"),
30 | url(r'^(?P[^/]+)/(?P[^/]+)/vnc/?$', views.vnc, name="instance-vnc"),
31 | url(r'^(?P[^/]+)/(?P[^/]+)/novnc/?$', views.novnc, name="instance-novnc"),
32 | url(r'^(?P[^/]+)/(?P[^/]+)/novnc-proxy/?$', views.novnc_proxy, name="instance-novnc-proxy"),
33 | url(r'^(?P[^/]+)/(?P[^/]+)/shutdown/?$', views.shutdown, name="instance-shutdown"),
34 | url(r'^(?P[^/]+)/(?P[^/]+)/startup/?$', views.startup, name="instance-startup"),
35 | url(r'^(?P[^/]+)/(?P[^/]+)/reboot/?$', views.reboot, name="instance-reboot"),
36 | url(r'^(?P[^/]+)/(?P[^/]+)/reinstalldestroy/?$', views.destroy, name="instance-destroy"),
37 | url(r'^(?P[^/]+)/(?P[^/]+)/reinstall/?$', views.reinstall, name="instance-reinstall"),
38 | url(r'^(?P[^/]+)/(?P[^/]+)/rename/?$', views.rename_instance, name="instance-rename"),
39 | url(r'^(?P[^/]+)/(?P[^/]+)/?', views.instance, name="instance-detail"),
40 | ]
41 |
--------------------------------------------------------------------------------
/ganeti/urls/jobs.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf.urls import url
19 | from ganeti import views
20 |
21 | urlpatterns = [
22 | url(r'^json/$', views.jobs_index_json, name="jobs_json"),
23 | url(r'^$', views.jobs, name="jobs"),
24 | ]
25 |
--------------------------------------------------------------------------------
/ganeti/urls/nodegroup.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf.urls import url
19 | from ganeti import views
20 |
21 | urlpatterns = [
22 | url(r'^fromnet/$', views.get_nodegroups_fromnet, name='ng_from_net'),
23 | url(r'^cluster/$', views.get_cluster_node_group_stack, name='cluster_ng_stack'),
24 |
25 | ]
26 |
--------------------------------------------------------------------------------
/ganeti/views/discovery.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 | from ganeti.decorators import ajax_required
18 | from django.http import HttpResponse
19 | from ganeti.utils import operating_systems
20 |
21 |
22 | @ajax_required
23 | def get_operating_systems(request):
24 | return HttpResponse(operating_systems())
25 |
26 |
--------------------------------------------------------------------------------
/ganeti/views/nodegroup.py:
--------------------------------------------------------------------------------
1 | import json
2 | from django.http import HttpResponse, HttpResponseBadRequest, Http404
3 | from django.contrib.auth.decorators import permission_required
4 | from django.contrib import messages
5 | from django.shortcuts import get_object_or_404
6 | from ganeti.models import Network, Cluster
7 | from ganeti.utils import prepare_cluster_node_group_stack, format_ganeti_api_error
8 | from util.client import GanetiApiError
9 |
10 |
11 | @permission_required("apply.change_instanceapplication")
12 | def get_nodegroups_fromnet(request):
13 | network_id = request.GET.get('network_id')
14 | if network_id:
15 | try:
16 | cluster = Network.objects.get(pk=network_id).cluster
17 | except Network.DoesNotExist:
18 | raise Http404
19 | else:
20 | return HttpResponseBadRequest()
21 | nodegroups = cluster.get_node_groups()
22 | nodegroups_list = []
23 | for g in nodegroups:
24 | nodeg_dict = {}
25 | nodeg_dict['name'] = g['name']
26 | nodegroups_list.append(nodeg_dict)
27 | return HttpResponse(json.dumps(nodegroups_list), content_type='application/json')
28 |
29 |
30 | @permission_required("apply.change_instanceapplication")
31 | def get_cluster_node_group_stack(request):
32 | res = ''
33 | error = None
34 | cluster_id = request.GET.get('cluster_id', None)
35 | if cluster_id:
36 | cluster = get_object_or_404(Cluster, pk=cluster_id)
37 | else:
38 | return HttpResponseBadRequest()
39 |
40 | try:
41 | res = prepare_cluster_node_group_stack(cluster)
42 | except GanetiApiError as e:
43 | error = format_ganeti_api_error(e)
44 | except Exception as e:
45 | error = e
46 | if error:
47 | messages.add_message(request, messages.ERROR, error)
48 | return HttpResponse(json.dumps(res), content_type='application/json')
49 |
--------------------------------------------------------------------------------
/ganetimgr/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/ganetimgr/__init__.py
--------------------------------------------------------------------------------
/ganetimgr/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for ganetimgrw project.
3 |
4 | This module contains the WSGI application used by Django's development server
5 | and any production WSGI deployments. It should expose a module-level variable
6 | named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
7 | this application via the ``WSGI_APPLICATION`` setting.
8 |
9 | Usually you will have the standard Django WSGI application here, but it also
10 | might make sense to replace the whole Django WSGI application with a custom one
11 | that later delegates to the Django one. For example, you could introduce WSGI
12 | middleware here, or combine a Django application with an application of another
13 | framework.
14 |
15 | """
16 | import os
17 |
18 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ganetimgr.settings")
19 |
20 | # This application object is used by any WSGI server configured to use this
21 | # file. This includes Django's development server, if the WSGI_APPLICATION
22 | # setting points here.
23 | from django.core.wsgi import get_wsgi_application
24 | application = get_wsgi_application()
25 |
26 | # Apply WSGI middleware here.
27 | # from helloworld.wsgi import HelloWorldApplication
28 | # application = HelloWorldApplication(application)
29 |
--------------------------------------------------------------------------------
/locale/el/LC_MESSAGES/django.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/locale/el/LC_MESSAGES/django.mo
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
3 | # Copyright (C) 2010-2014 GRNET S.A.
4 | #
5 | # This program is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # This program is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with this program. If not, see .
17 | #
18 |
19 | import os
20 | import sys
21 |
22 | if __name__ == "__main__":
23 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ganetimgr.settings")
24 |
25 | from gevent import monkey
26 | monkey.patch_all()
27 | from django.core.management import execute_from_command_line
28 |
29 | execute_from_command_line(sys.argv)
30 |
--------------------------------------------------------------------------------
/middleware/ForceLogout.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.contrib.auth import logout
19 |
20 |
21 | class ForceLogoutMiddleware(object):
22 | def process_request(self, request):
23 | if (
24 | request.user.is_authenticated() and
25 | request.user.userprofile.force_logout_date and
26 | (
27 | 'LAST_LOGIN_DATE' not in request.session or
28 | request.session['LAST_LOGIN_DATE'] < request.user.userprofile.force_logout_date
29 | )
30 | ):
31 | logout(request)
32 |
--------------------------------------------------------------------------------
/middleware/UserMessages.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.contrib import messages
19 | from django.utils.translation import ugettext as _
20 | from django.core.urlresolvers import reverse
21 | from django.utils.safestring import mark_safe
22 | from django.core.exceptions import ObjectDoesNotExist
23 |
24 | from accounts.models import UserProfile
25 |
26 |
27 | class UserMessageMiddleware(object):
28 | """
29 | Middleware to display various messages to the users.
30 | """
31 |
32 | def process_request(self, request):
33 | if not hasattr(request, "session"):
34 | return
35 |
36 | if request.user.is_authenticated():
37 | try:
38 | first_login = request.session["first_login"]
39 | except KeyError:
40 | try:
41 | profile = request.user.userprofile
42 | except ObjectDoesNotExist:
43 | profile = UserProfile.objects.create(user=request.user)
44 | first_login = profile.first_login
45 | request.session["first_login"] = first_login
46 |
47 | if first_login:
48 | messages.add_message(
49 | request,
50 | messages.INFO,
51 | mark_safe(
52 | _(
53 | "Welcome! Please take some time to"
54 | " update your profile "
55 | " and upload your SSH keys."
56 | ) % reverse("profile")
57 | )
58 | )
59 | profile = request.user.userprofile
60 | profile.first_login = False
61 | profile.save()
62 | request.session["first_login"] = False
63 |
--------------------------------------------------------------------------------
/middleware/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/middleware/__init__.py
--------------------------------------------------------------------------------
/notifications/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/notifications/__init__.py
--------------------------------------------------------------------------------
/notifications/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from notifications.models import NotificationArchive
3 |
4 |
5 | class NotificationArchiveAdmin(admin.ModelAdmin):
6 | list_display = ('subject', 'sender', 'date', )
7 |
8 | admin.site.register(NotificationArchive, NotificationArchiveAdmin)
9 |
--------------------------------------------------------------------------------
/notifications/forms.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 | from django import forms
18 | from django.utils.translation import ugettext_lazy
19 | from django.contrib.auth.models import User
20 | from notifications.models import NotificationArchive
21 | from notifications.utils import get_mails
22 |
23 |
24 | TYPE_CHOICES = (
25 | ('cluster', 'clusters'),
26 | ('nodes', 'nodes'),
27 | ('nodegroups', 'nodegroups'),
28 | ('users', 'users'),
29 | ('groups', 'groups'),
30 | ('instances', 'instances')
31 | )
32 |
33 |
34 | class MessageForm(forms.Form):
35 | search_for = forms.ChoiceField(
36 | label=ugettext_lazy("Search for"),
37 | choices=TYPE_CHOICES
38 | )
39 | subject = forms.CharField(max_length=100, label=ugettext_lazy("Subject"))
40 | message = forms.CharField(
41 | widget=forms.Textarea,
42 | label=ugettext_lazy("Body"),
43 | help_text='You can use {% for i in instances %} {{ i }} {% endfor %} if you want to use the body as a mail template.'
44 | )
45 | recipient_list = forms.CharField(label=ugettext_lazy("Recipients"))
46 |
47 | def add_to_archive(self, user):
48 | if self.is_valid():
49 | notification = NotificationArchive(
50 | subject=self.cleaned_data['subject'],
51 | message=self.cleaned_data['message'],
52 | sender=user
53 | )
54 | notification.save()
55 | mail_list = get_mails(self.cleaned_data['recipient_list'].split(','))
56 | for user in User.objects.filter(email__in=mail_list):
57 | notification.recipients.add(user)
58 | notification.save()
59 |
--------------------------------------------------------------------------------
/notifications/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models, migrations
5 | from django.conf import settings
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12 | ]
13 |
14 | operations = [
15 | migrations.CreateModel(
16 | name='NotificationArchive',
17 | fields=[
18 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
19 | ('subject', models.CharField(max_length=255)),
20 | ('message', models.TextField()),
21 | ('date', models.DateTimeField(auto_now_add=True)),
22 | ('recipients', models.ManyToManyField(related_name='notifications', to=settings.AUTH_USER_MODEL)),
23 | ('sender', models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True)),
24 | ],
25 | options={
26 | 'ordering': ['-date'],
27 | 'permissions': (('can_view_notif', 'Can view all notifications'),),
28 | },
29 | ),
30 | ]
31 |
--------------------------------------------------------------------------------
/notifications/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/notifications/migrations/__init__.py
--------------------------------------------------------------------------------
/notifications/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.contrib.auth.models import User
3 | from django.core.urlresolvers import reverse
4 |
5 |
6 | class NotificationArchive(models.Model):
7 | recipients = models.ManyToManyField(User, related_name='notifications')
8 | subject = models.CharField(max_length=255)
9 | message = models.TextField()
10 | date = models.DateTimeField(auto_now_add=True)
11 | sender = models.ForeignKey(User, blank=True, null=True)
12 |
13 | def __unicode__(self):
14 | return self.subject
15 |
16 | def get_absolute_url(self):
17 | return reverse('notification-details', kwargs={'notification': self.pk})
18 |
19 | class Meta():
20 | ordering = ['-date']
21 | permissions = (
22 | ("can_view_notif", "Can view all notifications"),
23 | )
24 |
--------------------------------------------------------------------------------
/notifications/urls.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf.urls import url
19 | from notifications import views
20 |
21 | urlpatterns = [
22 | url(r'^usergrps/$', views.get_user_group_list, name="usergroups"),
23 | url(r'^(?P[^/]+)/$', views.notify, name="notify"),
24 | url(r'^archive/(?P\w+)/$', views.archive, name="notification-details"),
25 | url(r'^$', views.notify, name="notify"),
26 | ]
27 |
--------------------------------------------------------------------------------
/readthedocs-requirements.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | ## dependencies for the ganetimgr project
2 | django==1.11
3 | # we target the latest LTS release
4 | gevent==1.1.2
5 | # gevent is used to pool cluster RAPI communication
6 | django-registration-redux==2.4
7 | # used for our registration workflow
8 | paramiko==2.0.0
9 | # used for user SSH key management
10 | python-daemon==2.1.2
11 | # used by watcher
12 | setproctitle==1.1.10
13 | # used by watcher to set it's process name
14 | pycurl==7.43.0
15 | # depenency for ganeti client library
16 | django-nocaptcha-recaptcha==0.0.20
17 | # used in the registration form
18 | ipaddr==2.1.11
19 | # used to calculate Instance ipv6addresses
20 | beautifulsoup4==4.5.3
21 | # used by the image autodiscovery mechanism
22 | requests==2.12.4
23 | # used by the image autodiscovery mechanism
24 | beanstalkc==0.4.0
25 | # used to pass messages between watcher and django
26 | django-redis-cache==1.7.1
27 | # used to cache cluster nodes/instances info
28 | pyyaml==3.12
29 | # used by beanstalkc
30 | django-jsonfield==1.0.1
31 |
--------------------------------------------------------------------------------
/static/branding/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/branding/logo.png
--------------------------------------------------------------------------------
/static/branding/logo.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/branding/logo.xcf
--------------------------------------------------------------------------------
/static/flatpagesassets/ownership.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/flatpagesassets/ownership.png
--------------------------------------------------------------------------------
/static/flatpagesassets/ownership_dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/flatpagesassets/ownership_dropdown.png
--------------------------------------------------------------------------------
/static/flatpagesassets/user_screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/flatpagesassets/user_screen.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/includes/feedek.css:
--------------------------------------------------------------------------------
1 | .feedEkList {
2 | /*width: 450px;*/
3 | list-style: none outside none;
4 | background-color: #FFFFFF;
5 | /*border: 1px solid #D3CAD7;*/
6 | /*padding: 4px 6px;*/
7 | color: #3E3E3E;
8 | }
9 |
10 | .feedEkList li {
11 | border-bottom: 1px solid #D3CAD7;
12 | padding: 5px;
13 | }
14 |
15 | .feedEkList li:last-child {
16 | border-bottom: none;
17 | }
18 |
19 | /*.itemTitle a {
20 | font-weight: bold;
21 | color: #4EBAFF !important;
22 | text-decoration: none
23 | }*/
24 |
25 | /*.itemTitle a:hover {
26 | text-decoration: underline
27 | }*/
28 |
29 | .itemDate {
30 | font-size: 11px;
31 | color: #AAAAAA;
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/static/ganetimgr/css/includes/img-on-top.css:
--------------------------------------------------------------------------------
1 | .imgstack-container{
2 |
3 | /* relative positioning to match parent */
4 | position:relative;
5 | }
6 |
7 | .imgstack-container > a {
8 |
9 | /* make appear clickable */
10 | cursor:pointer;
11 | }
12 |
13 | .imgstack-container > a > img {
14 |
15 | /* Center image on container, make it responsive */
16 | left:50%;
17 | top:50%;
18 | --webkit-transform:translate(-50%,-50%);
19 | --ms-transform:translate(-50%,-50%);
20 | transform:translate(-50%,-50%);
21 |
22 | /* absolute positioning to stack it on top
23 | of other image */
24 | position:absolute;
25 |
26 | /* z-index is greater than the background element's */
27 | z-index:99;
28 | }
29 |
30 | .imgstack-container img {
31 |
32 | /* relative positioning to match parent */
33 | position:relative;
34 |
35 | /* z-index less than the element that will go on top */
36 | z-index:90;
37 | }
--------------------------------------------------------------------------------
/static/ganetimgr/css/includes/nprogress.css:
--------------------------------------------------------------------------------
1 | /* Make clicks pass-through */
2 | #nprogress {
3 | pointer-events: none;
4 | }
5 |
6 | #nprogress .bar {
7 | background: #29d;
8 |
9 | position: fixed;
10 | z-index: 1031;
11 | top: 0;
12 | left: 0;
13 |
14 | width: 100%;
15 | height: 2px;
16 | }
17 |
18 | /* Fancy blur effect */
19 | #nprogress .peg {
20 | display: block;
21 | position: absolute;
22 | right: 0px;
23 | width: 100px;
24 | height: 100%;
25 | box-shadow: 0 0 10px #29d, 0 0 5px #29d;
26 | opacity: 1.0;
27 |
28 | -webkit-transform: rotate(3deg) translate(0px, -4px);
29 | -ms-transform: rotate(3deg) translate(0px, -4px);
30 | transform: rotate(3deg) translate(0px, -4px);
31 | }
32 |
33 | /* Remove these to get rid of the spinner */
34 | #nprogress .spinner {
35 | display: block;
36 | position: fixed;
37 | z-index: 1031;
38 | top: 15px;
39 | right: 15px;
40 | }
41 |
42 | #nprogress .spinner-icon {
43 | width: 18px;
44 | height: 18px;
45 | box-sizing: border-box;
46 |
47 | border: solid 2px transparent;
48 | border-top-color: #29d;
49 | border-left-color: #29d;
50 | border-radius: 50%;
51 |
52 | -webkit-animation: nprogress-spinner 400ms linear infinite;
53 | animation: nprogress-spinner 400ms linear infinite;
54 | }
55 |
56 | .nprogress-custom-parent {
57 | overflow: hidden;
58 | position: relative;
59 | }
60 |
61 | .nprogress-custom-parent #nprogress .spinner,
62 | .nprogress-custom-parent #nprogress .bar {
63 | position: absolute;
64 | }
65 |
66 | @-webkit-keyframes nprogress-spinner {
67 | 0% { -webkit-transform: rotate(0deg); }
68 | 100% { -webkit-transform: rotate(360deg); }
69 | }
70 | @keyframes nprogress-spinner {
71 | 0% { transform: rotate(0deg); }
72 | 100% { transform: rotate(360deg); }
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/static/ganetimgr/css/includes/resp-modal.css:
--------------------------------------------------------------------------------
1 |
2 | .video-container {
3 | position: relative;
4 | padding-bottom: 56.25%;
5 | padding-top: 35px;
6 | height: 0;
7 | overflow: hidden;
8 | }
9 | .video-container iframe {
10 | position: absolute;
11 | top:0;
12 | left: 0;
13 | width: 100%;
14 | height: 100%;
15 | }
16 |
17 | .resp-modal {
18 | width:60%;
19 | margin-left:-21%;
20 | left:41%;
21 | }
--------------------------------------------------------------------------------
/static/ganetimgr/css/includes/select2-spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/includes/select2-spinner.gif
--------------------------------------------------------------------------------
/static/ganetimgr/css/includes/select2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/includes/select2.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/includes/select2x2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/includes/select2x2.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-icons_2e83ff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-icons_2e83ff_256x240.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-icons_454545_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-icons_454545_256x240.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-icons_888888_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-icons_888888_256x240.png
--------------------------------------------------------------------------------
/static/ganetimgr/css/smoothness/images/ui-icons_cd0a0a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/css/smoothness/images/ui-icons_cd0a0a_256x240.png
--------------------------------------------------------------------------------
/static/ganetimgr/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/static/ganetimgr/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/static/ganetimgr/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/static/ganetimgr/img/background_grnet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/img/background_grnet.png
--------------------------------------------------------------------------------
/static/ganetimgr/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/img/favicon.ico
--------------------------------------------------------------------------------
/static/ganetimgr/img/gifs/ajax-loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/img/gifs/ajax-loader.gif
--------------------------------------------------------------------------------
/static/ganetimgr/img/learnmore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/img/learnmore.png
--------------------------------------------------------------------------------
/static/ganetimgr/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/img/logo.png
--------------------------------------------------------------------------------
/static/ganetimgr/img/nodata.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/img/nodata.jpg
--------------------------------------------------------------------------------
/static/ganetimgr/img/rule.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/img/rule.png
--------------------------------------------------------------------------------
/static/ganetimgr/img/sprites/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/img/sprites/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/static/ganetimgr/img/sprites/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/img/sprites/glyphicons-halflings.png
--------------------------------------------------------------------------------
/static/ganetimgr/img/video-crop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/ganetimgr/img/video-crop.png
--------------------------------------------------------------------------------
/static/ganetimgr/js/includes/feedek.js:
--------------------------------------------------------------------------------
1 | /*
2 | * FeedEk jQuery RSS/ATOM Feed Plugin v3.0 with YQL API
3 | * http://jquery-plugins.net/FeedEk/FeedEk.html https://github.com/enginkizil/FeedEk
4 | * Author : Engin KIZIL http://www.enginkizil.com
5 | */
6 |
7 | !function (a) { a.fn.FeedEk = function (b) { var g, c = a.extend({ MaxCount: 5, ShowDesc: !0, ShowPubDate: !0, DescCharacterLimit: 0, TitleLinkTarget: "_blank", DateFormat: "", DateFormatLang: "en" }, b), d = a(this).attr("id"), f = ""; if (a("#" + d).empty(), void 0 != c.FeedUrl) { a("#" + d).append(' '); var h = 'SELECT channel.item FROM feednormalizer WHERE output="rss_2.0" AND url ="' + c.FeedUrl + '" LIMIT ' + c.MaxCount; a.ajax({ url: "https://query.yahooapis.com/v1/public/yql?q=" + encodeURIComponent(h) + "&format=json&diagnostics=false&callback=?", dataType: "json", success: function (b) { a("#" + d).empty(), b.query.results.rss instanceof Array || (b.query.results.rss = [b.query.results.rss]), a.each(b.query.results.rss, function (b, d) { if (f += '", c.ShowPubDate) { if (g = new Date(d.channel.item.pubDate), f += '', a.trim(c.DateFormat).length > 0) try { moment.lang(c.DateFormatLang), f += moment(g).format(c.DateFormat) } catch (b) { f += g.toLocaleDateString() } else f += g.toLocaleDateString(); f += "
" } c.ShowDesc && (f += '', f += c.DescCharacterLimit > 0 && d.channel.item.description.length > c.DescCharacterLimit ? d.channel.item.description.substring(0, c.DescCharacterLimit) + "..." : d.channel.item.description, f += "
") }), a("#" + d).append('") } }) } } }(jQuery);
8 |
--------------------------------------------------------------------------------
/static/ganetimgr/js/includes/jquery.cookie.js:
--------------------------------------------------------------------------------
1 | function createCookie(name,value,days) {
2 | if (days) {
3 | var date = new Date();
4 | date.setTime(date.getTime()+(days*24*60*60*1000));
5 | var expires = "; expires="+date.toGMTString();
6 | }
7 | else var expires = "";
8 | document.cookie = name+"="+value+expires+"; path=/";
9 | }
10 |
11 | function readCookie(name) {
12 | var nameEQ = name + "=";
13 | var ca = document.cookie.split(';');
14 | for(var i=0;i < ca.length;i++) {
15 | var c = ca[i];
16 | while (c.charAt(0)==' ') c = c.substring(1,c.length);
17 | if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
18 | }
19 | return null;
20 | }
21 |
22 | function eraseCookie(name) {
23 | createCookie(name,"",-1);
24 | }
--------------------------------------------------------------------------------
/static/ganetimgr/js/jquery_csrf_protect.js:
--------------------------------------------------------------------------------
1 | $(document).ajaxSend(function(event, xhr, settings) {
2 | var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
3 |
4 | function csrfSafeMethod(method) {
5 | // these HTTP methods do not require CSRF protection
6 | return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
7 | }
8 |
9 | if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
10 | xhr.setRequestHeader("X-CSRFToken", csrftoken);
11 | }
12 | });
13 |
--------------------------------------------------------------------------------
/static/ganetimgr/js/messages.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 |
3 | var content = $('.content');
4 | var message_container = $('#jsonmessages');
5 | var messages_url = message_container.data('messages');
6 | var last = '';
7 | NProgress.configure({ showSpinner: false });
8 |
9 | $.add_message = function(text, css) {
10 | if (last !== text) {
11 | var css_class = 'alert-';
12 | if (css != undefined) {
13 | css_class += css;
14 | } else {
15 | css_class += 'warning';
16 | }
17 | var message_div = message_container.find('.message-template').clone();
18 | message_div.removeClass('message-template');
19 | message_div.find('span').text(text);
20 | message_div.addClass(css_class);
21 | message_container.append(message_div);
22 | message_container.show();
23 | last = text;
24 | }
25 | }
26 |
27 | $(document).ajaxError(function(event, request, settings) {
28 | // in case of ajax Error
29 | if (request.status === 500) {
30 | $.add_message('An error occured with your request');
31 | }
32 | });
33 |
34 | $(document).ajaxComplete(function(event, xhr, settings) {
35 | // in case an ajax request is completed
36 | if (xhr.readyState < 4) {
37 | xhr.abort();
38 | } else {
39 | NProgress.done();
40 | }
41 | });
42 |
43 | $(document).ajaxSend(function() {
44 | // in case an ajax request is sent
45 | // This does NOT work with jquery datatables.
46 | NProgress.start();
47 | });
48 |
49 | $( document ).ajaxSuccess(function(event, xhr, settings) {
50 | if (settings.url != messages_url) {
51 | $.get( messages_url, function(data) {
52 | if (data.logout === false) {
53 | for (var i=0; i < data.messages.length; i++) {
54 | $.add_message(data.messages[i].message, data.messages[i].css);
55 | }
56 | } else {
57 | $.add_message('Logging out...', 'info');
58 | setTimeout(
59 | function(){
60 | location.reload();
61 | },
62 | 3000
63 | );
64 | }
65 | });
66 | }
67 | });
68 | });
69 |
--------------------------------------------------------------------------------
/static/javavnc/VncViewer.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/javavnc/VncViewer.jar
--------------------------------------------------------------------------------
/static/noVNC/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "include/web-socket-js-project"]
2 | path = include/web-socket-js-project
3 | url = https://github.com/gimite/web-socket-js.git
4 |
--------------------------------------------------------------------------------
/static/noVNC/docs/LICENSE.BSD-2-Clause:
--------------------------------------------------------------------------------
1 | Copyright (c) ,
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright
10 | notice, this list of conditions and the following disclaimer in the
11 | documentation and/or other materials provided with the distribution.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
17 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 |
--------------------------------------------------------------------------------
/static/noVNC/docs/LICENSE.BSD-3-Clause:
--------------------------------------------------------------------------------
1 | Copyright (c) ,
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | * Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | * Neither the name of the nor the
12 | names of its contributors may be used to endorse or promote products
13 | derived from this software without specific prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 |
--------------------------------------------------------------------------------
/static/noVNC/docs/LICENSE.zlib:
--------------------------------------------------------------------------------
1 | Copyright (c) ,
2 | All rights reserved.
3 |
4 | This software is provided 'as-is', without any express
5 | or implied warranty. In no event will the authors be
6 | held liable for any damages arising from the use of
7 | this software.
8 |
9 | Permission is granted to anyone to use this software
10 | for any purpose, including commercial applications,
11 | and to alter it and redistribute it freely, subject to
12 | the following restrictions:
13 |
14 | 1. The origin of this software must not be
15 | misrepresented; you must not claim that you
16 | wrote the original software. If you use this
17 | software in a product, an acknowledgment in
18 | the product documentation would be appreciated
19 | but is not required.
20 |
21 | 2. Altered source versions must be plainly marked
22 | as such, and must not be misrepresented as
23 | being the original software.
24 |
25 | 3. This notice may not be removed or altered from
26 | any source distribution.
27 |
28 |
--------------------------------------------------------------------------------
/static/noVNC/docs/VERSION:
--------------------------------------------------------------------------------
1 | 0.4
2 |
--------------------------------------------------------------------------------
/static/noVNC/docs/flash_policy.txt:
--------------------------------------------------------------------------------
1 | Manual setup:
2 |
3 | DATA="echo \' \'"
4 | /usr/bin/socat -T 1 TCP-L:843,reuseaddr,fork,crlf SYSTEM:"$DATA"
5 |
--------------------------------------------------------------------------------
/static/noVNC/docs/links:
--------------------------------------------------------------------------------
1 | New tight PNG protocol:
2 | http://wiki.qemu.org/VNC_Tight_PNG
3 | http://xf.iksaif.net/blog/index.php?post/2010/06/14/QEMU:-Tight-PNG-and-some-profiling
4 |
5 | RFB protocol and extensions:
6 | http://tigervnc.org/cgi-bin/rfbproto
7 |
8 | Canvas Browser Compatibility:
9 | http://philip.html5.org/tests/canvas/suite/tests/results.html
10 |
11 | WebSockets API standard:
12 | http://www.whatwg.org/specs/web-apps/current-work/complete.html#websocket
13 | http://dev.w3.org/html5/websockets/
14 | http://www.ietf.org/id/draft-ietf-hybi-thewebsocketprotocol-00.txt
15 |
16 | Browser Keyboard Events detailed:
17 | http://unixpapa.com/js/key.html
18 |
19 | ActionScript (Flash) WebSocket implementation:
20 | http://github.com/gimite/web-socket-js
21 |
22 | ActionScript (Flash) crypto/TLS library:
23 | http://code.google.com/p/as3crypto
24 | http://github.com/lyokato/as3crypto_patched
25 |
26 | TLS Protocol:
27 | http://en.wikipedia.org/wiki/Transport_Layer_Security
28 |
29 | Generate self-signed certificate:
30 | http://docs.python.org/dev/library/ssl.html#certificates
31 |
32 | Cursor appearance/style (for Cursor pseudo-encoding):
33 | http://en.wikipedia.org/wiki/ICO_(file_format)
34 | http://www.daubnet.com/en/file-format-cur
35 | https://developer.mozilla.org/en/Using_URL_values_for_the_cursor_property
36 | http://www.fileformat.info/format/bmp/egff.htm
37 |
38 | Icon/Cursor file format:
39 | http://msdn.microsoft.com/en-us/library/ms997538
40 | http://msdn.microsoft.com/en-us/library/aa921550.aspx
41 | http://msdn.microsoft.com/en-us/library/aa930622.aspx
42 |
43 |
44 | RDP Protocol specification:
45 | http://msdn.microsoft.com/en-us/library/cc240445(v=PROT.10).aspx
46 |
47 |
48 | Related projects:
49 |
50 | guacamole: http://guacamole.sourceforge.net/
51 |
52 | - Web client, but Java servlet does pre-processing
53 |
54 | jsvnc: http://code.google.com/p/jsvnc/
55 |
56 | - No releases
57 |
58 | webvnc: http://code.google.com/p/webvnc/
59 |
60 | - Jetty web server gateway, no updates since April 2008.
61 |
62 | RealVNC Java applet: http://www.realvnc.com/support/javavncviewer.html
63 |
64 | - Java applet
65 |
66 | Flashlight-VNC: http://www.wizhelp.com/flashlight-vnc/
67 |
68 | - Adobe Flash implementation
69 |
70 | FVNC: http://osflash.org/fvnc
71 |
72 | - Adbove Flash implementation
73 |
74 | CanVNC: http://canvnc.sourceforge.net/
75 |
76 | - HTML client with REST to VNC python proxy. Mostly vapor.
77 |
--------------------------------------------------------------------------------
/static/noVNC/docs/notes:
--------------------------------------------------------------------------------
1 | Some implementation notes:
2 |
3 | There is an included flash object (web-socket-js) that is used to
4 | emulate websocket support on browsers without websocket support
5 | (currently only Chrome has WebSocket support).
6 |
7 | Javascript doesn't have a bytearray type, so what you get out of
8 | a WebSocket object is just Javascript strings. Javascript has UTF-16
9 | unicode strings and anything sent through the WebSocket gets converted
10 | to UTF-8 and vice-versa. So, one additional (and necessary) function
11 | of websockify is base64 encoding/decoding what is sent to/from the
12 | browser.
13 |
14 | Building web-socket-js emulator:
15 |
16 | cd include/web-socket-js/flash-src
17 | mxmlc -static-link-runtime-shared-libraries WebSocketMain.as
18 |
--------------------------------------------------------------------------------
/static/noVNC/docs/packaging.txt:
--------------------------------------------------------------------------------
1 | noVNC packaging steps for Debian/Ubuntu:
2 |
3 | - Update the noVNC version in docs/VERSION and add a new entry for the
4 | version in debian/changelog
5 |
6 | - Rename the novnc source directory to match the form "novnc-VERSION".
7 |
8 | - In the novnc source directory, run the packaging command:
9 |
10 | debuild -I -uc -us
11 |
12 | - The -I option ignores the .git directory when generating the
13 | source tarball.
14 | - the -uc and -us may be omitted in order to create a signed
15 | package.
16 |
17 | - Alternatively, use pbuilder instead of debuild in order to build
18 | for other distributions and to guarantee a sanitized package.
19 |
20 | - Verify the package and then commit the changes to docs/VERSION and
21 | debian/changelog.
22 |
23 | - Upload the new package file(s).
24 |
--------------------------------------------------------------------------------
/static/noVNC/docs/release.txt:
--------------------------------------------------------------------------------
1 | - Update and commit docs/VERSION and debian/changelog
2 | - Create version tag and tarball from tag
3 | WVER=0.3
4 | git tag v${WVER}
5 | git push origin master
6 | git push origin v${WVER}
7 | git archive --format=tar --prefix=novnc-${WVER}/ v${WVER} > novnc-${WVER}.tar
8 | gzip novnc-${WVER}.tar
9 | - Upload tarball to repo
10 |
--------------------------------------------------------------------------------
/static/noVNC/docs/rfbproto-3.3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/noVNC/docs/rfbproto-3.3.pdf
--------------------------------------------------------------------------------
/static/noVNC/docs/rfbproto-3.7.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/noVNC/docs/rfbproto-3.7.pdf
--------------------------------------------------------------------------------
/static/noVNC/docs/rfbproto-3.8.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/noVNC/docs/rfbproto-3.8.pdf
--------------------------------------------------------------------------------
/static/noVNC/include/Orbitron700.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/noVNC/include/Orbitron700.ttf
--------------------------------------------------------------------------------
/static/noVNC/include/Orbitron700.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/noVNC/include/Orbitron700.woff
--------------------------------------------------------------------------------
/static/noVNC/include/blue.css:
--------------------------------------------------------------------------------
1 | /*
2 | * noVNC blue CSS
3 | * Copyright (C) 2012 Joel Martin
4 | * Copyright (C) 2013 Samuel Mannehed for Cendio AB
5 | * noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
6 | * This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
7 | */
8 |
9 | .noVNC_status_normal {
10 | background-color:#04073d;
11 | background-image: -webkit-gradient(
12 | linear,
13 | left bottom,
14 | left top,
15 | color-stop(0.54, rgb(10,15,79)),
16 | color-stop(0.5, rgb(4,7,61))
17 | );
18 | background-image: -moz-linear-gradient(
19 | center bottom,
20 | rgb(10,15,79) 54%,
21 | rgb(4,7,61) 50%
22 | );
23 | }
24 | .noVNC_status_error {
25 | background-color:#f04040;
26 | background-image: -webkit-gradient(
27 | linear,
28 | left bottom,
29 | left top,
30 | color-stop(0.54, rgb(240,64,64)),
31 | color-stop(0.5, rgb(4,7,61))
32 | );
33 | background-image: -moz-linear-gradient(
34 | center bottom,
35 | rgb(4,7,61) 54%,
36 | rgb(249,64,64) 50%
37 | );
38 | }
39 | .noVNC_status_warn {
40 | background-color:#f0f040;
41 | background-image: -webkit-gradient(
42 | linear,
43 | left bottom,
44 | left top,
45 | color-stop(0.54, rgb(240,240,64)),
46 | color-stop(0.5, rgb(4,7,61))
47 | );
48 | background-image: -moz-linear-gradient(
49 | center bottom,
50 | rgb(4,7,61) 54%,
51 | rgb(240,240,64) 50%
52 | );
53 | }
54 |
55 | .triangle-right {
56 | border:2px solid #fff;
57 | background:#04073d;
58 | color:#fff;
59 | }
60 |
61 | #keyboardinput {
62 | background-color:#04073d;
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/static/noVNC/include/web-socket-js/WebSocketMain.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/static/noVNC/include/web-socket-js/WebSocketMain.swf
--------------------------------------------------------------------------------
/stats/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/stats/__init__.py
--------------------------------------------------------------------------------
/stats/models.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/stats/models.py
--------------------------------------------------------------------------------
/stats/urls.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 | # Copyright (C) 2010-2014 GRNET S.A.
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 | #
17 |
18 | from django.conf.urls import url
19 | from stats import views
20 |
21 | urlpatterns = [
22 | url(r'^applications/?', views.stats_ajax_applications, name="stats_ajax_apps"),
23 | url(r'^instances/?', views.stats_ajax_instances, name="stats_ajax_instances"),
24 | url(r'^vms_cluster/(?P[^/]+)/?', views.stats_ajax_vms_per_cluster, name="stats_ajax_vms_pc"),
25 | url(r'^$', views.stats, name="stats"),
26 | ]
27 |
--------------------------------------------------------------------------------
/templates/403.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block title %}Access denied{% endblock %}
4 |
5 | {% block navbars %}{% endblock %}
6 |
7 | {% block blockcontainer %}
8 |
33 | {% endblock %}
34 |
--------------------------------------------------------------------------------
/templates/404.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block title %}Nice 404 - Page not found{% endblock %}
4 | {% block navbars %}{% endblock %}
5 | {% block blockcontainer %}
6 |
31 | {% endblock %}
32 |
--------------------------------------------------------------------------------
/templates/500.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block title %}Ohhhh a 500 - Internal Error{% endblock %}
5 | {% block navbars %}{% endblock %}
6 | {% block blockcontainer %}
7 |
32 | {% endblock %}
33 |
--------------------------------------------------------------------------------
/templates/apply/emails/application_rejected_mail.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}{% blocktrans with username=application.applicant.username pk=application.pk hostname=application.hostname admin_comments=application.admin_comments service=BRANDING.SERVICE_PROVIDED_BY.NAME %}Dear {{ username }},
2 | Your request #{{ pk }} to create virtual machine name
3 | {{ hostname }} has been rejected for the following reasons:
4 |
5 | {{ admin_comments }}
6 |
7 | For more information please contact the {{ service }} Helpdesk.
8 | {% endblocktrans %}
9 |
--------------------------------------------------------------------------------
/templates/apply/emails/apply_mail.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}{% blocktrans with username=user.username first_name=user.first_name last_name=user.last_name %}User {{ username }} ({{ first_name }} {{ last_name }}) made the following request:{% endblocktrans %}
2 | {% load disksizes %}
3 | {% blocktrans with hostname=application.hostname memory=application.memory|memsize vcpus=application.vcpus disk_size=application.disk_size operating_system=application.operating_system hosts_mail_server=application.hosts_mail_server|yesno:"Yes,No" %}
4 | VM parameters
5 | -------------
6 | Name: {{ hostname }}
7 | Memory: {{ memory }}
8 | vCPUs: {{ vcpus }}
9 | Disk: {{ disk_size }} GB
10 | Operating system: {{ operating_system }}
11 | Hosting mail server: {{ hosts_mail_server }}
12 | {% endblocktrans %}
13 | {% if application.network %}{% blocktrans %}The user requested the VM to connect to the network{% endblocktrans %} «{{application.network}}»{% endif %}
14 |
15 | {% trans "Contact" %}:
16 | {% if application.organization %}
17 |
18 | {% trans "Responsible entity" %}: {{application.organization}} {% else %}
19 | {% trans "Administrative Contact" %}
20 | ----------------------
21 | {{ application.admin_contact_name }}
22 | {{ application.admin_contact_email }}
23 | {{ application.admin_contact_phone }}{% endif %}
24 |
25 | {% if application.comments %}
26 | {% trans "Comments" %}
27 | --------
28 | {{ application.comments }}{% endif %}
29 |
30 | {% blocktrans %}To manage the request, visit {{url}}{% endblocktrans %}
31 |
--------------------------------------------------------------------------------
/templates/flatpages/default.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% load staticfiles %}
4 |
5 | {% block navbars %}{% endblock %}
6 |
7 | {% block title %}{{ flatpage.title }}{% endblock %}
8 |
9 | {% block brcrmb_container %}{% endblock %}
10 |
11 | {% block extrahead %}
12 |
27 | {% endblock %}
28 |
29 | {% block blockcontainer %}
30 |
55 | {% endblock %}
56 |
57 |
--------------------------------------------------------------------------------
/templates/flatpages/faq.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% block extrahead %}
4 |
19 | {% endblock %}
20 |
21 | {% block title %}
22 | {{ flatpage.title }}
23 | {% endblock %}
24 |
25 | {% block faq %}class="active"{% endblock %}
26 |
27 | {% block crumbs %}
28 | {% trans "Home" %} /
29 | {% trans flatpage.title %}
30 | {% endblock %}
31 |
32 | {% block content %}
33 |
34 |
35 |
36 |
{% trans flatpage.title %}
37 | {{ flatpage.content }}
38 |
39 |
40 |
41 | {% endblock %}
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/templates/includes/analytics.html.dist:
--------------------------------------------------------------------------------
1 | {% comment %}
2 | This is an example.
3 | Copy this file to the templates/analytics.html file
4 |
5 | Change provider according to your needs or leave this file empty if no analytics is required.
6 |
7 | Examples:
8 | PIWIK:
9 |
10 |
23 |
24 |
25 |
26 |
27 | GOOGLE ANALYTICS:
28 |
41 | {% endcomment %}
42 |
43 |
--------------------------------------------------------------------------------
/templates/includes/banners.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/templates/instances/emails/instance_created_mail.txt:
--------------------------------------------------------------------------------
1 | Η εικονική μηχανή με όνομα {{ application.hostname }} δημιουργήθηκε.
2 |
3 | Μπορείτε να τη χειριστείτε και να δείτε τα στοιχεία της στην ακόλουθη
4 | διεύθυνση:
5 | {{instance_url}}
6 |
7 | {% if application.admin_comments %}Σχόλια διαχειριστή:
8 | {{ application.admin_comments }}
9 | {% endif %}
10 |
11 | {% if reviewer %}Εγκρίθηκε από: {{reviewer}}
12 | {% endif %}
13 |
14 | Για περισσότερες πληροφορίες για την εικονική μηχανή σας ή για οποιοιδήποτε
15 | άλλο αίτημα αφορά την υπηρεσία, μπορείτε να επικοινωνήσετε με το Helpdesk του
16 | {{ BRANDING.SERVICE_PROVIDED_BY.NAME }}.
17 |
18 | -----------------------------------------------------------------------------
19 |
20 | The virtual machine name {{ application.hostname }} has been created.
21 |
22 | You can manipulate and view the data at the following address:
23 | {{instance_url}}
24 |
25 | {% if application.admin_comments %}Comments from the administrator:
26 | {{ application.admin_comments }}
27 | {% endif %}
28 |
29 | {% if reviewer %}Approved by: {{reviewer}}
30 | {% endif %}
31 | For more information on the virtual machine or any
32 | other request regarding the service, you can contact the {{ BRANDING.SERVICE_PROVIDED_BY.NAME }} Helpdesk.
33 |
--------------------------------------------------------------------------------
/templates/instances/emails/reinstall_mail.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}{% blocktrans with username=user.username %}User {{ user.username }} {% endblocktrans%}{% if user.first_name or user.last_name %}({{user.first_name}} {{user.last_name}}){% endif %} {% trans "has made the following request" %}:
2 | ------------------------
3 |
4 | {% if action == 'reinstall' %}{% trans "Reinstall" %}:{% endif %}{% if action == 'destroy' %}{% trans "Delete" %}:{% endif %}{% if action == 'rename' %}{% trans "Rename" %}:{% endif %}{% if action == 'mailchange' %}{% trans "Change email" %}{% endif %}
5 | {% if action == 'mailchange' %}{% trans "New email" %}: {{action_value}}{% endif %}{% if action != 'mailchange' %}
6 | {{instance}} {% if action == 'rename' %}{% trans "to" %} {{action_value}}{% endif %}{% if action != 'rename' %}
7 | {% trans "WARNING! The above action will" %} {% if action == 'reinstall' %}{% trans "delete your data" %}{% if operating_system %} {% trans "and install" %} {{ operating_system }}{% endif %}{% endif %}{% if action == 'destroy' %}{% trans "delete your virtual machine" %}{% endif %}. {% blocktrans %}Make sure you take backups of any data you need.
8 | WARNING! Once you start the process, it cannot be undone. {% endblocktrans %}
9 | {% endif %}{% endif %}
10 | {% blocktrans %}To continue, please visit {{url}}{% endblocktrans %}
11 |
--------------------------------------------------------------------------------
/templates/instances/includes/console-module.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 |
3 | {% if WEBSOCK_VNC_ENABLED %}
4 |
5 | {% endif %}
6 | {% if LEGACY_VNC_ENABLED %}
7 |
8 | {% endif %}
9 |
--------------------------------------------------------------------------------
/templates/instances/includes/instance_status.html:
--------------------------------------------------------------------------------
1 |
2 | {{ instance.get_state }}
3 |
4 |
--------------------------------------------------------------------------------
/templates/instances/vnc.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load staticfiles %}
3 | {% load i18n %}
4 |
5 | {% block homepage %}class="active"{% endblock %}
6 |
7 | {% block homepagetop %}class="active"{% endblock %}
8 |
9 | {% block title %}{{ instance }} - {% trans "Console" %}{% endblock %}
10 |
11 | {% block crumbs %}
12 | {% trans "Home" %} /
13 | {{ instance }} /
14 | {% trans "Console" %}
15 | {% endblock %}
16 |
17 | {% block content %}
18 | {% if LEGACY_VNC_ENABLED %}
19 |
20 |
21 |
22 |
{% trans "VNC session on" %} {{ instance }}
23 |
24 |
25 |
26 |
30 |
31 |
32 |
33 |
34 | {% else %}
35 |
36 |
37 | Java VNC is not enabled.
38 |
39 | {% endif %}
40 | {% endblock %}
41 |
--------------------------------------------------------------------------------
/templates/jobs/job_details.html:
--------------------------------------------------------------------------------
1 |
{{job}}
--------------------------------------------------------------------------------
/templates/news/news.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load staticfiles %}
3 | {% load i18n %}
4 | {% block extrahead %}
5 | {% if BRANDING.FEED_URL %}
6 |
7 |
8 |
9 |
10 |
22 | {% endif %}
23 | {% endblock %}
24 |
25 | {% block title %}
26 | {% trans "Latest News" %}
27 | {% endblock %}
28 |
29 | {% block news %}class="active"{% endblock %}
30 |
31 | {% block crumbs %}
32 |
{% trans "Home" %} /
33 |
{% trans "Latest News" %}
34 | {% endblock %}
35 |
36 | {% block content %}
37 |
38 |
39 |
40 |
{% trans "Latest News" %}
41 | {% if BRANDING.FEED_URL %}{% else %}No news channel set.{% endif %}
42 |
43 |
44 |
45 | {% endblock %}
46 |
--------------------------------------------------------------------------------
/templates/notifications/create.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% block notify %}class="active"{% endblock %}
4 | {% block title %}{% trans "Notifications" %}{% endblock %}
5 |
6 | {% block crumbs %}
7 |
8 | {% trans "Home" %}
9 | /
10 |
11 |
{% trans "Notifications" %}
12 | {% endblock %}
13 |
14 | {% block extrahead %}
15 |
16 | {% include "notifications/create_script.html" %}
17 |
18 | {% endblock %}
19 |
20 | {% block content %}
21 | {% include "notifications/create_body.html" %}
22 | {% if archive %}
23 |
Archive
24 |
31 | {% endif %}
32 | {% endblock %}
33 |
34 |
--------------------------------------------------------------------------------
/templates/notifications/create_ajax.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% block extrahead %}
3 |
4 | {% include "notifications/create_script.html" %}
5 |
34 | {% endblock %}
35 |
36 | {% block content %}
37 | {% include "notifications/create_body.html" %}
38 | {% endblock %}
39 |
--------------------------------------------------------------------------------
/templates/notifications/detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block notify %}class="active"{% endblock %}
5 |
6 | {% block title %}{% trans "Notifications" %}{% endblock %}
7 |
8 | {% block crumbs %}
9 |
10 | {% trans "Home" %}
11 | /
12 |
13 |
{% trans "Notifications" %}
14 | {% endblock %}
15 |
16 | {% block content %}
17 |
{{ notification.subject }}
18 |
{{ notification.date }}
19 | {% if notification.sender %}
20 |
Sender
21 | {{ notification.sender }}
22 | {% endif %}
23 |
Message
24 |
{{ notification.message }}
25 |
Recipients
26 |
27 | {% for user in notification.recipients.all %}
28 | {{ user }} {% if not forloop.last %}, {% endif %}
29 | {% endfor %}
30 |
31 | {% endblock %}
32 |
33 |
--------------------------------------------------------------------------------
/templates/registration/activate.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% block title %}{% trans "Activation Status" %}{% endblock %}
4 | {% block brcrmb_container %}{% endblock %}
5 | {% block blockcontainer %}
6 |
32 | {% endblock %}
33 |
--------------------------------------------------------------------------------
/templates/registration/activation_complete_admin_pending.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% block title %}{% trans "Activation Complete" %}{% endblock %}
4 | {% block brcrmb_container %}{% endblock %}
5 | {% block blockcontainer %}
6 |
31 | {% endblock %}
32 |
--------------------------------------------------------------------------------
/templates/registration/activation_complete_admin_pending.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}{% blocktrans %}You have successfully validated your email address.
2 | Your account with username {% endblocktrans %}“{{ user.username }}” {% blocktrans %} will be activated by an administrator and you will be notified via email.{% endblocktrans %}
--------------------------------------------------------------------------------
/templates/registration/activation_email.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}{% url validate_email validation_key as validation_url %}{% blocktrans with full_name=user.get_full_name username=user.username email=user.email domain=site.domain %}You have registered for a new account.
2 |
3 | Username: {{ username }}
4 | E-mail: {{ email }}
5 |
6 | To proceed with with your account activation, you must first validate your email
7 | address. To do so, click on the following link or copy the address to your browser
8 | {% endblocktrans %}
9 |
10 | http://{{ site.domain }}{% url 'registration_activate' activation_key %}
11 |
12 | {% blocktrans %}
13 | The site's administrator will then be notified about your newly created account and
14 | proceed to approve it.
15 |
16 | You have {{ expiration_days }} days to validate your email address. If you fail to
17 | do so within the time limit, you will have to register again.
18 |
19 | Upon approval, you will receive a new email message.
20 | {% endblocktrans %}
21 |
--------------------------------------------------------------------------------
/templates/registration/activation_email_subject.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}[{{site.name}}]{% trans "User account activation" %}
2 |
--------------------------------------------------------------------------------
/templates/registration/admin_approve.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% block title %}{% trans "Admin approval status" %}{% endblock %}
4 | {% block brcrmb_container %}{% endblock %}
5 | {% block blockcontainer %}
6 |
32 | {% endblock %}
33 |
--------------------------------------------------------------------------------
/templates/registration/admin_approve_complete.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% block title %}{% trans "Admin approval Complete" %}{% endblock %}
4 | {% block brcrmb_container %}{% endblock %}
5 |
6 | {% block blockcontainer %}
7 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/templates/registration/admin_approve_complete_email.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}{% blocktrans %}Your account {% endblocktrans %} {% blocktrans %}has been approved.{% endblocktrans %}
2 | {% blocktrans %}You may login using the following URL:{% endblocktrans %}
3 |
4 | http://{{ site.domain }}{% url 'login' %}
5 |
--------------------------------------------------------------------------------
/templates/registration/admin_approve_email.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}{% blocktrans with full_name=user.get_full_name username=user.username email=user.email %}User {{ full_name }} has registered for a new account.
2 |
3 | Username: {{ username }}
4 | E-mail: {{ email }}
5 |
6 | To approve the user's account, click on the following url:
7 | {% endblocktrans %}
8 |
9 | http://{{ site.domain }}{% url 'registration_admin_approve' profile_id %}"
10 |
11 | {% blocktrans %}
12 | Upon approval the user will receive a new email message.
13 | {% endblocktrans %}
14 |
--------------------------------------------------------------------------------
/templates/registration/admin_approve_email_subject.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}[{{site.name}}]{% trans "User account approval" %}
2 |
--------------------------------------------------------------------------------
/templates/registration/password_change_form.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block content %}
4 |
5 |
{% trans "Change Password" %}
6 |
7 |
13 |
14 |
15 | {% endblock %}
16 |
--------------------------------------------------------------------------------
/templates/registration/password_reset_complete.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% block title %}{% trans "Password Reset Complete" %}{% endblock %}
4 | {% block brcrmb_container %}{% endblock %}
5 |
6 | {% block blockcontainer %}
7 |
31 | {% endblock %}
32 |
--------------------------------------------------------------------------------
/templates/registration/password_reset_confirm.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %} {% load i18n %}
2 | {% block title %}{% trans "Reset Password" %}{% endblock %}
3 | {% block brcrmb_container %}{% endblock %}
4 | {% block blockcontainer %}
5 |
56 | {% endblock %}
57 |
--------------------------------------------------------------------------------
/templates/registration/password_reset_done.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% block title %}{% trans "Email sent" %}{% endblock %}
4 | {% block brcrmb_container %}{% endblock %}
5 | {% block blockcontainer %}
6 |
28 | {% endblock %}
29 |
--------------------------------------------------------------------------------
/templates/registration/password_reset_email.html:
--------------------------------------------------------------------------------
1 | Dear {{ user.username }},
2 | Reset password at {{ site_name }}:
3 | {% block reset_link %}
4 | {{ protocol }}://{{ domain }}{% url 'auth_password_reset_confirm' uid token %}
5 | {% endblock %}
6 |
--------------------------------------------------------------------------------
/templates/registration/password_reset_form.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %} {% load i18n %} {% block title %}
2 | {% trans "Reset Password" %}{% endblock %} {% block brcrmb_container %}{% endblock %}
3 | {% load widget_tweaks %}
4 | {% block blockcontainer %}
5 |
44 | {% endblock %}
45 |
--------------------------------------------------------------------------------
/templates/registration/registration_complete.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% block title %}{% trans "Activation email sent" %}{% endblock %}
4 | {% block brcrmb_container %}{% endblock %}
5 |
6 | {% block blockcontainer %}
7 |
32 | {% endblock %}
33 |
--------------------------------------------------------------------------------
/templates/registration/validation_expired.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% block title %}{% trans "Activation Expired" %}{% endblock %}
4 | {% block brcrmb_container %}{% endblock %}
5 |
6 | {% block blockcontainer %}
7 |
32 | {% endblock %}
33 |
--------------------------------------------------------------------------------
/templates/tagging/isolate.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
5 |
35 |
36 |
48 |
49 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/templates/tagging/lock.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
34 |
46 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/templates/users/emails/idle_account.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}{% trans 'Dear' %} {{ user.username }},
2 | {% blocktrans %}To ensure the validity of user accounts in the
3 | service we monitor usage of the web management interface.{% endblocktrans %}
4 | {% blocktrans %}We would like to inform you that the last time you logged in was {{days}} ago (or more). {% endblocktrans %}
5 |
6 | {% blocktrans %}Therefore we kindly ask you to confirm the validity of your account.
7 | The confirmation is performed by accessing the login page of the service: {% endblocktrans %}
8 | https://{{ site.domain }}{% url 'login' %}
9 | {% blocktrans %}Please do this as soon as possible.{% endblocktrans %}
10 | {% blocktrans with service_name=service.TITLE %}
11 | Sincerely,
12 | The {{ service_name }} Management.
13 | {% endblocktrans %}
14 |
--------------------------------------------------------------------------------
/templates/users/emails/pass_change_notify_mail.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}{% blocktrans %}Dear {{ user }},{% endblocktrans %}{% blocktrans %}
2 | We hereby inform you that the password for your account
3 | in the {{ service_title }} service has been changed successfully.
4 | {% endblocktrans %}{% blocktrans %}
5 | If the password change was not made by you, please inform
6 | the {{ provider }} Helpdesk.
7 | {% endblocktrans %}
8 |
--------------------------------------------------------------------------------
/templates/users/pass_change_done.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 |
15 |
{% trans "Password changed" %} {% trans "successfully" %}
16 |
--------------------------------------------------------------------------------
/util/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grnet/ganetimgr/314173e7f0b7001174fb77fcb6bf679d4d33012b/util/__init__.py
--------------------------------------------------------------------------------
/util/vapclient.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
3 | #
4 |
5 | import sys
6 | import json
7 | import socket
8 |
9 |
10 | CTRL_SOCKET = "/var/run/vncauthproxy/vncproxy.sock"
11 |
12 | def request_forwarding(sport, daddr, dport, password):
13 | assert(len(password) > 0)
14 | req = {
15 | "source_port": int(sport),
16 | "destination_address": daddr,
17 | "destination_port": int(dport),
18 | "password": password
19 | }
20 |
21 | ctrl = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
22 | ctrl.connect(CTRL_SOCKET)
23 | ctrl.send(json.dumps(req))
24 |
25 | response = ctrl.recv(1024)
26 | res = json.loads(response)
27 | return res
28 |
29 | if __name__ == '__main__':
30 | res = request_forwarding(*sys.argv[1:])
31 | if res['status'] == "OK":
32 | sys.exit(0)
33 | else:
34 | sys.exit(1)
35 |
36 |
37 | def request_novnc_forwarding(server, daddr, dport, password, sport=None, tls=True):
38 | """
39 | Ask TVAP/VNCAP for a forwarding port.
40 |
41 | The control socket on TVAP wants a JSON dictionary containing at least the
42 | destination port and address, and VNC password. It optionally can accept a
43 | requested source port, whether WebSockets should be used, and whether TLS
44 | (SSL/WSS) should be used.
45 | """
46 |
47 | try:
48 | host, port = server
49 | port = int(port)
50 | dport = int(dport)
51 | if not password:
52 | return False
53 |
54 | request = {
55 | "daddr": daddr,
56 | "dport": dport,
57 | "password": password,
58 | "ws": True,
59 | "tls": tls,
60 | }
61 |
62 | if sport:
63 | request["sport"] = sport
64 |
65 | request = json.dumps(request)
66 |
67 | ctrl = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
68 | ctrl.connect((host, port))
69 | ctrl.send("%s\r\n" % request)
70 | response = ctrl.recv(1024).strip()
71 | ctrl.close()
72 |
73 | if response.startswith("FAIL"):
74 | return False
75 | else:
76 | return response
77 |
78 | # XXX bare except
79 | except:
80 | return False
81 |
--------------------------------------------------------------------------------
/version:
--------------------------------------------------------------------------------
1 | 314173e7
2 |
--------------------------------------------------------------------------------