Commit 08e83ca6 by Őry Máté

network-gui: merge from network-gui

parent 43391a3d
......@@ -218,8 +218,9 @@ DJANGO_APPS = (
)
THIRD_PARTY_APPS = (
# Database migration helpers:
'south',
'django_tables2',
'crispy_forms',
)
# Apps specific for this project go here.
......@@ -227,6 +228,7 @@ LOCAL_APPS = (
'vm',
'storage',
'firewall',
'network',
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
......@@ -287,3 +289,5 @@ WSGI_APPLICATION = '%s.wsgi.application' % SITE_NAME
########## END WSGI CONFIGURATION
FIREWALL_SETTINGS = loads(get_env_variable('DJANGO_FIREWALL_SETTINGS'))
CRISPY_TEMPLATE_PACK = 'bootstrap3'
......@@ -14,4 +14,5 @@ urlpatterns = patterns('',
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^network/', include('network.urls')),
)
from django.forms import ModelForm
from django.core.urlresolvers import reverse_lazy
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Fieldset, Div, Submit, BaseInput
from crispy_forms.bootstrap import FormActions
from firewall.models import (Host, Vlan, Domain, Group, Record, Blacklist,
Rule, VlanGroup)
class LinkButton(BaseInput):
"""
Used to create a link button descriptor for the {% crispy %} template tag::
back = LinkButton('back', 'Back', reverse_lazy('index'))
.. note:: The first argument is also slugified and turned into the id for
the submit button.
"""
template = "bootstrap/layout/linkbutton.html"
field_classes = 'btn btn-default'
def __init__(self, name, text, url, *args, **kwargs):
self.href = url
super(LinkButton, self).__init__(name, text, *args, **kwargs)
class BlacklistForm(ModelForm):
helper = FormHelper()
helper.layout = Layout(
Div(
Fieldset(
'',
'ipv4',
'host',
'reason',
'type',
)
),
FormActions(
Submit('submit', 'Save changes'),
LinkButton('back', 'Back', reverse_lazy('network.blacklist_list'))
)
)
class Meta:
model = Blacklist
class DomainForm(ModelForm):
helper = FormHelper()
helper.layout = Layout(
Div(
Fieldset(
'',
'name',
'owner',
'ttl',
),
),
FormActions(
Submit('submit', 'Save'),
LinkButton('back', 'Back', reverse_lazy('network.domain_list'))
)
)
class Meta:
model = Domain
class GroupForm(ModelForm):
helper = FormHelper()
helper.layout = Layout(
Div(
Fieldset(
'Identity',
'name',
'description',
'owner',
),
),
FormActions(
Submit('submit', 'Save'),
LinkButton('back', 'Back', reverse_lazy('network.group_list'))
)
)
class Meta:
model = Group
class HostForm(ModelForm):
helper = FormHelper()
helper.layout = Layout(
Div(
Fieldset(
'Identity',
'hostname',
'reverse',
'mac',
),
Fieldset(
'Network',
'vlan',
'ipv4',
'ipv6',
'shared_ip',
'pub_ipv4',
),
Fieldset(
'Information',
'description',
'location',
'comment',
'owner',
),
),
FormActions(
Submit('submit', 'Save'),
LinkButton('back', 'Back', reverse_lazy('network.host_list')))
)
class Meta:
model = Host
class RecordForm(ModelForm):
helper = FormHelper()
helper.layout = Layout(
Div(
Fieldset(
'',
'type',
'host',
'name',
'domain',
'address',
'ttl',
'description',
'owner',
)
),
FormActions(
Submit('submit', 'Save'),
LinkButton('back', 'Back', reverse_lazy('network.record_list'))
)
)
class Meta:
model = Record
class RuleForm(ModelForm):
helper = FormHelper()
helper.layout = Layout(
Div(
Fieldset(
'Identity',
'direction',
'description',
'foreign_network',
'dport',
'sport',
'proto',
'extra',
'accept',
'owner',
'r_type',
'nat',
'nat_dport',
),
Fieldset(
'External',
'vlan',
'vlangroup',
'host',
'hostgroup',
'firewall'
)
),
FormActions(
Submit('submit', 'Save'),
LinkButton('back', 'Back', reverse_lazy('network.rule_list'))
)
)
class Meta:
model = Rule
class VlanForm(ModelForm):
helper = FormHelper()
helper.layout = Layout(
Div(
Fieldset(
'Identity',
'name',
'vid',
'interface',
),
Fieldset(
'IPv4',
'net4',
'prefix4',
'ipv4',
'snat_to',
'snat_ip',
'dhcp_pool',
),
Fieldset(
'IPv6',
'net6',
'prefix6',
'ipv6',
),
Fieldset(
'Domain name service',
'domain',
'reverse_domain',
),
Fieldset(
'Info',
'description',
'comment',
# 'created_at',
# 'modified_at',
),
),
FormActions(
Submit('submit', 'Save'),
LinkButton('back', 'Back', reverse_lazy('network.vlan_list'))
)
)
class Meta:
model = Vlan
class VlanGroupForm(ModelForm):
helper = FormHelper()
helper.layout = Layout(
Div(
Fieldset(
'',
'name',
'vlans',
'description',
'owner',
)
),
FormActions(
Submit('submit', 'Save'),
LinkButton('back', 'Back', reverse_lazy(
'network.vlan_group_list'))
)
)
class Meta:
model = VlanGroup
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-08-21 12:29+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: static/js/record-create.js:108
msgid "Address must be specified!"
msgstr ""
#: static/js/record-create.js:118
#, c-format
msgid "%s - not an IPv4 address"
msgstr "%s - nem egy IPv4 cím"
#: static/js/record-create.js:128
#, c-format
msgid "%s - not an IPv6 address"
msgstr ""
#: static/js/record-create.js:139
msgid "Bad MX address format. "
msgstr ""
#: static/js/record-create.js:150 static/js/record-create.js.c:178
#, c-format
msgid "%s - invalid domain name"
msgstr ""
#: static/js/record-create.js:160
msgid "Unknown record type."
msgstr ""
#: static/js/record-create.js:168 static/js/record-create.js.c:287
msgid "You must choose a type"
msgstr ""
#: static/js/record-create.js:188
msgid "You must choose a domain"
msgstr ""
#: static/js/record-create.js:195
msgid "You must specify an owner!"
msgstr ""
#: static/js/record-create.js:271
msgid "Specify a type!"
msgstr ""
from django.db import models
# Create your models here.
/**
* bootbox.js v3.3.0
*
* http://bootboxjs.com/license.txt
*/
var bootbox=window.bootbox||function(a,b){function c(a,b){return"undefined"==typeof b&&(b=d),"string"==typeof m[b][a]?m[b][a]:b!=e?c(a,e):a}var d="en",e="en",f=!0,g="static",h="javascript:;",i="",j={},k={},l={};l.setLocale=function(a){for(var b in m)if(b==a)return d=a,void 0;throw new Error("Invalid locale: "+a)},l.addLocale=function(a,b){"undefined"==typeof m[a]&&(m[a]={});for(var c in b)m[a][c]=b[c]},l.setIcons=function(a){k=a,("object"!=typeof k||null===k)&&(k={})},l.setBtnClasses=function(a){j=a,("object"!=typeof j||null===j)&&(j={})},l.alert=function(){var a="",b=c("OK"),d=null;switch(arguments.length){case 1:a=arguments[0];break;case 2:a=arguments[0],"function"==typeof arguments[1]?d=arguments[1]:b=arguments[1];break;case 3:a=arguments[0],b=arguments[1],d=arguments[2];break;default:throw new Error("Incorrect number of arguments: expected 1-3")}return l.dialog(a,{label:b,icon:k.OK,"class":j.OK,callback:d},{onEscape:d||!0})},l.confirm=function(){var a="",b=c("CANCEL"),d=c("CONFIRM"),e=null;switch(arguments.length){case 1:a=arguments[0];break;case 2:a=arguments[0],"function"==typeof arguments[1]?e=arguments[1]:b=arguments[1];break;case 3:a=arguments[0],b=arguments[1],"function"==typeof arguments[2]?e=arguments[2]:d=arguments[2];break;case 4:a=arguments[0],b=arguments[1],d=arguments[2],e=arguments[3];break;default:throw new Error("Incorrect number of arguments: expected 1-4")}var f=function(){return"function"==typeof e?e(!1):void 0},g=function(){return"function"==typeof e?e(!0):void 0};return l.dialog(a,[{label:b,icon:k.CANCEL,"class":j.CANCEL,callback:f},{label:d,icon:k.CONFIRM,"class":j.CONFIRM,callback:g}],{onEscape:f})},l.prompt=function(){var a="",d=c("CANCEL"),e=c("CONFIRM"),f=null,g="";switch(arguments.length){case 1:a=arguments[0];break;case 2:a=arguments[0],"function"==typeof arguments[1]?f=arguments[1]:d=arguments[1];break;case 3:a=arguments[0],d=arguments[1],"function"==typeof arguments[2]?f=arguments[2]:e=arguments[2];break;case 4:a=arguments[0],d=arguments[1],e=arguments[2],f=arguments[3];break;case 5:a=arguments[0],d=arguments[1],e=arguments[2],f=arguments[3],g=arguments[4];break;default:throw new Error("Incorrect number of arguments: expected 1-5")}var h=a,i=b("<form></form>");i.append("<input class='input-block-level' autocomplete=off type=text value='"+g+"' />");var m=function(){return"function"==typeof f?f(null):void 0},n=function(){return"function"==typeof f?f(i.find("input[type=text]").val()):void 0},o=l.dialog(i,[{label:d,icon:k.CANCEL,"class":j.CANCEL,callback:m},{label:e,icon:k.CONFIRM,"class":j.CONFIRM,callback:n}],{header:h,show:!1,onEscape:m});return o.on("shown",function(){i.find("input[type=text]").focus(),i.on("submit",function(a){a.preventDefault(),o.find(".btn-primary").click()})}),o.modal("show"),o},l.dialog=function(c,d,e){function j(){var a=null;"function"==typeof e.onEscape&&(a=e.onEscape()),a!==!1&&x.modal("hide")}var k="",l=[];e||(e={}),"undefined"==typeof d?d=[]:"undefined"==typeof d.length&&(d=[d]);for(var m=d.length;m--;){var n=null,o=null,p=null,q="",r=null;if("undefined"==typeof d[m].label&&"undefined"==typeof d[m]["class"]&&"undefined"==typeof d[m].callback){var s=0,t=null;for(var u in d[m])if(t=u,++s>1)break;1==s&&"function"==typeof d[m][u]&&(d[m].label=t,d[m].callback=d[m][u])}"function"==typeof d[m].callback&&(r=d[m].callback),d[m]["class"]?p=d[m]["class"]:m==d.length-1&&d.length<=2&&(p="btn-primary"),d[m].link!==!0&&(p="btn "+p),n=d[m].label?d[m].label:"Option "+(m+1),d[m].icon&&(q="<i class='"+d[m].icon+"'></i> "),o=d[m].href?d[m].href:h,k="<a data-handler='"+m+"' class='"+p+"' href='"+o+"'>"+q+n+"</a>"+k,l[m]=r}var v=["<div class='bootbox modal' tabindex='-1' style='overflow:hidden;'>"];if(e.header){var w="";("undefined"==typeof e.headerCloseButton||e.headerCloseButton)&&(w="<a href='"+h+"' class='close'>&times;</a>"),v.push("<div class='modal-header'>"+w+"<h3>"+e.header+"</h3></div>")}v.push("<div class='modal-body'></div>"),k&&v.push("<div class='modal-footer'>"+k+"</div>"),v.push("</div>");var x=b(v.join("\n")),y="undefined"==typeof e.animate?f:e.animate;y&&x.addClass("fade");var z="undefined"==typeof e.classes?i:e.classes;return z&&x.addClass(z),x.find(".modal-body").html(c),x.on("keyup.dismiss.modal",function(a){27===a.which&&e.onEscape&&j("escape")}),x.on("click","a.close",function(a){a.preventDefault(),j("close")}),x.on("shown",function(){x.find("a.btn-primary:first").focus()}),x.on("hidden",function(a){a.target===this&&x.remove()}),x.on("click",".modal-footer a",function(a){var c=b(this).data("handler"),e=l[c],f=null;("undefined"==typeof c||"undefined"==typeof d[c].href)&&(a.preventDefault(),"function"==typeof e&&(f=e(a)),f!==!1&&x.modal("hide"))}),b("body").append(x),x.modal({backdrop:"undefined"==typeof e.backdrop?g:e.backdrop,keyboard:!1,show:!1}),x.on("show",function(){b(a).off("focusin.modal")}),("undefined"==typeof e.show||e.show===!0)&&x.modal("show"),x},l.modal=function(){var a,c,d,e={onEscape:null,keyboard:!0,backdrop:g};switch(arguments.length){case 1:a=arguments[0];break;case 2:a=arguments[0],"object"==typeof arguments[1]?d=arguments[1]:c=arguments[1];break;case 3:a=arguments[0],c=arguments[1],d=arguments[2];break;default:throw new Error("Incorrect number of arguments: expected 1-3")}return e.header=c,d="object"==typeof d?b.extend(e,d):e,l.dialog(a,[],d)},l.hideAll=function(){b(".bootbox").modal("hide")},l.animate=function(a){f=a},l.backdrop=function(a){g=a},l.classes=function(a){i=a};var m={br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return l}(document,window.jQuery);window.bootbox=bootbox;
\ No newline at end of file
$('i[class="icon-remove"]').click(function() {
href = $(this).parent('a').attr('href');
csrf = getCookie('csrftoken');
var click_this = this;
bootbox.dialog("Are you sure?", [
{
"label": "Cancel",
"class": "btn-info",
"callback": function () {}
},
{
"label": "Remove",
"class": "btn-danger",
"callback": function() {
delete_rule_or_group(click_this);
}
}
]);
return false;
});
function delete_rule_or_group(click_this) {
ajax = $.ajax({
type: 'POST',
url: href,
headers: {"X-CSRFToken": csrf},
context: click_this,
success: function(data, textStatus, xhr) {
if(xhr.status == 200) {
// we delete a row in a table
if(href.indexOf("rules") != -1) {
$(this).closest('tr').fadeOut(500, function() {
$(this).remove();
});
}
// we delete the whole div around the table
else {
// we need to readd the deleted group to the select
group_pk = parseInt($(this).closest('h4').attr('id'));
group_name = $(this).closest('h4').text();
$(this).closest('div').fadeOut(500, function() {
$(this).remove();
$('#add_group')
.append($("<option></option>")
.attr('value', group_pk)
.text(group_name));
});
}
}
}
});
return false;
}
/**
* Getter for user cookies
* @param {String} name Cookie name
* @return {String} Cookie value
*/
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
Copyright 2012 Igor Vaynberg
Version: @@ver@@ Timestamp: @@timestamp@@
This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
General Public License version 2 (the "GPL License"). You may choose either license to govern your
use of this software only upon the condition that you accept all of the terms of either the Apache
License or the GPL License.
You may obtain a copy of the Apache License and the GPL License at:
http://www.apache.org/licenses/LICENSE-2.0
http://www.gnu.org/licenses/gpl-2.0.html
Unless required by applicable law or agreed to in writing, software distributed under the Apache License
or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the Apache License and the GPL License for the specific language governing
permissions and limitations under the Apache License and the GPL License.
\ No newline at end of file
Select2
=================
Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.
To get started checkout examples and documentation at http://ivaynberg.github.com/select2
What Usecases Does Select2 Support
-------------------------------------------------
* Enhances native selects with search
* Enhances native selects with a better multi-select interface
* Loading data from javascript: easily load items via ajax and have them searchable
* Nested optgroups: native selects only support one level of nested, Select2 does not have this restriction
* Tagging: ability to add new items on the fly
* Working with large remote datesets: ability to partially load a dataset based on the search term
* Paging of large datasets: easy support for loading more pages when the results are scrolled to the end
* Templating: support for custom rendering of results and selections
Browser Compatibility
--------------------
* IE 8+ (7 mostly works except for [issue with z-index](https://github.com/ivaynberg/select2/issues/37))
* Chrome 8+
* Firefox 3.5+
* Safari 3+
* Opera 10.6+
Integrations
------------
* [Wicket-Select2](https://github.com/ivaynberg/wicket-select2) (Java / [Apache Wicket](http://wicket.apache.org))
* [select2-rails](https://github.com/argerim/select2-rails) (Ruby on Rails)
* [AngularUI](http://angular-ui.github.com/#directives-select2) ([AngularJS](angularjs.org))
* [Django](https://github.com/applegrew/django-select2)
* [Symfony](https://github.com/19Gerhard85/sfSelect2WidgetsPlugin)
* [Bootstrap](https://github.com/t0m/select2-bootstrap-css) (CSS skin)
* [Yii](https://github.com/tonybolzan/yii-select2)
Internationalization (i18n)
---------------------------
Select2 supports multiple languages by simply including the right
language JS file (`select2_locale_it.js`, `select2_locale_nl.js` etc.).
Missing a language? Just copy `select2_locale_en.js.template`, translate
it and make a pull request back to Select2 here on Github.
Bug tracker
-----------
Have a bug? Please create an issue here on GitHub!
https://github.com/ivaynberg/select2/issues
Mailing list
------------
Have a question? Ask on our mailing list!
select2@googlegroups.com
https://groups.google.com/d/forum/select2
Copyright and License
---------------------
Copyright 2012 Igor Vaynberg
This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
General Public License version 2 (the "GPL License"). You may choose either license to govern your
use of this software only upon the condition that you accept all of the terms of either the Apache
License or the GPL License.
You may obtain a copy of the Apache License and the GPL License in the LICENSE file, or at:
http://www.apache.org/licenses/LICENSE-2.0
http://www.gnu.org/licenses/gpl-2.0.html
Unless required by applicable law or agreed to in writing, software distributed under the Apache License
or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the Apache License and the GPL License for the specific language governing
permissions and limitations under the Apache License and the GPL License.
{
"name": "select2",
"version": "3.4.0",
"main": ["select2.js", "select2.css", "select2.png", "select2x2.png", "select2-spinner.gif"],
"dependencies": {
"jquery": ">= 1.7.1"
}
}
#!/bin/bash
set -e
echo -n "Enter the version for this release: "
read ver
if [ ! $ver ]; then
echo "Invalid version."
exit
fi
name="select2"
js="$name.js"
mini="$name.min.js"
css="$name.css"
release="$name-$ver"
tag="$ver"
branch="build-$ver"
curbranch=`git branch | grep "*" | sed "s/* //"`
timestamp=$(date)
tokens="s/@@ver@@/$ver/g;s/\@@timestamp@@/$timestamp/g"
remote="github"
echo "Updating Version Identifiers"
sed -E -e "s/\"version\": \"([0-9\.]+)\",/\"version\": \"$ver\",/g" -i "" component.json select2.jquery.json
git add component.json
git add select2.jquery.json
git commit -m "modified version identifiers in descriptors for release $ver"
git push
git branch "$branch"
git checkout "$branch"
echo "Tokenizing..."
find . -name "$js" | xargs -I{} sed -e "$tokens" -i "" {}
find . -name "$css" | xargs -I{} sed -e "$tokens" -i "" {}
sed -e "s/latest/$ver/g" -i "" component.json
git add "$js"
git add "$css"
echo "Minifying..."
echo "/*" > "$mini"
cat LICENSE | sed "$tokens" >> "$mini"
echo "*/" >> "$mini"
curl -s \
--data-urlencode "js_code@$js" \
http://marijnhaverbeke.nl/uglifyjs \
>> "$mini"
git add "$mini"
git commit -m "release $ver"
echo "Tagging..."
git tag -a "$tag" -m "tagged version $ver"
git push "$remote" --tags
echo "Cleaning Up..."
git checkout "$curbranch"
git branch -D "$branch"
echo "Done"
{
"name": "select2",
"title": "Select2",
"description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.",
"keywords": [
"select",
"autocomplete",
"typeahead",
"dropdown",
"multiselect",
"tag",
"tagging"
],
"version": "3.4.0",
"author": {
"name": "Igor Vaynberg",
"url": "https://github.com/ivaynberg"
},
"licenses": [
{
"type": "Apache",
"url": "http://www.apache.org/licenses/LICENSE-2.0"
},
{
"type": "GPL v2",
"url": "http://www.gnu.org/licenses/gpl-2.0.html"
}
],
"bugs": "https://github.com/ivaynberg/select2/issues",
"homepage": "http://ivaynberg.github.com/select2",
"docs": "http://ivaynberg.github.com/select2/",
"download": "https://github.com/ivaynberg/select2/tags",
"dependencies": {
"jquery": ">=1.7.1"
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* Select2 Catalan translation.
*
* Author: David Planella <david.planella@gmail.com>
*/
(function ($) {
"use strict";
$.extend($.fn.select2.defaults, {
formatNoMatches: function () { return "No s'ha trobat cap coincidència"; },
formatInputTooShort: function (input, min) { var n = min - input.length; return "Introduïu " + n + " caràcter" + (n == 1 ? "" : "s") + " més"; },
formatInputTooLong: function (input, max) { var n = input.length - max; return "Introduïu " + n + " caràcter" + (n == 1? "" : "s") + "menys"; },
formatSelectionTooBig: function (limit) { return "Només podeu seleccionar " + limit + " element" + (limit == 1 ? "" : "s"); },
formatLoadMore: function (pageNumber) { return "S'estan carregant més resultats..."; },
formatSearching: function () { return "S'està cercant..."; }
});
})(jQuery);