Commit 0d188bd6 by Őry Máté

Merge branch 'release-13.03.1' into releases

parents e0757a88 a5e7ec7a
......@@ -34,6 +34,10 @@ nosetests.xml
.project
.pydevproject
# Compiled CSS/JS resources
*.css
*.min.js
# Other
*.swp
*~
......
SHELL := /bin/bash
jsfiles += one/static/script/cloud.min.js
jsfiles += one/static/script/util.min.js
jsfiles += one/static/script/store.min.js
cssfiles += one/static/style/style.css
default: migrate collectstatic mo restart
default: migrate generatestatic collectstatic mo restart
pulldef: pull default
pull:
......@@ -14,6 +18,8 @@ po:
migrate:
./manage.py migrate
generatestatic: $(jsfiles) $(cssfiles)
collectstatic:
./manage.py collectstatic --noinput
......@@ -22,4 +28,10 @@ mo:
for i in */; do cd $$i; ls locale &>/dev/null && ../manage.py compilemessages || true; cd ..; done
restart:
sudo /etc/init.d/apache2 reload
sudo /etc/init.d/apache2 reload || sudo restart django
%.min.js: %.js
uglifyjs $< > $@
%.css: %.less
lessc one/static/style/style.less > one/static/style/style.css
from cloud.settings import DEBUG
def process_debug(req):
return {'DEBUG': DEBUG}
......@@ -5,7 +5,7 @@ DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
('IK', 'cloud@iit.bme.hu'),
('IK', 'cloud@cloud.ik.bme.hu'),
)
MANAGERS = ADMINS
......@@ -73,6 +73,7 @@ STATICFILES_DIRS = (
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
'/opt/webadmin/cloud/one/static',
'/opt/webadmin/cloud/cloud/static',
)
# List of finder classes that know how to find static files in
......@@ -109,6 +110,17 @@ ROOT_URLCONF = 'cloud.urls'
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'cloud.wsgi.application'
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.contrib.messages.context_processors.messages',
'cloud.context_processors.process_debug',
)
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
......@@ -186,21 +198,22 @@ CELERY_ROUTES = {
'firewall.tasks.reload_firewall_task': {'queue': 'firewall'},
'firewall.tasks.reload_dhcp_task': {'queue': 'dhcp'},
'firewall.tasks.reload_blacklist_task': {'queue': 'firewall'},
'firewall.tasks.Periodic': {'queue': 'local'},
'one.tasks.SendMailTask': {'queue': 'local'},
}
store_settings = {
"basic_auth": "True",
"verify_ssl": "False",
"ssl_auth": "False",
"store_client_pass": "IQu8Eice",
"store_client_user": "admin",
"store_client_key": "/opt/webadmin/cloud/client.key",
"store_client_cert": "/opt/webadmin/cloud/client.crt",
"store_url": "http://localhost:9000",
"store_public": "store.ik.bme.hu",
"basic_auth": "True",
"verify_ssl": "False",
"ssl_auth": "False",
"store_client_pass": "IQu8Eice",
"store_client_user": "admin",
"store_client_key": "/opt/webadmin/cloud/client.key",
"store_client_cert": "/opt/webadmin/cloud/client.crt",
"store_url": "http://localhost:9000",
"store_public": "store.ik.bme.hu",
}
firewall_settings = {
"default_vlangroup": "publikus",
"reload_sleep": "10",
......@@ -210,6 +223,9 @@ firewall_settings = {
"dns_ttl": "300",
}
EMAIL_HOST='152.66.243.92' # giccero ipv4
CLOUD_URL='https://cloud.ik.bme.hu/'
try:
from cloud.local_settings import *
except:
......
<!DOCTYPE html>
<html lang="hu">
<head>
<title>IK Cloud</title>
<link href="https://fonts.googleapis.com/css?family=Titillium+Web&amp;subset=latin,latin-ext" rel="stylesheet" type="text/css" />
<link rel="icon" type="image/png" href="/static/favicon.png" />
<link href="/static/style/style.css" rel="stylesheet" type="text/css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div id="header">
<h1><a href="/">IK Cloud</a></h1>
</div>
<div id="content">
<div id="http-error">
<h1>Karbantartás – Maintenance</h1>
<p lang="hu">
Az oldal ideiglenesen nem érhető el karbantartás miatt. Elnézést kérünk a kellemetlenségekért.
</p>
<p lang="en">
The site is temporarily down for maintenance. We apologize for any inconvinience.
</p>
</div>
<div class="clear"></div>
</div>
<footer>
<a href="/sites/legal/">Impresszum</a> |
<a href="/sites/policy/">Szabályzat</a> |
<a href="/sites/help/">Súgó</a> |
<a href="/sites/support/">Támogatás</a> |
cloud <em>(kukac)</em> ik.bme.hu
</footer>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-39125666-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block js %}
<script type="text/javascript" src="{% static "script/store.js" %}"></script>
<style>
.contentblock p{
margin: 15px;
text-align: justify;
}
.contentblock img{
margin: 0px auto;
display: block;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.3);
border-radius: 5px;
text-align: center;
vertical-align: middle;
}
.boxes a:link,
a:visited {
color: black;
}
.boxes strong {
font-size: .9em;
}
</style>
{% endblock %}
{% block content %}
<div class="boxes">
<div class="contentblock" id="state">
<h2>A projektről</h2>
<div>
<p>Az <strong>IK Cloud</strong> a BME IK és IIT együttműködésében, a VIK
támogatásával hosszabb ideje folyó munka során jött létre.
A kutatás célja <strong>a cloud oktatási-kutatási célú felhasználásának</strong>
vonzóvá tétele.
</p>
<p>
A nagy kapacitású virtuális infrastruktúra azonban új lehetőséget is nyújt.
<strong>Igény szerint</strong> indíthatóak virtuális gépek:
gördülékennyé válik a tantermi és otthoni <strong>hallgatói munka,</strong>
a kutatási <strong>projektek dinamikus IT támogatása.</strong>
</p>
<p><img src="{% static "info/cloud-migration.png" %}" /></p>
<p>A rendszerünk segítségével <strong>kiváltható</strong> a tanszéken
működő öregedő szerverpark jelentős része.</p>
</div>
</div>
</div>
<div class="boxes">
<div class="contentblock" id="state">
<h2>Virtuális labor</h2>
<div>
<p><img src="{% static "info/cloud-lab.png" %}" /></p>
<p>Lehetőség van <strong>tantárgyra szabott környezet</strong> biztosítására
a tantermi mérések vagy az otthoni feladatok elvégzéséhez, vagy az
önkiszolgáló felületen pillanatok alatt indítható <strong>projektek, önálló
labor, szakdolgozat, diplomaterv, vagy TDK-munka</strong> segítéséhez
virtuális gép.</p>
<p style="text-align:center;"><a
href="{% url one.views.home %}">Próbálja ki a rendszert
most!</a></p>
</div>
</div>
<div class="contentblock" id="state" lang="en">
<h2>About the project</h2>
<div>
<p>The project aims to harness the power of cloud computing in
education and research. Our self service portal helps migrating
old servers, and on-demand launching appliances prepared by the
teacher.</p>
</p>
</div>
</div>
</div>
{% endblock %}
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
<div class="irasmu">
<p>A súgó elkészültéig kérjük szíves türelmüket.</p>
<p>Addig is ajánljuk figyelmükbe a rendszer <a href="/info/">rövid ismertetőjét</a>, a használat módját részletező <a href="/sites/policy/">szabályzatot</a>, valamint a felület számos pontján megjelenő <img src="{% static "icons/information-frame.png" %}" alt="Súgó" /> ikonnal jelölt információdobozokat.</p>
<p>Amennyiben kérdése maradt, örömmel segítünk a <a href="/sites/support/">támogatás</a> oldalon leírt elérhetőségeinken.</p>
</div>
{% endblock %}
{% extends "base.html" %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
<div class="irasmu">
<p>Az IK Cloud a BME IK és IIT együttműködésében, a VIK támogatásával létrejött rendszer, amelyben az IIT oktatói és hallgatói szükség szerint vehetnek igénybe virtuális erőforrásokat.
</p>
<p>Az oldal üzemeltetője a BME Közigazgatási Informatikai Központ.</p>
<p>A rendszer fejlesztésében részt vettek:
Bach Dániel,
Dányi Bence,
Dudás Ádám,
Guba Sándor,
Őry Máté és
dr. Szeberényi Imre.</p>
<p>A rendszer HP hardveren, Ubuntu operációs rendszeren, KVM virtualizációval, Open vSwitch virtuális hálózaton, libvirt köztes réteggel, OpenNebula cloud menedzserrel, Django alapú webportállal működik.</p>
<p>Some icons by <a href="http://p.yusukekamiyamane.com/">Yusuke Kamiyamane</a>. Licensed under a <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 License</a>.</p>
</div>
{% endblock %}
{% extends "base.html" %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
<div class="irasmu">
<p>Az IK Cloud a BME IK és IIT együttműködésében, a VIK támogatásával létrejött rendszer, amelyben az IIT oktatói és hallgatói szükség szerint vehetnek igénybe <strong>virtuális erőforrásokat</strong>.</p>
<p>Az IIT géptermeiben telepített kliensszoftver segítségével az oktató által előkészített és kiajánlott <strong>virtuális környezetet a hallgató</strong> a számára megszabott <strong>kvóta keretein belül</strong> igény szerint indíthatja.</p>
<p>A HSZK géptermeiben a kliensszoftver jelenleg nincs telepítve, de a virtuális gépek indítása, a fájlok elérése webböngészővel is teljes értékű; míg a gépekhez való csatlakozás kézzel elvégezhető.</p>
<p>Lehetőség van a gépteremben elkezdett munka otthoni folytatására is a korábban elindított környezetben. A rendszer segítségével az otthoni feladatot végző hallgató is elkerülheti az összetett szoftverkörnyezet telepítésével járó kellemetlenségeket, figyelmét a szakmai munkára irányíthatja.</p>
<p>A rendszer segítséget nyújt önálló labor, szakdolgozat, diplomaterv vagy tdk-munka készítésénél is: a munkához szükséges virtuális gépeket az önkiszolgáló rendszeren keresztül azonnal használatba lehet venni.</p>
<p>Az elindított virtuális gépekre az adott operációs rendszeren szokásos módon lehet távolról csatlakozni: Windows esetén RDP (távoli asztal), Linux esetén SSH, vagy grafikusan NoMachine NX segítségével. A kapcsolódást a géptermekben telepített kliensszoftver még kényelmesebbé teszi.</p>
<p>Az elindított gépeken a <strong>felhasználói adattár</strong> automatikusan csatolásra kerül. Minden munkát itt érdemes végezni, mivel az a gép leállítása után is elérhető marad.</p>
<p>A felhasználók a rendszert jelen önkiszolgáló felületen keresztül érhetik el, amelybe az egyetemi címtárszolgáltatás (eduID) segítségével léphetnek be. A továbblépéssel elfogadják a következőekben összefoglalt <strong>felhasználási feltételeket</strong>.</p>
<ul>
<li>A rendszer <strong>nem használható</strong> semmilyen jogszabályba, vagy <a href="http://net.bme.hu/regula/">egyetemi</a> <strong>szabályzatba ütköző tevékenységre</strong>.</li>
<li><strong>Kizárólag tanulmányi</strong> vagy <strong>kutatási tevékenységhez</strong> használható erőforrás.</li>
<li>Bár a rendszer használata térítésmentes, a <strong>felesleges gépek leállítása</strong> a felhasználó kötelessége.</li>
<li>Minden gép indítása <strong>határidő kijelölésével</strong> történik. A határidő lejártával <strong>a gépet megállítjuk</strong>. Amennyiben a felhasználó a megállítást követően (a törlési határidő leteltéig) nem kéri meghosszabbítását, a gépet és <strong>minden rajta lévő adatot törlünk!</strong></li>
<li>A felhasználó felelőssége a futtatott rendszer biztonságos üzemeltetése, a hosszabb időn át futó gépek frissítése.</li>
<li>A rendszert üzemeltető BME IK lehetőségeihez mérten mindent megtesz a szolgáltatásbiztos üzemért, az egyetemi infrastruktúra sajátosságai miatt előforduló üzemszünetekre azonban számítani kell. A BME IK az üzemeltetés kapcsán a folyamatos üzem sérüléséért vagy adatvesztésért <strong>minden felelősséget kizár</strong>. Ezeknek megfelelően szükség esetén a biztonsági mentés és a magas rendelkezésre állású környezet kialakítása a felhasználóra hárul.</li>
</ul>
<p>A szabályok betartása közös érdekünk. Reméljük, hogy a rendszerünk használata megkönnyíti munkájukat, melyhez sok sikert kívánunk!</p>
</div>
{% endblock %}
{% extends "base.html" %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
<div class="irasmu">
<p>A rendszer használatával kapcsolatos kérdéseket, általános észrevételeket a <tt>cloud <em>(kukac)</em>
ik.bme.hu</tt> e-mail címen várjuk.
Ugyancsak örömmel fogadjuk a rendszer használatával kapcsolatos beszámolókat.</p>
<p>A rendszerben talált hibákat (vagy azok gyanúját), valamint ötleteit, javaslatait kérjük,
<a href="https://giccero.cloud.ik.bme.hu/trac/cloud/newticket" rel="nofollow">
hibajegy felvételével</a> jelezze.
</p>
</div>
{% endblock %}
......@@ -5,107 +5,91 @@ admin.autodiscover()
import one.views
import firewall.views
#import store.views
# import store.views
js_info_dict = {
'packages': ('one', ),
}
urlpatterns = patterns('',
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'one.views.home', name='home'),
url(r'^login/$', 'school.views.login', name='login'),
url(r'^logout/$', 'school.views.logout', name='logout'),
url(r'^vm/new/(?P<template>\d+)/$', 'one.views.vm_new', name='vm_new'),
url(r'^ajax/vm/new/(?P<template>\d+)/$', 'one.views.vm_new_ajax',
name='vm_new_ajax'),
url(r'^vm/new/s(?P<share>\d+)/$', 'one.views.vm_new', name='vm_new'),
url(r'^vm/show/(?P<iid>\d+)/$', 'one.views.vm_show', name='vm_show'),
url(r'^vm/delete/(?P<iid>\d+)/$', 'one.views.vm_delete',
name='vm_delete'),
url(r'^vm/stop/(?P<iid>\d+)/$', 'one.views.vm_stop', name='vm_stop'),
url(r'^vm/unshare/(?P<id>\d+)/$', 'one.views.vm_unshare',
name='vm_unshare'),
url(r'^vm/resume/(?P<iid>\d+)/$', 'one.views.vm_resume',
name='vm_resume'),
url(r'^vm/power_off/(?P<iid>\d+)/$', 'one.views.vm_power_off',
name='vm_power_off'),
url(r'^vm/restart/(?P<iid>\d+)/$', 'one.views.vm_restart',
name='vm_restart'),
url(r'^admin/doc/', include('django.contrib.admindocs.urls'), ),
url(r'^admin/', include(admin.site.urls), ),
url(r'^login/$', 'school.views.login', name='login', ),
url(r'^logout/$', 'school.views.logout', name='logout', ),
url(r'^$', 'one.views.index', ),
url(r'^info/$', 'one.views.info', ),
url(r'^home/$', 'one.views.home', ),
url(r'^vm/new/(?P<template>\d+)/$', 'one.views.vm_new',
name='new_vm_from_template'),
url(r'^ajax/vm/new/(?P<template>\d+)/$', 'one.views.vm_new_ajax', ),
url(r'^vm/new/s(?P<share>\d+)/$', 'one.views.vm_new',
name='new_vm_form_share'),
url(r'^vm/show/(?P<iid>\d+)/$', 'one.views.vm_show', ),
url(r'^vm/delete/(?P<iid>\d+)/$', 'one.views.vm_delete', ),
url(r'^vm/stop/(?P<iid>\d+)/$', 'one.views.vm_stop', ),
url(r'^vm/unshare/(?P<id>\d+)/$', 'one.views.vm_unshare', ),
url(r'^vm/resume/(?P<iid>\d+)/$', 'one.views.vm_resume', ),
url(r'^vm/power_off/(?P<iid>\d+)/$', 'one.views.vm_power_off', ),
url(r'^vm/restart/(?P<iid>\d+)/$', 'one.views.vm_restart', ),
url(r'^vm/renew/(?P<which>(suspend|delete))/(?P<iid>\d+)/$',
'one.views.vm_renew', name='vm_renew'),
url(r'^vm/port_add/(?P<iid>\d+)/$', 'one.views.vm_port_add',
name='vm_port_add'),
'one.views.vm_renew', ),
url(r'^vm/port_add/(?P<iid>\d+)/$', 'one.views.vm_port_add', ),
url(r'^vm/port_del/(?P<iid>\d+)/(?P<proto>tcp|udp)/(?P<public>\d+)/$',
'one.views.vm_port_del', name='vm_port_del'),
url(r'^vm/saveas/(?P<vmid>\d+)$', 'one.views.vm_saveas',
name='vm_saveas'),
url(r'^vm/credentials/(?P<iid>\d+)$', 'one.views.vm_credentials',
name='vm_credentials'),
url(r'^reload/$', 'firewall.views.reload_firewall',
name='reload_firewall'),
url(r'^fwapi/$', 'firewall.views.firewall_api',
name='firewall_api'),
url(r'^store/$', 'store.views.index', name='store_index'),
url(r'^store/gui/$', 'store.views.gui', name='store_gui'),
url(r'^store/top/$', 'store.views.toplist', name='store_top'),
url(r'^ajax/store/top/$', 'store.views.ajax_toplist',
name='axat_store_top'),
url(r'^ajax/templateWizard$', 'one.views.ajax_template_wizard',
name='ajax_template_wizard'),
url(r'^ajax/share/(?P<id>\d+)/$', 'one.views.ajax_share_wizard',
name='ajax_share_wizard'),
'one.views.vm_port_del', ),
url(r'^ajax/shareEdit/(?P<id>\d+)/$', 'one.views.ajax_share_edit_wizard',
name='ajax_share_edit_wizard'),
url(r'^vm/saveas/(?P<vmid>\d+)$', 'one.views.vm_saveas', ),
url(r'^vm/credentials/(?P<iid>\d+)$', 'one.views.vm_credentials', ),
url(r'^ajax/templateWizard/$', 'one.views.ajax_template_wizard', ),
url(r'^ajax/templateEditWizard/(?P<id>\d+)/$', 'one.views.ajax_template_edit_wizard', ),
url(r'^ajax/share/(?P<id>\d+)/$', 'one.views.ajax_share_wizard', ),
url(r'^ajax/share/(?P<id>\d+)/(?P<gid>\d+)$',
'one.views.ajax_share_wizard', name='ajax_share_wizard'),
url(r'^ajax/template/delete/$', 'one.views.ajax_template_delete',
name='ajax_template_delete'),
url(r'^ajax/template_name_unique/(?P<name>.*)$',
'one.views.ajax_template_name_unique',
name='ajax_template_name_unique'),
url(r'^ajax/store/list$', 'store.views.ajax_listfolder',
name='store_ajax_listfolder'),
url(r'^ajax/store/download$', 'store.views.ajax_download',
name='store_ajax_download'),
url(r'^ajax/store/upload$', 'store.views.ajax_upload',
name='store_ajax_upload'),
url(r'^ajax/store/delete$', 'store.views.ajax_delete',
name='store_ajax_delete'),
url(r'^ajax/store/newFolder$', 'store.views.ajax_new_folder',
name='store_ajax_new_folder'),
url(r'^ajax/store/quota$', 'store.views.ajax_quota',
name='store_ajax_quota'),
url(r'^ajax/store/rename$', 'store.views.ajax_rename',
name='store_ajax_rename'),
'one.views.ajax_share_wizard', ),
url(r'^ajax/vm/status/(?P<iid>\d+)$',
'one.views.vm_ajax_instance_status',
name='vm_ajax_instance_status'),
'one.views.vm_ajax_instance_status', ),
url(r'^ajax/vm/rename/(?P<iid>\d+)/$',
'one.views.vm_ajax_rename',
name='vm_ajax_rename'),
url(r'^language/(?P<lang>[-A-Za-z]+)/$', 'school.views.language',
name='language'),
url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
url(r'^b/(?P<token>.*)/$', 'one.views.boot_token', name='boot_token'),
'one.views.vm_ajax_rename', ),
url(r'^key/add/$', 'one.views.key_add', ),
url(r'^ajax/key/delete/$', 'one.views.key_ajax_delete', ),
url(r'^ajax/key/reset/$', 'one.views.key_ajax_reset', ),
url(r'^ajax/template/delete/$', 'one.views.ajax_template_delete', ),
url(r'^ajax/template_name_unique/$',
'one.views.ajax_template_name_unique', ),
url(r'^reload/$', 'firewall.views.reload_firewall', ),
url(r'^fwapi/$', 'firewall.views.firewall_api', ),
url(r'^store/$', 'store.views.index', ),
url(r'^store/gui/$', 'store.views.gui', ),
url(r'^store/top/$', 'store.views.toplist', ),
url(r'^ajax/store/top/$', 'store.views.ajax_toplist', ),
url(r'^ajax/store/list$', 'store.views.ajax_listfolder', ),
url(r'^ajax/store/download$', 'store.views.ajax_download', ),
url(r'^ajax/store/upload$', 'store.views.ajax_upload', ),
url(r'^ajax/store/delete$', 'store.views.ajax_delete', ),
url(r'^ajax/store/newFolder$', 'store.views.ajax_new_folder', ),
url(r'^ajax/store/quota$', 'store.views.ajax_quota', ),
url(r'^ajax/store/rename$', 'store.views.ajax_rename', ),
url(r'^language/(?P<lang>[-A-Za-z]+)/$', 'school.views.language', ),
url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict, ),
url(r'^b/(?P<token>.*)/$', 'one.views.boot_token', ),
url(r'^group/show/(?P<gid>\d+)/$', 'school.views.group_show',
name='group_show'),
url(r'^group/new/$', 'school.views.group_new', name='group_new'),
name='group_show'),
url(r'^group/new/$', 'school.views.group_new', ),
url(r'^ajax/group/(?P<gid>\d+)/add/$',
'school.views.group_ajax_add_new_member',
name='group_ajax_add_new_member'),
'school.views.group_ajax_add_new_member', ),
url(r'^ajax/group/(?P<gid>\d+)/addOwner/$',
'school.views.group_ajax_add_new_owner',
name='group_ajax_add_new_owner'),
'school.views.group_ajax_add_new_owner', ),
url(r'^ajax/group/(?P<gid>\d+)/remove/$',
'school.views.group_ajax_remove_member',
name='group_ajax_remove_member'),
url(r'^ajax/group/delete/$', 'school.views.group_ajax_delete',
name='group_ajax_delete'),
url(r'^ajax/group/autocomplete/$', 'school.views.group_ajax_owner_autocomplete',
name='group_ajax_autocomplete'),
url(r'^key/add/$', 'one.views.key_add', name='key_add'),
url(r'^ajax/key/delete/$', 'one.views.key_ajax_delete',
name='key_ajax_delete'),
url(r'^ajax/key/reset/$', 'one.views.key_ajax_reset',
name='key_ajax_reset'),
'school.views.group_ajax_remove_member', ),
url(r'^ajax/group/delete/$', 'school.views.group_ajax_delete', ),
url(r'^ajax/group/autocomplete/$',
'school.views.group_ajax_owner_autocomplete', ),
url(r'^stat/$', 'one.views.stat'),
url(r'^sites/(?P<site>[a-zA-Z0-9]+)/$', 'one.views.sites'),
url(r'^accounts/(?P<site>profile)/$', 'one.views.sites'),
)
......@@ -13,7 +13,7 @@ class RecordInline(contrib.admin.TabularInline):
class HostAdmin(admin.ModelAdmin):
list_display = ('hostname', 'vlan', 'ipv4', 'ipv6', 'pub_ipv4', 'mac',
'shared_ip', 'owner', 'description', 'reverse', 'groups_l')
'shared_ip', 'owner', 'description', 'reverse', 'list_groups')
ordering = ('hostname', )
list_filter = ('owner', 'vlan', 'groups')
search_fields = ('hostname', 'description', 'ipv4', 'ipv6', 'mac')
......@@ -21,7 +21,7 @@ class HostAdmin(admin.ModelAdmin):
inlines = (RuleInline, RecordInline)
@staticmethod
def groups_l(instance):
def list_groups(instance):
"""Returns instance's groups' names as a comma-separated list."""
names = [group.name for group in instance.groups.all()]
return u', '.join(names)
......@@ -45,34 +45,36 @@ class RuleAdmin(admin.ModelAdmin):
def color_desc(self, instance):
"""Returns a colorful description of the instance."""
para = '</span>'
if instance.dport:
para = 'dport=%s %s' % (instance.dport, para)
if instance.sport:
para = 'sport=%s %s' % (instance.sport, para)
if instance.proto:
para = 'proto=%s %s' % (instance.proto, para)
para = u'<span style="color: #00FF00;">' + para
return (
u'<span style="color: #FF0000;">[%s]</span> ' % instance.r_type +
(u'%s<span style="color: #0000FF;"> ▸ </span>%s' %
((instance.foreign_network.name, instance.r_type)
if instance.direction == '1' else
(instance.r_type, instance.foreign_network.name))) +
' ' + para + ' ' + instance.description)
return (u'<span style="color: #FF0000;">[%(type)s]</span> '
u'%(src)s<span style="color: #0000FF;"> ▸ </span>%(dst)s '
u'%(para)s %(desc)s') % {
'type': instance.r_type,
'src': (instance.foreign_network.name
if instance.direction == '1' else instance.r_type),
'dst': (instance.r_type if instance.direction == '1'
else instance.foreign_network.name),
'para': (u'<span style="color: #00FF00;">' +
(('proto=%s ' % instance.proto)
if instance.proto else '') +
(('sport=%s ' % instance.sport)
if instance.sport else '') +
(('dport=%s ' % instance.dport)
if instance.dport else '') +
'</span>'),
'desc': instance.description}
color_desc.allow_tags = True
def vlan_l(self, instance):
@staticmethod
def vlan_l(instance):
"""Returns instance's VLANs' names as a comma-separated list."""
retval = []
for vlan in instance.foreign_network.vlans.all():
retval.append(vlan.name)
return u', '.join(retval)
names = [vlan.name for vlan in instance.foreign_network.vlans.all()]
return u', '.join(names)
def used_in(self, instance):
@staticmethod
def used_in(instance):
for field in [instance.vlan, instance.vlangroup, instance.host,
instance.hostgroup, instance.firewall]:
if field is not None:
if field:
return unicode(field) + ' ' + field._meta.object_name
......@@ -92,15 +94,15 @@ class DomainAdmin(admin.ModelAdmin):
class RecordAdmin(admin.ModelAdmin):
list_display = ('name_', 'type', 'address_', 'ttl', 'host', 'owner')
def address_(self, instance):
@staticmethod
def address_(instance):
a = instance.get_data()
if a:
return a['address']
return a['address'] if a else None
def name_(self, instance):
@staticmethod
def name_(instance):
a = instance.get_data()
if a:
return a['name']
return a['name'] if a else None
class BlacklistAdmin(admin.ModelAdmin):
list_display = ('ipv4', 'reason', 'created_at', 'modified_at')
......
......@@ -2,6 +2,7 @@ from django.core.exceptions import ValidationError
from django.forms import fields
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.ipv6 import is_valid_ipv6_address
from south.modelsinspector import add_introspection_rules
import re
......@@ -35,26 +36,46 @@ class MACAddressField(models.Field):
add_introspection_rules([], ["firewall\.fields\.MACAddressField"])
def val_alfanum(value):
"""Check whether the parameter is a valid alphanumeric value."""
if alfanum_re.search(value) is None:
raise ValidationError(
_(u'%s - only letters, numbers, underscores and hyphens are '
'allowed!') % value)
"""Validate whether the parameter is a valid alphanumeric value."""
if not alfanum_re.match(value):
raise ValidationError(_(u'%s - only letters, numbers, underscores '
'and hyphens are allowed!') % value)
def is_valid_domain(value):
"""Check whether the parameter is a valid domain name."""
return domain_re.match(value) is not None
def val_domain(value):
"""Check wheter the parameter is a valid domin."""
if domain_re.search(value) is None:
raise ValidationError(_(u'%s - invalid domain') % value)
"""Validate whether the parameter is a valid domin name."""
if not is_valid_domain(value):
raise ValidationError(_(u'%s - invalid domain name') % value)
def is_valid_reverse_domain(value):
"""Check whether the parameter is a valid reverse domain name."""
return reverse_domain_re.match(value) is not None
def val_reverse_domain(value):
"""Check whether the parameter is a valid reverse domain."""
if not reverse_domain_re.search(value):
raise ValidationError(u'%s - reverse domain' % value)
"""Validate whether the parameter is a valid reverse domain name."""
if not is_valid_reverse_domain(value):
raise ValidationError(u'%s - invalid reverse domain name' % value)
def is_valid_ipv4_address(value):
"""Check whether the parameter is a valid IPv4 address."""
return ipv4_re.match(value) is not None
def val_ipv4(value):
"""Validate whether the parameter is a valid IPv4 address."""
if not is_valid_ipv4_address(value):
raise ValidationError(_(u'%s - not an IPv4 address') % value)
def val_ipv6(value):
"""Validate whether the parameter is a valid IPv6 address."""
if not is_valid_ipv6_address(value):
raise ValidationError(_(u'%s - not an IPv6 address') % value)
def ipv4_2_ipv6(ipv4):
"""Convert IPv4 address string to IPv6 address string."""
val_ipv4(ipv4)
m = ipv4_re.match(ipv4)
if m is None:
raise ValidationError(_(u'%s - not an IPv4 address') % ipv4)
return ("2001:738:2001:4031:%s:%s:%s:0" %
(m.group(1), m.group(2), m.group(3)))
......@@ -10,7 +10,7 @@ from datetime import datetime, timedelta
from django.db.models import Q
class firewall:
class Firewall:
IPV6=False
RULES = None
RULES_NAT = []
......@@ -36,14 +36,15 @@ class firewall:
def iptables(self, s):
"""Append rule."""
"""Append rule to filter table."""
self.RULES.append(s)
def iptablesnat(self, s):
"""Append rule to NAT table."""
self.RULES_NAT.append(s)
def host2vlan(self, host, rule):
if rule.foreign_network is None:
if not rule.foreign_network:
return
if self.IPV6 and host.ipv6:
......@@ -76,7 +77,7 @@ class firewall:
def fw2vlan(self, rule):
if rule.foreign_network is None:
if not rule.foreign_network:
return
dport_sport = self.dportsport(rule)
......@@ -92,7 +93,7 @@ class firewall:
'LOG_ACC' if rule.accept else 'LOG_DROP'))
def vlan2vlan(self, l_vlan, rule):
if rule.foreign_network is None:
if not rule.foreign_network:
return
dport_sport = self.dportsport(rule)
......
......@@ -19,44 +19,47 @@ def reload_dhcp_task(data):