Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gyuricska Milán
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
ca137eda
authored
Nov 17, 2014
by
Bach Dániel
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master' into feature-management-commands
parents
bad4afd4
1ca7edbb
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
462 additions
and
117 deletions
+462
-117
circle/dashboard/static/dashboard/dashboard.js
+3
-3
circle/dashboard/templates/dashboard/base.html
+1
-0
circle/dashboard/templates/dashboard/index.html
+7
-0
circle/dashboard/templates/dashboard/vm-opensearch.xml
+6
-0
circle/dashboard/urls.py
+3
-0
circle/dashboard/views/index.py
+13
-0
circle/firewall/fields.py
+55
-19
circle/firewall/models.py
+133
-11
circle/firewall/tasks/remote_tasks.py
+2
-1
circle/firewall/tests/test_firewall.py
+4
-6
circle/locale/hu/LC_MESSAGES/django.po
+0
-0
circle/locale/hu/LC_MESSAGES/djangojs.po
+41
-51
circle/network/forms.py
+14
-5
circle/network/static/js/network.js
+43
-0
circle/network/tables.py
+32
-4
circle/network/templates/network/columns/host-register.html
+3
-0
circle/network/templates/network/columns/mac.html
+0
-3
circle/network/templates/network/vlan-edit.html
+7
-0
circle/network/views.py
+94
-14
circle/vm/tests/test_models.py
+1
-0
No files found.
circle/dashboard/static/dashboard/dashboard.js
View file @
ca137eda
...
@@ -108,9 +108,9 @@ $(function () {
...
@@ -108,9 +108,9 @@ $(function () {
e
.
stopImmediatePropagation
();
e
.
stopImmediatePropagation
();
return
false
;
return
false
;
});
});
$
(
'[title]:not(.title-favourite)'
).
tooltip
();
$
(
'
body
[title]:not(.title-favourite)'
).
tooltip
();
$
(
'.title-favourite'
).
tooltip
({
'placement'
:
'right'
});
$
(
'
body
.title-favourite'
).
tooltip
({
'placement'
:
'right'
});
$
(
':input[title]'
).
tooltip
({
trigger
:
'focus'
,
placement
:
'auto right'
});
$
(
'
body
:input[title]'
).
tooltip
({
trigger
:
'focus'
,
placement
:
'auto right'
});
$
(
".knob"
).
knob
();
$
(
".knob"
).
knob
();
$
(
'[data-toggle="pill"]'
).
click
(
function
()
{
$
(
'[data-toggle="pill"]'
).
click
(
function
()
{
...
...
circle/dashboard/templates/dashboard/base.html
View file @
ca137eda
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
<link
rel=
"stylesheet"
href=
"{{ STATIC_URL }}dashboard/loopj-jquery-simple-slider/css/simple-slider.css"
/>
<link
rel=
"stylesheet"
href=
"{{ STATIC_URL }}dashboard/loopj-jquery-simple-slider/css/simple-slider.css"
/>
<link
rel=
"stylesheet"
href=
"{{ STATIC_URL }}dashboard/introjs/introjs.min.css"
>
<link
rel=
"stylesheet"
href=
"{{ STATIC_URL }}dashboard/introjs/introjs.min.css"
>
<link
href=
"{{ STATIC_URL }}dashboard/dashboard.css"
rel=
"stylesheet"
>
<link
href=
"{{ STATIC_URL }}dashboard/dashboard.css"
rel=
"stylesheet"
>
{% block extra_link_2 %}{% endblock %}
{% endblock %}
{% endblock %}
...
...
circle/dashboard/templates/dashboard/index.html
View file @
ca137eda
...
@@ -3,6 +3,13 @@
...
@@ -3,6 +3,13 @@
{% block title-page %}{% trans "Index" %}{% endblock %}
{% block title-page %}{% trans "Index" %}{% endblock %}
{% block extra_link_2 %}
<link
rel=
"search"
type=
"application/opensearchdescription+xml"
href=
"{% url "
dashboard
.
views
.
vm-opensearch
"
%}"
title=
"{% blocktrans with name=COMPANY_NAME %}{{name}} virtual machines{% endblocktrans %}"
/>
{% endblock %}
{% block content %}
{% block content %}
<div
class=
"body-content dashboard-index"
>
<div
class=
"body-content dashboard-index"
>
<div
class=
"row"
>
<div
class=
"row"
>
...
...
circle/dashboard/templates/dashboard/vm-opensearch.xml
0 → 100644
View file @
ca137eda
{% load i18n %}
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription
xmlns=
"http://a9.com/-/spec/opensearch/1.1/"
>
<ShortName>
{% blocktrans with name=COMPANY_NAME %}{{name}} virtual machines{% endblocktrans %}
</ShortName>
<Url
type=
"text/html"
template=
"{{ url }}?s={searchTerms}&stype=shared"
/>
</OpenSearchDescription>
circle/dashboard/urls.py
View file @
ca137eda
...
@@ -50,6 +50,7 @@ from .views import (
...
@@ -50,6 +50,7 @@ from .views import (
VmGraphView
,
NodeGraphView
,
NodeListGraphView
,
VmGraphView
,
NodeGraphView
,
NodeListGraphView
,
TransferInstanceOwnershipView
,
TransferInstanceOwnershipConfirmView
,
TransferInstanceOwnershipView
,
TransferInstanceOwnershipConfirmView
,
TransferTemplateOwnershipView
,
TransferTemplateOwnershipConfirmView
,
TransferTemplateOwnershipView
,
TransferTemplateOwnershipConfirmView
,
OpenSearchDescriptionView
,
)
)
from
.views.vm
import
vm_ops
,
vm_mass_ops
from
.views.vm
import
vm_ops
,
vm_mass_ops
from
.views.node
import
node_ops
from
.views.node
import
node_ops
...
@@ -221,6 +222,8 @@ urlpatterns = patterns(
...
@@ -221,6 +222,8 @@ urlpatterns = patterns(
name
=
"dashboard.views.client-check"
),
name
=
"dashboard.views.client-check"
),
url
(
r'^token-login/(?P<token>.*)/$'
,
TokenLogin
.
as_view
(),
url
(
r'^token-login/(?P<token>.*)/$'
,
TokenLogin
.
as_view
(),
name
=
"dashboard.views.token-login"
),
name
=
"dashboard.views.token-login"
),
url
(
r'^vm/opensearch.xml$'
,
OpenSearchDescriptionView
.
as_view
(),
name
=
"dashboard.views.vm-opensearch"
),
)
)
urlpatterns
+=
patterns
(
urlpatterns
+=
patterns
(
...
...
circle/dashboard/views/index.py
View file @
ca137eda
...
@@ -19,6 +19,7 @@ from __future__ import unicode_literals, absolute_import
...
@@ -19,6 +19,7 @@ from __future__ import unicode_literals, absolute_import
import
logging
import
logging
from
django.core.cache
import
get_cache
from
django.core.cache
import
get_cache
from
django.core.urlresolvers
import
reverse
from
django.conf
import
settings
from
django.conf
import
settings
from
django.contrib.auth.models
import
Group
from
django.contrib.auth.models
import
Group
from
django.views.generic
import
TemplateView
from
django.views.generic
import
TemplateView
...
@@ -121,3 +122,15 @@ class HelpView(TemplateView):
...
@@ -121,3 +122,15 @@ class HelpView(TemplateView):
ctx
.
update
({
"saml"
:
hasattr
(
settings
,
"SAML_CONFIG"
),
ctx
.
update
({
"saml"
:
hasattr
(
settings
,
"SAML_CONFIG"
),
"store"
:
settings
.
STORE_URL
})
"store"
:
settings
.
STORE_URL
})
return
ctx
return
ctx
class
OpenSearchDescriptionView
(
TemplateView
):
template_name
=
"dashboard/vm-opensearch.xml"
content_type
=
"application/opensearchdescription+xml"
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
OpenSearchDescriptionView
,
self
)
.
get_context_data
(
**
kwargs
)
context
[
'url'
]
=
self
.
request
.
build_absolute_uri
(
reverse
(
"dashboard.views.vm-list"
))
return
context
circle/firewall/fields.py
View file @
ca137eda
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License along
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from
string
import
ascii_letters
from
django.core.exceptions
import
ValidationError
from
django.core.exceptions
import
ValidationError
from
django.db
import
models
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
...
@@ -22,7 +23,7 @@ from django.utils.ipv6 import is_valid_ipv6_address
...
@@ -22,7 +23,7 @@ from django.utils.ipv6 import is_valid_ipv6_address
from
south.modelsinspector
import
add_introspection_rules
from
south.modelsinspector
import
add_introspection_rules
from
django
import
forms
from
django
import
forms
from
netaddr
import
(
IPAddress
,
IPNetwork
,
AddrFormatError
,
ZEROFILL
,
from
netaddr
import
(
IPAddress
,
IPNetwork
,
AddrFormatError
,
ZEROFILL
,
EUI
,
mac_unix
)
EUI
,
mac_unix
,
AddrConversionError
)
import
re
import
re
...
@@ -31,7 +32,6 @@ domain_re = re.compile(r'^([A-Za-z0-9_-]\.?)+$')
...
@@ -31,7 +32,6 @@ domain_re = re.compile(r'^([A-Za-z0-9_-]\.?)+$')
domain_wildcard_re
=
re
.
compile
(
r'^(\*\.)?([A-Za-z0-9_-]\.?)+$'
)
domain_wildcard_re
=
re
.
compile
(
r'^(\*\.)?([A-Za-z0-9_-]\.?)+$'
)
ipv4_re
=
re
.
compile
(
'^([0-9]+)
\
.([0-9]+)
\
.([0-9]+)
\
.([0-9]+)$'
)
ipv4_re
=
re
.
compile
(
'^([0-9]+)
\
.([0-9]+)
\
.([0-9]+)
\
.([0-9]+)$'
)
reverse_domain_re
=
re
.
compile
(
r'^(
%
\([abcd]\)d|[a-z0-9.-])+$'
)
reverse_domain_re
=
re
.
compile
(
r'^(
%
\([abcd]\)d|[a-z0-9.-])+$'
)
ipv6_template_re
=
re
.
compile
(
r'^(
%
\([abcd]\)[dxX]|[A-Za-z0-9:-])+$'
)
class
mac_custom
(
mac_unix
):
class
mac_custom
(
mac_unix
):
...
@@ -246,15 +246,60 @@ def val_reverse_domain(value):
...
@@ -246,15 +246,60 @@ def val_reverse_domain(value):
raise
ValidationError
(
u'
%
s - invalid reverse domain name'
%
value
)
raise
ValidationError
(
u'
%
s - invalid reverse domain name'
%
value
)
def
is_valid_ipv6_template
(
value
):
"""Check whether the parameter is a valid ipv6 template."""
return
ipv6_template_re
.
match
(
value
)
is
not
None
def
val_ipv6_template
(
value
):
def
val_ipv6_template
(
value
):
"""Validate whether the parameter is a valid ipv6 template."""
"""Validate whether the parameter is a valid ipv6 template.
if
not
is_valid_ipv6_template
(
value
):
raise
ValidationError
(
u'
%
s - invalid reverse ipv6 template'
%
value
)
Normal use:
>>> val_ipv6_template("123::
%(a)
d:
%(b)
d:
%(c)
d:
%(d)
d")
>>> val_ipv6_template("::
%(a)
x:
%(b)
x:
%(c)
d:
%(d)
d")
Don't have to use all bytes from the left (no a):
>>> val_ipv6_template("::
%(b)
x:
%(c)
d:
%(d)
d")
But have to use all ones to the right (a, but no b):
>>> val_ipv6_template("::
%(a)
x:
%(c)
d:
%(d)
d")
Traceback (most recent call last):
...
ValidationError: [u"template doesn't use parameter b"]
Detects valid templates building invalid ips:
>>> val_ipv6_template("xxx::
%(a)
d:
%(b)
d:
%(c)
d:
%(d)
d")
Traceback (most recent call last):
...
ValidationError: [u'template renders invalid IPv6 address']
Also IPv4-compatible addresses are invalid:
>>> val_ipv6_template("::
%(a)02
x
%(b)02
x:
%(c)
d:
%(d)
d")
Traceback (most recent call last):
...
ValidationError: [u'template results in IPv4 address']
"""
tpl
=
{
ascii_letters
[
i
]:
255
for
i
in
range
(
4
)}
try
:
v6
=
value
%
tpl
except
:
raise
ValidationError
(
_
(
'
%
s: invalid template'
)
%
value
)
used
=
False
for
i
in
ascii_letters
[:
4
]:
try
:
value
%
{
k
:
tpl
[
k
]
for
k
in
tpl
if
k
!=
i
}
except
KeyError
:
used
=
True
# ok, it misses this key
else
:
if
used
:
raise
ValidationError
(
_
(
"template doesn't use parameter
%
s"
)
%
i
)
try
:
v6
=
IPAddress
(
v6
,
6
)
except
:
raise
ValidationError
(
_
(
'template renders invalid IPv6 address'
))
try
:
v6
.
ipv4
()
except
(
AddrConversionError
,
AddrFormatError
):
pass
# can't converted to ipv4 == it's real ipv6
else
:
raise
ValidationError
(
_
(
'template results in IPv4 address'
))
def
is_valid_ipv4_address
(
value
):
def
is_valid_ipv4_address
(
value
):
...
@@ -284,12 +329,3 @@ def val_mx(value):
...
@@ -284,12 +329,3 @@ def val_mx(value):
domain_re
.
match
(
mx
[
1
])):
domain_re
.
match
(
mx
[
1
])):
raise
ValidationError
(
_
(
"Bad MX address format. "
raise
ValidationError
(
_
(
"Bad MX address format. "
"Should be: <priority>:<hostname>"
))
"Should be: <priority>:<hostname>"
))
def
convert_ipv4_to_ipv6
(
ipv6_template
,
ipv4
):
"""Convert IPv4 address string to IPv6 address string."""
m
=
ipv4
.
words
return
IPAddress
(
ipv6_template
%
{
'a'
:
int
(
m
[
0
]),
'b'
:
int
(
m
[
1
]),
'c'
:
int
(
m
[
2
]),
'd'
:
int
(
m
[
3
])})
circle/firewall/models.py
View file @
ca137eda
...
@@ -17,9 +17,11 @@
...
@@ -17,9 +17,11 @@
# You should have received a copy of the GNU General Public License along
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from
itertools
import
islice
,
ifilter
from
string
import
ascii_letters
from
itertools
import
islice
,
ifilter
,
chain
from
math
import
ceil
import
logging
import
logging
from
netaddr
import
IPSet
,
EUI
,
IPNetwork
import
random
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.db
import
models
from
django.db
import
models
...
@@ -28,15 +30,17 @@ from django.utils.translation import ugettext_lazy as _
...
@@ -28,15 +30,17 @@ from django.utils.translation import ugettext_lazy as _
from
firewall.fields
import
(
MACAddressField
,
val_alfanum
,
val_reverse_domain
,
from
firewall.fields
import
(
MACAddressField
,
val_alfanum
,
val_reverse_domain
,
val_ipv6_template
,
val_domain
,
val_ipv4
,
val_ipv6_template
,
val_domain
,
val_ipv4
,
val_domain_wildcard
,
val_domain_wildcard
,
val_ipv6
,
val_mx
,
convert_ipv4_to_ipv6
,
val_ipv6
,
val_mx
,
IPNetworkField
,
IPAddressField
)
IPNetworkField
,
IPAddressField
)
from
django.core.validators
import
MinValueValidator
,
MaxValueValidator
from
django.core.validators
import
MinValueValidator
,
MaxValueValidator
import
django.conf
import
django.conf
from
django.db.models.signals
import
post_save
,
post_delete
from
django.db.models.signals
import
post_save
,
post_delete
import
random
from
celery.exceptions
import
TimeoutError
from
netaddr
import
IPSet
,
EUI
,
IPNetwork
,
IPAddress
,
ipv6_full
from
common.models
import
method_cache
,
WorkerNotFound
,
HumanSortField
from
common.models
import
method_cache
,
WorkerNotFound
,
HumanSortField
from
firewall.tasks.local_tasks
import
reloadtask
from
firewall.tasks.local_tasks
import
reloadtask
from
firewall.tasks.remote_tasks
import
get_dhcp_clients
from
.iptables
import
IptRule
from
.iptables
import
IptRule
from
acl.models
import
AclBase
from
acl.models
import
AclBase
...
@@ -360,9 +364,19 @@ class Vlan(AclBase, models.Model):
...
@@ -360,9 +364,19 @@ class Vlan(AclBase, models.Model):
'address is: "
%(d)
d.
%(c)
d.
%(b)
d.
%(a)
d.in-addr.arpa".'
),
'address is: "
%(d)
d.
%(c)
d.
%(b)
d.
%(a)
d.in-addr.arpa".'
),
default
=
"
%(d)
d.
%(c)
d.
%(b)
d.
%(a)
d.in-addr.arpa"
)
default
=
"
%(d)
d.
%(c)
d.
%(b)
d.
%(a)
d.in-addr.arpa"
)
ipv6_template
=
models
.
TextField
(
ipv6_template
=
models
.
TextField
(
validators
=
[
val_ipv6_template
],
blank
=
True
,
verbose_name
=
_
(
'ipv6 template'
),
help_text
=
_
(
'Template for translating IPv4 addresses to IPv6. '
default
=
"2001:738:2001:4031:
%(b)
d:
%(c)
d:
%(d)
d:0"
)
'Automatically generated hosts in dual-stack networks '
'will get this address. The template '
'can contain four tokens: "
%(a)
d", "
%(b)
d", '
'"
%(c)
d", and "
%(d)
d", representing the four bytes '
'of the IPv4 address, respectively, in decimal notation. '
'Moreover you can use any standard printf format '
'specification like
%(a)02
x to get the first byte as two '
'hexadecimal digits. Usual choices for mapping '
'198.51.100.0/24 to 2001:0DB8:1:1::/64 would be '
'"2001:db8:1:1:
%(d)
d::" and "2001:db8:1:1:
%(d)02
x00::".'
),
validators
=
[
val_ipv6_template
],
verbose_name
=
_
(
'ipv6 template'
))
dhcp_pool
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'DHCP pool'
),
dhcp_pool
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'DHCP pool'
),
help_text
=
_
(
help_text
=
_
(
'The address range of the DHCP pool: '
'The address range of the DHCP pool: '
...
@@ -377,6 +391,87 @@ class Vlan(AclBase, models.Model):
...
@@ -377,6 +391,87 @@ class Vlan(AclBase, models.Model):
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
,
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'modified at'
))
verbose_name
=
_
(
'modified at'
))
def
clean
(
self
):
super
(
Vlan
,
self
)
.
clean
()
if
self
.
ipv6_template
:
if
not
self
.
network6
:
raise
ValidationError
(
_
(
"You cannot specify an IPv6 template if there is no "
"IPv6 network set."
))
for
i
in
(
self
.
network4
[
1
],
self
.
network4
[
-
1
]):
i6
=
self
.
convert_ipv4_to_ipv6
(
i
)
if
i6
not
in
self
.
network6
:
raise
ValidationError
(
_
(
"
%(ip6)
s (translated from
%(ip4)
s) is outside of "
"the IPv6 network."
)
%
{
"ip4"
:
i
,
"ip6"
:
i6
})
if
self
.
network6
:
tpl
,
prefixlen
=
self
.
_magic_ipv6_template
(
self
.
network4
,
self
.
network6
)
if
not
self
.
ipv6_template
:
self
.
ipv6_template
=
tpl
if
not
self
.
host_ipv6_prefixlen
:
self
.
host_ipv6_prefixlen
=
prefixlen
@staticmethod
def
_host_bytes
(
prefixlen
,
maxbytes
):
return
int
(
ceil
((
maxbytes
-
prefixlen
/
8.0
)))
@staticmethod
def
_append_hexa
(
s
,
v
,
lasthalf
):
if
lasthalf
:
# can use last half word
assert
s
[
-
1
]
==
"0"
or
s
[
-
1
]
.
endswith
(
"00"
)
if
s
[
-
1
]
.
endswith
(
"00"
):
s
[
-
1
]
=
s
[
-
1
][:
-
2
]
s
[
-
1
]
+=
"
%
({})02x"
.
format
(
v
)
s
[
-
1
]
.
lstrip
(
"0"
)
else
:
s
.
append
(
"
%
({})02x00"
.
format
(
v
))
@classmethod
def
_magic_ipv6_template
(
cls
,
network4
,
network6
,
verbose
=
None
):
"""Offer a sensible ipv6_template value.
Based on prefix lengths the method magically selects verbose (decimal)
format:
>>> Vlan._magic_ipv6_template(IPNetwork("198.51.100.0/24"),
... IPNetwork("2001:0DB8:1:1::/64"))
('2001:db8:1:1:
%(d)
d::', 80)
However you can explicitly select non-verbose, i.e. hexa format:
>>> Vlan._magic_ipv6_template(IPNetwork("198.51.100.0/24"),
... IPNetwork("2001:0DB8:1:1::/64"), False)
('2001:db8:1:1:
%(d)02
x00::', 72)
"""
host4_bytes
=
cls
.
_host_bytes
(
network4
.
prefixlen
,
4
)
host6_bytes
=
cls
.
_host_bytes
(
network6
.
prefixlen
,
16
)
if
host4_bytes
>
host6_bytes
:
raise
ValidationError
(
_
(
"IPv6 network is too small to map IPv4 addresses to it."
))
letters
=
ascii_letters
[
4
-
host4_bytes
:
4
]
remove
=
host6_bytes
//
2
ipstr
=
network6
.
network
.
format
(
ipv6_full
)
s
=
ipstr
.
split
(
":"
)[
0
:
-
remove
]
if
verbose
is
None
:
# use verbose format if net6 much wider
verbose
=
2
*
(
host4_bytes
+
1
)
<
host6_bytes
if
verbose
:
for
i
in
letters
:
s
.
append
(
"
%
({})d"
.
format
(
i
))
else
:
remain
=
host6_bytes
for
i
in
letters
:
cls
.
_append_hexa
(
s
,
i
,
remain
%
2
==
1
)
remain
-=
1
if
host6_bytes
>
host4_bytes
:
s
.
append
(
":"
)
tpl
=
":"
.
join
(
s
)
# compute prefix length
mask
=
int
(
IPAddress
(
tpl
%
{
"a"
:
1
,
"b"
:
1
,
"c"
:
1
,
"d"
:
1
}))
prefixlen
=
128
while
mask
%
2
==
0
:
mask
/=
2
prefixlen
-=
1
return
(
tpl
,
prefixlen
)
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
"
%
s -
%
s"
%
(
"managed"
if
self
.
managed
else
"unmanaged"
,
return
"
%
s -
%
s"
%
(
"managed"
if
self
.
managed
else
"unmanaged"
,
self
.
name
)
self
.
name
)
...
@@ -402,7 +497,7 @@ class Vlan(AclBase, models.Model):
...
@@ -402,7 +497,7 @@ class Vlan(AclBase, models.Model):
logger
.
debug
(
"Found unused IPv4 address
%
s."
,
ipv4
)
logger
.
debug
(
"Found unused IPv4 address
%
s."
,
ipv4
)
ipv6
=
None
ipv6
=
None
if
self
.
network6
is
not
None
:
if
self
.
network6
is
not
None
:
ipv6
=
convert_ipv4_to_ipv6
(
self
.
ipv6_template
,
ipv4
)
ipv6
=
self
.
convert_ipv4_to_ipv6
(
ipv4
)
if
ipv6
in
used_v6
:
if
ipv6
in
used_v6
:
continue
continue
else
:
else
:
...
@@ -411,6 +506,20 @@ class Vlan(AclBase, models.Model):
...
@@ -411,6 +506,20 @@ class Vlan(AclBase, models.Model):
else
:
else
:
raise
ValidationError
(
_
(
"All IP addresses are already in use."
))
raise
ValidationError
(
_
(
"All IP addresses are already in use."
))
def
convert_ipv4_to_ipv6
(
self
,
ipv4
):
"""Convert IPv4 address string to IPv6 address string."""
if
isinstance
(
ipv4
,
basestring
):
ipv4
=
IPAddress
(
ipv4
,
4
)
nums
=
{
ascii_letters
[
i
]:
int
(
ipv4
.
words
[
i
])
for
i
in
range
(
4
)}
return
IPAddress
(
self
.
ipv6_template
%
nums
)
def
get_dhcp_clients
(
self
):
macs
=
set
(
i
.
mac
for
i
in
self
.
host_set
.
all
())
return
[{
"mac"
:
k
,
"ip"
:
v
[
"ip"
],
"hostname"
:
v
[
"hostname"
]}
for
k
,
v
in
chain
(
*
(
fw
.
get_dhcp_clients
()
.
iteritems
()
for
fw
in
Firewall
.
objects
.
all
()
if
fw
))
if
v
[
"interface"
]
==
self
.
name
and
EUI
(
k
)
not
in
macs
]
class
VlanGroup
(
models
.
Model
):
class
VlanGroup
(
models
.
Model
):
"""
"""
...
@@ -581,8 +690,7 @@ class Host(models.Model):
...
@@ -581,8 +690,7 @@ class Host(models.Model):
def
save
(
self
,
*
args
,
**
kwargs
):
def
save
(
self
,
*
args
,
**
kwargs
):
if
not
self
.
id
and
self
.
ipv6
==
"auto"
:
if
not
self
.
id
and
self
.
ipv6
==
"auto"
:
self
.
ipv6
=
convert_ipv4_to_ipv6
(
self
.
vlan
.
ipv6_template
,
self
.
ipv6
=
self
.
vlan
.
convert_ipv4_to_ipv6
(
self
.
ipv4
)
self
.
ipv4
)
self
.
full_clean
()
self
.
full_clean
()
super
(
Host
,
self
)
.
save
(
*
args
,
**
kwargs
)
super
(
Host
,
self
)
.
save
(
*
args
,
**
kwargs
)
...
@@ -835,7 +943,7 @@ class Firewall(models.Model):
...
@@ -835,7 +943,7 @@ class Firewall(models.Model):
return
self
.
name
return
self
.
name
@method_cache
(
30
)
@method_cache
(
30
)
def
get_remote_queue_name
(
self
,
queue_id
):
def
get_remote_queue_name
(
self
,
queue_id
=
"firewall"
):
"""Returns the name of the remote celery queue for this node.
"""Returns the name of the remote celery queue for this node.
Throws Exception if there is no worker on the queue.
Throws Exception if there is no worker on the queue.
...
@@ -848,6 +956,20 @@ class Firewall(models.Model):
...
@@ -848,6 +956,20 @@ class Firewall(models.Model):
else
:
else
:
raise
WorkerNotFound
()
raise
WorkerNotFound
()
@method_cache
(
20
)
def
get_dhcp_clients
(
self
):
try
:
return
get_dhcp_clients
.
apply_async
(
queue
=
self
.
get_remote_queue_name
(),
expires
=
60
)
.
get
(
timeout
=
2
)
except
TimeoutError
:
logger
.
info
(
"get_dhcp_clients task timed out"
)
except
IOError
:
logger
.
exception
(
"get_dhcp_clients failed. "
"maybe syslog isn't readble by firewall worker"
)
except
:
logger
.
exception
(
"get_dhcp_clients failed"
)
return
{}
class
Domain
(
models
.
Model
):
class
Domain
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
40
,
validators
=
[
val_domain
],
name
=
models
.
CharField
(
max_length
=
40
,
validators
=
[
val_domain
],
...
...
circle/firewall/tasks/remote_tasks.py
View file @
ca137eda
...
@@ -62,5 +62,6 @@ def reload_blacklist(data):
...
@@ -62,5 +62,6 @@ def reload_blacklist(data):
@celery.task
(
name
=
'firewall.get_dhcp_clients'
)
@celery.task
(
name
=
'firewall.get_dhcp_clients'
)
def
get_dhcp_clients
(
data
):
def
get_dhcp_clients
():
# {'00:21:5a:73:72:cd': {'interface': 'OFF', 'ip': None, 'hostname': None}}
pass
pass
circle/firewall/tests/test_firewall.py
View file @
ca137eda
...
@@ -78,6 +78,7 @@ class GetNewAddressTestCase(TestCase):
...
@@ -78,6 +78,7 @@ class GetNewAddressTestCase(TestCase):
self
.
vlan
=
Vlan
(
vid
=
1
,
name
=
'test'
,
network4
=
'10.0.0.0/29'
,
self
.
vlan
=
Vlan
(
vid
=
1
,
name
=
'test'
,
network4
=
'10.0.0.0/29'
,
network6
=
'2001:738:2001:4031::/80'
,
domain
=
d
,
network6
=
'2001:738:2001:4031::/80'
,
domain
=
d
,
owner
=
self
.
u1
)
owner
=
self
.
u1
)
self
.
vlan
.
clean
()
self
.
vlan
.
save
()
self
.
vlan
.
save
()
self
.
vlan
.
host_set
.
all
()
.
delete
()
self
.
vlan
.
host_set
.
all
()
.
delete
()
for
i
in
[
1
]
+
range
(
3
,
6
):
for
i
in
[
1
]
+
range
(
3
,
6
):
...
@@ -85,6 +86,9 @@ class GetNewAddressTestCase(TestCase):
...
@@ -85,6 +86,9 @@ class GetNewAddressTestCase(TestCase):
ipv4
=
'10.0.0.
%
d'
%
i
,
vlan
=
self
.
vlan
,
ipv4
=
'10.0.0.
%
d'
%
i
,
vlan
=
self
.
vlan
,
owner
=
self
.
u1
)
.
save
()
owner
=
self
.
u1
)
.
save
()
def
tearDown
(
self
):
self
.
vlan
.
delete
()
def
test_new_addr_w_empty_vlan
(
self
):
def
test_new_addr_w_empty_vlan
(
self
):
self
.
vlan
.
host_set
.
all
()
.
delete
()
self
.
vlan
.
host_set
.
all
()
.
delete
()
self
.
vlan
.
get_new_address
()
self
.
vlan
.
get_new_address
()
...
@@ -96,12 +100,6 @@ class GetNewAddressTestCase(TestCase):
...
@@ -96,12 +100,6 @@ class GetNewAddressTestCase(TestCase):
owner
=
self
.
u1
)
.
save
()
owner
=
self
.
u1
)
.
save
()
self
.
assertRaises
(
ValidationError
,
self
.
vlan
.
get_new_address
)
self
.
assertRaises
(
ValidationError
,
self
.
vlan
.
get_new_address
)
def
test_all_addr_in_use_w_ipv6
(
self
):
Host
(
hostname
=
'h-x'
,
mac
=
'01:02:03:04:05:06'
,
ipv4
=
'10.0.0.6'
,
ipv6
=
'2001:738:2001:4031:0:0:2:0'
,
vlan
=
self
.
vlan
,
owner
=
self
.
u1
)
.
save
()
self
.
assertRaises
(
ValidationError
,
self
.
vlan
.
get_new_address
)
def
test_new_addr
(
self
):
def
test_new_addr
(
self
):
used_v4
=
IPSet
(
self
.
vlan
.
host_set
.
values_list
(
'ipv4'
,
flat
=
True
))
used_v4
=
IPSet
(
self
.
vlan
.
host_set
.
values_list
(
'ipv4'
,
flat
=
True
))
assert
self
.
vlan
.
get_new_address
()[
'ipv4'
]
not
in
used_v4
assert
self
.
vlan
.
get_new_address
()[
'ipv4'
]
not
in
used_v4
...
...
circle/locale/hu/LC_MESSAGES/django.po
View file @
ca137eda
This source diff could not be displayed because it is too large. You can
view the blob
instead.
circle/locale/hu/LC_MESSAGES/djangojs.po
View file @
ca137eda
...
@@ -6,7 +6,7 @@ msgid ""
...
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
msgstr ""
"Project-Id-Version: \n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-1
0-20 12:09+02
00\n"
"POT-Creation-Date: 2014-1
1-14 13:43+01
00\n"
"PO-Revision-Date: 2014-10-20 12:21+0200\n"
"PO-Revision-Date: 2014-10-20 12:21+0200\n"
"Last-Translator: Mate Ory <ory.mate@ik.bme.hu>\n"
"Last-Translator: Mate Ory <ory.mate@ik.bme.hu>\n"
"Language-Team: Hungarian <cloud@ik.bme.hu>\n"
"Language-Team: Hungarian <cloud@ik.bme.hu>\n"
...
@@ -17,7 +17,7 @@ msgstr ""
...
@@ -17,7 +17,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 1.5\n"
"X-Generator: Lokalize 1.5\n"
#: dashboard/static/dashboard/dashboard.js:
68
#: dashboard/static/dashboard/dashboard.js:
83
#: static_collected/all.047675ebf594.js:3443
#: static_collected/all.047675ebf594.js:3443
#: static_collected/all.0aecd87e873a.js:3443
#: static_collected/all.0aecd87e873a.js:3443
#: static_collected/all.0db607331718.js:3443
#: static_collected/all.0db607331718.js:3443
...
@@ -34,13 +34,13 @@ msgstr ""
...
@@ -34,13 +34,13 @@ msgstr ""
#: static_collected/dashboard/dashboard.be8725cd91bf.js:68
#: static_collected/dashboard/dashboard.be8725cd91bf.js:68
#: static_collected/dashboard/dashboard.e740d80401b2.js:68
#: static_collected/dashboard/dashboard.e740d80401b2.js:68
#: static_collected/dashboard/dashboard.fe0a2f126346.js:68
#: static_collected/dashboard/dashboard.fe0a2f126346.js:68
#: static_collected/dashboard/dashboard.js:
68
#: static_collected/dashboard/dashboard.js:
83
msgid "Select an option to proceed!"
msgid "Select an option to proceed!"
msgstr "Válasszon a folytatáshoz."
msgstr "Válasszon a folytatáshoz."
#: dashboard/static/dashboard/dashboard.js:2
59
#: dashboard/static/dashboard/dashboard.js:2
74
#: dashboard/static/dashboard/dashboard.js:3
07
#: dashboard/static/dashboard/dashboard.js:3
22
#: dashboard/static/dashboard/dashboard.js:3
17
#: dashboard/static/dashboard/dashboard.js:3
32
#: static_collected/all.047675ebf594.js:3633
#: static_collected/all.047675ebf594.js:3633
#: static_collected/all.047675ebf594.js:3681
#: static_collected/all.047675ebf594.js:3681
#: static_collected/all.047675ebf594.js:3691
#: static_collected/all.047675ebf594.js:3691
...
@@ -88,9 +88,9 @@ msgstr "Válasszon a folytatáshoz."
...
@@ -88,9 +88,9 @@ msgstr "Válasszon a folytatáshoz."
#: static_collected/dashboard/dashboard.fe0a2f126346.js:258
#: static_collected/dashboard/dashboard.fe0a2f126346.js:258
#: static_collected/dashboard/dashboard.fe0a2f126346.js:306
#: static_collected/dashboard/dashboard.fe0a2f126346.js:306
#: static_collected/dashboard/dashboard.fe0a2f126346.js:316
#: static_collected/dashboard/dashboard.fe0a2f126346.js:316
#: static_collected/dashboard/dashboard.js:2
59
#: static_collected/dashboard/dashboard.js:2
74
#: static_collected/dashboard/dashboard.js:3
07
#: static_collected/dashboard/dashboard.js:3
22
#: static_collected/dashboard/dashboard.js:3
17
#: static_collected/dashboard/dashboard.js:3
32
msgid "No result"
msgid "No result"
msgstr "Nincs eredmény"
msgstr "Nincs eredmény"
...
@@ -129,10 +129,12 @@ msgid "Unknown error."
...
@@ -129,10 +129,12 @@ msgid "Unknown error."
msgstr "Ismeretlen hiba."
msgstr "Ismeretlen hiba."
#: dashboard/static/dashboard/template-list.js:103
#: dashboard/static/dashboard/template-list.js:103
#: static_collected/dashboard/template-list.js:103
msgid "Only the owners can delete the selected object."
msgid "Only the owners can delete the selected object."
msgstr "Csak a tulajdonos törölheti a kiválasztott elemet."
msgstr "Csak a tulajdonos törölheti a kiválasztott elemet."
#: dashboard/static/dashboard/template-list.js:105
#: dashboard/static/dashboard/template-list.js:105
#: static_collected/dashboard/template-list.js:105
msgid "An error occurred. ("
msgid "An error occurred. ("
msgstr "Hiba történt. ("
msgstr "Hiba történt. ("
...
@@ -206,11 +208,12 @@ msgstr "Jelszó megjelenítése"
...
@@ -206,11 +208,12 @@ msgstr "Jelszó megjelenítése"
#: static_collected/vm-detail.js:6391
#: static_collected/vm-detail.js:6391
#: static_collected/dashboard/vm-tour.1562cc89a659.js:22
#: static_collected/dashboard/vm-tour.1562cc89a659.js:22
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:22
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:22
#: static_collected/dashboard/vm-tour.js:
22
#: static_collected/dashboard/vm-tour.js:
6
msgid "Next"
msgid "Next"
msgstr "Tovább"
msgstr "Tovább"
#: dashboard/static/dashboard/vm-tour.js:7
#: dashboard/static/dashboard/vm-tour.js:7
#: static_collected/dashboard/vm-tour.js:7
msgid "Previous"
msgid "Previous"
msgstr "Vissza"
msgstr "Vissza"
...
@@ -226,15 +229,17 @@ msgstr "Vissza"
...
@@ -226,15 +229,17 @@ msgstr "Vissza"
#: static_collected/vm-detail.js:6395
#: static_collected/vm-detail.js:6395
#: static_collected/dashboard/vm-tour.1562cc89a659.js:26
#: static_collected/dashboard/vm-tour.1562cc89a659.js:26
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:26
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:26
#: static_collected/dashboard/vm-tour.js:
26
#: static_collected/dashboard/vm-tour.js:
8
msgid "End tour"
msgid "End tour"
msgstr "Befejezés"
msgstr "Befejezés"
#: dashboard/static/dashboard/vm-tour.js:9
#: dashboard/static/dashboard/vm-tour.js:9
#: static_collected/dashboard/vm-tour.js:9
msgid "Done"
msgid "Done"
msgstr "Kész"
msgstr "Kész"
#: dashboard/static/dashboard/vm-tour.js:56
#: dashboard/static/dashboard/vm-tour.js:56
#: static_collected/dashboard/vm-tour.js:56
msgid ""
msgid ""
"Welcome to the template tutorial. In this quick tour, we are going to show "
"Welcome to the template tutorial. In this quick tour, we are going to show "
"you how to do the steps described above."
"you how to do the steps described above."
...
@@ -254,7 +259,7 @@ msgstr ""
...
@@ -254,7 +259,7 @@ msgstr ""
#: static_collected/vm-detail.js:6404
#: static_collected/vm-detail.js:6404
#: static_collected/dashboard/vm-tour.1562cc89a659.js:35
#: static_collected/dashboard/vm-tour.1562cc89a659.js:35
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:35
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:35
#: static_collected/dashboard/vm-tour.js:
35
#: static_collected/dashboard/vm-tour.js:
57
msgid ""
msgid ""
"For the next tour step press the \"Next\" button or the right arrow (or "
"For the next tour step press the \"Next\" button or the right arrow (or "
"\"Back\" button/left arrow for the previous step)."
"\"Back\" button/left arrow for the previous step)."
...
@@ -263,6 +268,7 @@ msgstr ""
...
@@ -263,6 +268,7 @@ msgstr ""
"nyílbillentyűket."
"nyílbillentyűket."
#: dashboard/static/dashboard/vm-tour.js:61
#: dashboard/static/dashboard/vm-tour.js:61
#: static_collected/dashboard/vm-tour.js:61
msgid ""
msgid ""
"In this tab you can extend the expiration date of your virtual machine, add "
"In this tab you can extend the expiration date of your virtual machine, add "
"tags and modify the name and description."
"tags and modify the name and description."
...
@@ -271,24 +277,26 @@ msgstr ""
...
@@ -271,24 +277,26 @@ msgstr ""
"vagy módosíthatja a nevét, leírását."
"vagy módosíthatja a nevét, leírását."
#: dashboard/static/dashboard/vm-tour.js:65
#: dashboard/static/dashboard/vm-tour.js:65
#: static_collected/dashboard/vm-tour.js:65
msgid ""
msgid ""
"Please add a meaningful description to the virtual machine. Changing the "
"Please add a meaningful description to the virtual machine. Changing the "
"name is also recommended, however you can choose a new name when saving the "
"name is also recommended, however you can choose a new name when saving the "
"template."
"template."
msgstr ""
msgstr ""
"Kérjük, adjon meg egy informatív leírást. A név megváltoztatása is "
"Kérjük, adjon meg egy informatív leírást. A név megváltoztatása is ajánlott, "
"ajánlott, azonban a mentéskor is van a sablon nevének "
"azonban a mentéskor is van a sablon nevének megválasztására."
"megválasztására."
#: dashboard/static/dashboard/vm-tour.js:69
#: dashboard/static/dashboard/vm-tour.js:69
#: static_collected/dashboard/vm-tour.js:69
msgid ""
msgid ""
"You can change the lease to extend the expiration date. This will be the "
"You can change the lease to extend the expiration date. This will be the "
"lease of the new template."
"lease of the new template."
msgstr ""
msgstr ""
"Megváltoztathatja a bérleti módot is a lejárat bővítéséhez. Az gép "
"Megváltoztathatja a bérleti módot is a lejárat bővítéséhez. Az gép
bérleti
"
"
bérleti
módját örökli majd a sablon is."
"módját örökli majd a sablon is."
#: dashboard/static/dashboard/vm-tour.js:73
#: dashboard/static/dashboard/vm-tour.js:73
#: static_collected/dashboard/vm-tour.js:73
msgid ""
msgid ""
"On the resources tab you can edit the CPU/RAM options and add/remove disks "
"On the resources tab you can edit the CPU/RAM options and add/remove disks "
"if you have required permissions."
"if you have required permissions."
...
@@ -308,7 +316,7 @@ msgstr ""
...
@@ -308,7 +316,7 @@ msgstr ""
#: static_collected/vm-detail.js:6438
#: static_collected/vm-detail.js:6438
#: static_collected/dashboard/vm-tour.1562cc89a659.js:69
#: static_collected/dashboard/vm-tour.1562cc89a659.js:69
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:69
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:69
#: static_collected/dashboard/vm-tour.js:
69
#: static_collected/dashboard/vm-tour.js:
81
msgid "CPU priority"
msgid "CPU priority"
msgstr "CPU prioritás"
msgstr "CPU prioritás"
...
@@ -324,7 +332,7 @@ msgstr "CPU prioritás"
...
@@ -324,7 +332,7 @@ msgstr "CPU prioritás"
#: static_collected/vm-detail.js:6438
#: static_collected/vm-detail.js:6438
#: static_collected/dashboard/vm-tour.1562cc89a659.js:69
#: static_collected/dashboard/vm-tour.1562cc89a659.js:69
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:69
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:69
#: static_collected/dashboard/vm-tour.js:
69
#: static_collected/dashboard/vm-tour.js:
82
msgid "higher is better"
msgid "higher is better"
msgstr "a nagyobb érték a jobb"
msgstr "a nagyobb érték a jobb"
...
@@ -340,7 +348,7 @@ msgstr "a nagyobb érték a jobb"
...
@@ -340,7 +348,7 @@ msgstr "a nagyobb érték a jobb"
#: static_collected/vm-detail.js:6439
#: static_collected/vm-detail.js:6439
#: static_collected/dashboard/vm-tour.1562cc89a659.js:70
#: static_collected/dashboard/vm-tour.1562cc89a659.js:70
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:70
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:70
#: static_collected/dashboard/vm-tour.js:
70
#: static_collected/dashboard/vm-tour.js:
83
msgid "CPU count"
msgid "CPU count"
msgstr "CPU-k száma"
msgstr "CPU-k száma"
...
@@ -356,7 +364,7 @@ msgstr "CPU-k száma"
...
@@ -356,7 +364,7 @@ msgstr "CPU-k száma"
#: static_collected/vm-detail.js:6439
#: static_collected/vm-detail.js:6439
#: static_collected/dashboard/vm-tour.1562cc89a659.js:70
#: static_collected/dashboard/vm-tour.1562cc89a659.js:70
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:70
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:70
#: static_collected/dashboard/vm-tour.js:
70
#: static_collected/dashboard/vm-tour.js:
84
msgid "number of CPU cores."
msgid "number of CPU cores."
msgstr "A CPU-magok száma."
msgstr "A CPU-magok száma."
...
@@ -372,7 +380,7 @@ msgstr "A CPU-magok száma."
...
@@ -372,7 +380,7 @@ msgstr "A CPU-magok száma."
#: static_collected/vm-detail.js:6440
#: static_collected/vm-detail.js:6440
#: static_collected/dashboard/vm-tour.1562cc89a659.js:71
#: static_collected/dashboard/vm-tour.1562cc89a659.js:71
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:71
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:71
#: static_collected/dashboard/vm-tour.js:
71
#: static_collected/dashboard/vm-tour.js:
85
msgid "RAM amount"
msgid "RAM amount"
msgstr "RAM mennyiség"
msgstr "RAM mennyiség"
...
@@ -388,7 +396,7 @@ msgstr "RAM mennyiség"
...
@@ -388,7 +396,7 @@ msgstr "RAM mennyiség"
#: static_collected/vm-detail.js:6440
#: static_collected/vm-detail.js:6440
#: static_collected/dashboard/vm-tour.1562cc89a659.js:71
#: static_collected/dashboard/vm-tour.1562cc89a659.js:71
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:71
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:71
#: static_collected/dashboard/vm-tour.js:
71
#: static_collected/dashboard/vm-tour.js:
86
msgid "amount of RAM."
msgid "amount of RAM."
msgstr "a memória mennyisége."
msgstr "a memória mennyisége."
...
@@ -404,7 +412,7 @@ msgstr "a memória mennyisége."
...
@@ -404,7 +412,7 @@ msgstr "a memória mennyisége."
#: static_collected/vm-detail.js:6451
#: static_collected/vm-detail.js:6451
#: static_collected/dashboard/vm-tour.1562cc89a659.js:82
#: static_collected/dashboard/vm-tour.1562cc89a659.js:82
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:82
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:82
#: static_collected/dashboard/vm-tour.js:
82
#: static_collected/dashboard/vm-tour.js:
96
msgid ""
msgid ""
"You can add empty disks, download new ones and remove existing ones here."
"You can add empty disks, download new ones and remove existing ones here."
msgstr ""
msgstr ""
...
@@ -423,7 +431,7 @@ msgstr ""
...
@@ -423,7 +431,7 @@ msgstr ""
#: static_collected/vm-detail.js:6462
#: static_collected/vm-detail.js:6462
#: static_collected/dashboard/vm-tour.1562cc89a659.js:93
#: static_collected/dashboard/vm-tour.1562cc89a659.js:93
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:93
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:93
#: static_collected/dashboard/vm-tour.js:
93
#: static_collected/dashboard/vm-tour.js:
105
msgid "You can add new network interfaces or remove existing ones here."
msgid "You can add new network interfaces or remove existing ones here."
msgstr "Hozzáadhat új hálózati interfészeket, vagy törölheti a meglévőket."
msgstr "Hozzáadhat új hálózati interfészeket, vagy törölheti a meglévőket."
...
@@ -439,17 +447,18 @@ msgstr "Hozzáadhat új hálózati interfészeket, vagy törölheti a meglévők
...
@@ -439,17 +447,18 @@ msgstr "Hozzáadhat új hálózati interfészeket, vagy törölheti a meglévők
#: static_collected/vm-detail.js:6474
#: static_collected/vm-detail.js:6474
#: static_collected/dashboard/vm-tour.1562cc89a659.js:105
#: static_collected/dashboard/vm-tour.1562cc89a659.js:105
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:105
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:105
#: static_collected/dashboard/vm-tour.js:10
5
#: static_collected/dashboard/vm-tour.js:10
9
msgid "Deploy the virtual machine."
msgid "Deploy the virtual machine."
msgstr "A virtuális gép elindítása."
msgstr "A virtuális gép elindítása."
#: dashboard/static/dashboard/vm-tour.js:113
#: dashboard/static/dashboard/vm-tour.js:113
#: static_collected/dashboard/vm-tour.js:113
msgid ""
msgid ""
"Use the CIRCLE client or the connection string to connect to the virtual "
"Use the CIRCLE client or the connection string to connect to the virtual "
"machine."
"machine."
msgstr ""
msgstr ""
"Használja a CIRCLE klienst vagy a kapcsolódási adatokat a "
"Használja a CIRCLE klienst vagy a kapcsolódási adatokat a
virtuális géphez
"
"v
irtuális géphez v
aló csatlakozáshoz."
"való csatlakozáshoz."
#: dashboard/static/dashboard/vm-tour.js:117
#: dashboard/static/dashboard/vm-tour.js:117
#: static_collected/vm-detail.09737c69abc3.js:5954
#: static_collected/vm-detail.09737c69abc3.js:5954
...
@@ -463,7 +472,7 @@ msgstr ""
...
@@ -463,7 +472,7 @@ msgstr ""
#: static_collected/vm-detail.js:6490
#: static_collected/vm-detail.js:6490
#: static_collected/dashboard/vm-tour.1562cc89a659.js:121
#: static_collected/dashboard/vm-tour.1562cc89a659.js:121
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:121
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:121
#: static_collected/dashboard/vm-tour.js:1
21
#: static_collected/dashboard/vm-tour.js:1
17
msgid ""
msgid ""
"After you have connected to the virtual machine do your modifications then "
"After you have connected to the virtual machine do your modifications then "
"log off."
"log off."
...
@@ -483,7 +492,7 @@ msgstr ""
...
@@ -483,7 +492,7 @@ msgstr ""
#: static_collected/vm-detail.js:6498
#: static_collected/vm-detail.js:6498
#: static_collected/dashboard/vm-tour.1562cc89a659.js:129
#: static_collected/dashboard/vm-tour.1562cc89a659.js:129
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:129
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:129
#: static_collected/dashboard/vm-tour.js:12
9
#: static_collected/dashboard/vm-tour.js:12
1
msgid ""
msgid ""
"Press the \"Save as template\" button and wait until the activity finishes."
"Press the \"Save as template\" button and wait until the activity finishes."
msgstr ""
msgstr ""
...
@@ -491,12 +500,11 @@ msgstr ""
...
@@ -491,12 +500,11 @@ msgstr ""
"elkészül."
"elkészül."
#: dashboard/static/dashboard/vm-tour.js:125
#: dashboard/static/dashboard/vm-tour.js:125
#: static_collected/dashboard/vm-tour.js:125
msgid ""
msgid ""
"This is the last message, if something is not clear you can do the the tour "
"This is the last message, if something is not clear you can do the the tour "
"again."
"again."
msgstr ""
msgstr "A túra véget ért. Ha valami nem érthető, újrakezdheti az útmutatót."
"A túra véget ért. Ha valami nem érthető, újrakezdheti az "
"útmutatót."
#: network/static/js/host.js:10 static_collected/all.047675ebf594.js:5239
#: network/static/js/host.js:10 static_collected/all.047675ebf594.js:5239
#: static_collected/all.0aecd87e873a.js:5309
#: static_collected/all.0aecd87e873a.js:5309
...
@@ -617,7 +625,6 @@ msgstr "Biztosan törli ezt az eszközt?"
...
@@ -617,7 +625,6 @@ msgstr "Biztosan törli ezt az eszközt?"
#: static_collected/vm-detail.js:6389
#: static_collected/vm-detail.js:6389
#: static_collected/dashboard/vm-tour.1562cc89a659.js:20
#: static_collected/dashboard/vm-tour.1562cc89a659.js:20
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:20
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:20
#: static_collected/dashboard/vm-tour.js:20
msgid "Prev"
msgid "Prev"
msgstr "Vissza"
msgstr "Vissza"
...
@@ -632,7 +639,6 @@ msgstr "Vissza"
...
@@ -632,7 +639,6 @@ msgstr "Vissza"
#: static_collected/vm-detail.js:6402
#: static_collected/vm-detail.js:6402
#: static_collected/dashboard/vm-tour.1562cc89a659.js:33
#: static_collected/dashboard/vm-tour.1562cc89a659.js:33
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:33
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:33
#: static_collected/dashboard/vm-tour.js:33
msgid "Template Tutorial Tour"
msgid "Template Tutorial Tour"
msgstr "Sablon-kalauz"
msgstr "Sablon-kalauz"
...
@@ -647,7 +653,6 @@ msgstr "Sablon-kalauz"
...
@@ -647,7 +653,6 @@ msgstr "Sablon-kalauz"
#: static_collected/vm-detail.js:6403
#: static_collected/vm-detail.js:6403
#: static_collected/dashboard/vm-tour.1562cc89a659.js:34
#: static_collected/dashboard/vm-tour.1562cc89a659.js:34
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:34
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:34
#: static_collected/dashboard/vm-tour.js:34
msgid ""
msgid ""
"Welcome to the template tutorial. In this quick tour, we gonna show you how "
"Welcome to the template tutorial. In this quick tour, we gonna show you how "
"to do the steps described above."
"to do the steps described above."
...
@@ -665,7 +670,6 @@ msgstr ""
...
@@ -665,7 +670,6 @@ msgstr ""
#: static_collected/vm-detail.js:6405
#: static_collected/vm-detail.js:6405
#: static_collected/dashboard/vm-tour.1562cc89a659.js:36
#: static_collected/dashboard/vm-tour.1562cc89a659.js:36
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:36
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:36
#: static_collected/dashboard/vm-tour.js:36
msgid ""
msgid ""
"During the tour please don't try the functions because it may lead to "
"During the tour please don't try the functions because it may lead to "
"graphical glitches, however "
"graphical glitches, however "
...
@@ -682,7 +686,6 @@ msgstr "A túra során még ne próbálja ki a bemutatott funkciókat."
...
@@ -682,7 +686,6 @@ msgstr "A túra során még ne próbálja ki a bemutatott funkciókat."
#: static_collected/vm-detail.js:6414
#: static_collected/vm-detail.js:6414
#: static_collected/dashboard/vm-tour.1562cc89a659.js:45
#: static_collected/dashboard/vm-tour.1562cc89a659.js:45
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:45
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:45
#: static_collected/dashboard/vm-tour.js:45
msgid "Home tab"
msgid "Home tab"
msgstr "Kezdőoldal"
msgstr "Kezdőoldal"
...
@@ -697,7 +700,6 @@ msgstr "Kezdőoldal"
...
@@ -697,7 +700,6 @@ msgstr "Kezdőoldal"
#: static_collected/vm-detail.js:6415
#: static_collected/vm-detail.js:6415
#: static_collected/dashboard/vm-tour.1562cc89a659.js:46
#: static_collected/dashboard/vm-tour.1562cc89a659.js:46
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:46
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:46
#: static_collected/dashboard/vm-tour.js:46
msgid ""
msgid ""
"In this tab you can tag your virtual machine and modify the name and "
"In this tab you can tag your virtual machine and modify the name and "
"description."
"description."
...
@@ -716,7 +718,6 @@ msgstr ""
...
@@ -716,7 +718,6 @@ msgstr ""
#: static_collected/vm-detail.js:6424
#: static_collected/vm-detail.js:6424
#: static_collected/dashboard/vm-tour.1562cc89a659.js:55
#: static_collected/dashboard/vm-tour.1562cc89a659.js:55
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:55
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:55
#: static_collected/dashboard/vm-tour.js:55
msgid "Resources tab"
msgid "Resources tab"
msgstr "Erőforrások lap"
msgstr "Erőforrások lap"
...
@@ -731,7 +732,6 @@ msgstr "Erőforrások lap"
...
@@ -731,7 +732,6 @@ msgstr "Erőforrások lap"
#: static_collected/vm-detail.js:6427
#: static_collected/vm-detail.js:6427
#: static_collected/dashboard/vm-tour.1562cc89a659.js:58
#: static_collected/dashboard/vm-tour.1562cc89a659.js:58
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:58
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:58
#: static_collected/dashboard/vm-tour.js:58
msgid ""
msgid ""
"On the resources tab you can edit the CPU/RAM options and add/remove disks!"
"On the resources tab you can edit the CPU/RAM options and add/remove disks!"
msgstr ""
msgstr ""
...
@@ -749,7 +749,6 @@ msgstr ""
...
@@ -749,7 +749,6 @@ msgstr ""
#: static_collected/vm-detail.js:6437
#: static_collected/vm-detail.js:6437
#: static_collected/dashboard/vm-tour.1562cc89a659.js:68
#: static_collected/dashboard/vm-tour.1562cc89a659.js:68
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:68
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:68
#: static_collected/dashboard/vm-tour.js:68
msgid "Resources"
msgid "Resources"
msgstr "Erőforrások"
msgstr "Erőforrások"
...
@@ -764,7 +763,6 @@ msgstr "Erőforrások"
...
@@ -764,7 +763,6 @@ msgstr "Erőforrások"
#: static_collected/vm-detail.js:6450
#: static_collected/vm-detail.js:6450
#: static_collected/dashboard/vm-tour.1562cc89a659.js:81
#: static_collected/dashboard/vm-tour.1562cc89a659.js:81
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:81
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:81
#: static_collected/dashboard/vm-tour.js:81
msgid "Disks"
msgid "Disks"
msgstr "Lemezek"
msgstr "Lemezek"
...
@@ -779,7 +777,6 @@ msgstr "Lemezek"
...
@@ -779,7 +777,6 @@ msgstr "Lemezek"
#: static_collected/vm-detail.js:6461
#: static_collected/vm-detail.js:6461
#: static_collected/dashboard/vm-tour.1562cc89a659.js:92
#: static_collected/dashboard/vm-tour.1562cc89a659.js:92
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:92
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:92
#: static_collected/dashboard/vm-tour.js:92
msgid "Network tab"
msgid "Network tab"
msgstr "Hálózat lap"
msgstr "Hálózat lap"
...
@@ -794,7 +791,6 @@ msgstr "Hálózat lap"
...
@@ -794,7 +791,6 @@ msgstr "Hálózat lap"
#: static_collected/vm-detail.js:6471
#: static_collected/vm-detail.js:6471
#: static_collected/dashboard/vm-tour.1562cc89a659.js:102
#: static_collected/dashboard/vm-tour.1562cc89a659.js:102
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:102
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:102
#: static_collected/dashboard/vm-tour.js:102
msgid "Deploy"
msgid "Deploy"
msgstr "Indítás"
msgstr "Indítás"
...
@@ -809,7 +805,6 @@ msgstr "Indítás"
...
@@ -809,7 +805,6 @@ msgstr "Indítás"
#: static_collected/vm-detail.js:6479
#: static_collected/vm-detail.js:6479
#: static_collected/dashboard/vm-tour.1562cc89a659.js:110
#: static_collected/dashboard/vm-tour.1562cc89a659.js:110
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:110
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:110
#: static_collected/dashboard/vm-tour.js:110
msgid "Connect"
msgid "Connect"
msgstr "Csatlakozás"
msgstr "Csatlakozás"
...
@@ -824,7 +819,6 @@ msgstr "Csatlakozás"
...
@@ -824,7 +819,6 @@ msgstr "Csatlakozás"
#: static_collected/vm-detail.js:6482
#: static_collected/vm-detail.js:6482
#: static_collected/dashboard/vm-tour.1562cc89a659.js:113
#: static_collected/dashboard/vm-tour.1562cc89a659.js:113
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:113
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:113
#: static_collected/dashboard/vm-tour.js:113
msgid "Use the connection string or connect with your choice of client!"
msgid "Use the connection string or connect with your choice of client!"
msgstr "Használja a megadott parancsot, vagy kedvenc kliensét."
msgstr "Használja a megadott parancsot, vagy kedvenc kliensét."
...
@@ -839,7 +833,6 @@ msgstr "Használja a megadott parancsot, vagy kedvenc kliensét."
...
@@ -839,7 +833,6 @@ msgstr "Használja a megadott parancsot, vagy kedvenc kliensét."
#: static_collected/vm-detail.js:6489
#: static_collected/vm-detail.js:6489
#: static_collected/dashboard/vm-tour.1562cc89a659.js:120
#: static_collected/dashboard/vm-tour.1562cc89a659.js:120
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:120
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:120
#: static_collected/dashboard/vm-tour.js:120
msgid "Customize the virtual machine"
msgid "Customize the virtual machine"
msgstr "Szabja testre a gépet"
msgstr "Szabja testre a gépet"
...
@@ -854,7 +847,6 @@ msgstr "Szabja testre a gépet"
...
@@ -854,7 +847,6 @@ msgstr "Szabja testre a gépet"
#: static_collected/vm-detail.js:6495
#: static_collected/vm-detail.js:6495
#: static_collected/dashboard/vm-tour.1562cc89a659.js:126
#: static_collected/dashboard/vm-tour.1562cc89a659.js:126
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:126
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:126
#: static_collected/dashboard/vm-tour.js:126
msgid "Save as"
msgid "Save as"
msgstr "Mentés sablonként"
msgstr "Mentés sablonként"
...
@@ -869,7 +861,6 @@ msgstr "Mentés sablonként"
...
@@ -869,7 +861,6 @@ msgstr "Mentés sablonként"
#: static_collected/vm-detail.js:6504
#: static_collected/vm-detail.js:6504
#: static_collected/dashboard/vm-tour.1562cc89a659.js:135
#: static_collected/dashboard/vm-tour.1562cc89a659.js:135
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:135
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:135
#: static_collected/dashboard/vm-tour.js:135
msgid "Finish"
msgid "Finish"
msgstr "Befejezés"
msgstr "Befejezés"
...
@@ -884,7 +875,6 @@ msgstr "Befejezés"
...
@@ -884,7 +875,6 @@ msgstr "Befejezés"
#: static_collected/vm-detail.js:6507
#: static_collected/vm-detail.js:6507
#: static_collected/dashboard/vm-tour.1562cc89a659.js:138
#: static_collected/dashboard/vm-tour.1562cc89a659.js:138
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:138
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:138
#: static_collected/dashboard/vm-tour.js:138
msgid ""
msgid ""
"This is the last message, if something is not clear you can do the the tour "
"This is the last message, if something is not clear you can do the the tour "
"again!"
"again!"
...
...
circle/network/forms.py
View file @
ca137eda
...
@@ -15,13 +15,13 @@
...
@@ -15,13 +15,13 @@
# You should have received a copy of the GNU General Public License along
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from
django.forms
import
ModelForm
from
django.forms
import
ModelForm
,
widgets
from
django.core.urlresolvers
import
reverse_lazy
from
django.core.urlresolvers
import
reverse_lazy
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
crispy_forms.helper
import
FormHelper
from
crispy_forms.helper
import
FormHelper
from
crispy_forms.layout
import
Layout
,
Fieldset
,
Div
,
Submit
,
BaseInput
from
crispy_forms.layout
import
Layout
,
Fieldset
,
Div
,
Submit
,
BaseInput
from
crispy_forms.bootstrap
import
FormActions
from
crispy_forms.bootstrap
import
FormActions
,
FieldWithButtons
,
StrictButton
from
firewall.models
import
(
Host
,
Vlan
,
Domain
,
Group
,
Record
,
BlacklistItem
,
from
firewall.models
import
(
Host
,
Vlan
,
Domain
,
Group
,
Record
,
BlacklistItem
,
Rule
,
VlanGroup
,
SwitchPort
)
Rule
,
VlanGroup
,
SwitchPort
)
...
@@ -122,8 +122,12 @@ class HostForm(ModelForm):
...
@@ -122,8 +122,12 @@ class HostForm(ModelForm):
Fieldset
(
Fieldset
(
_
(
'Network'
),
_
(
'Network'
),
'vlan'
,
'vlan'
,
'ipv4'
,
FieldWithButtons
(
'ipv4'
,
StrictButton
(
'ipv6'
,
'<i class="fa fa-magic"></i>'
,
css_id
=
"ipv4-magic"
,
title
=
_
(
"Generate random address."
))),
FieldWithButtons
(
'ipv6'
,
StrictButton
(
'<i class="fa fa-magic"></i>'
,
css_id
=
"ipv6-magic"
,
title
=
_
(
"Generate IPv6 pair of IPv4 address."
))),
'shared_ip'
,
'shared_ip'
,
'external_ipv4'
,
'external_ipv4'
,
),
),
...
@@ -252,7 +256,9 @@ class VlanForm(ModelForm):
...
@@ -252,7 +256,9 @@ class VlanForm(ModelForm):
Fieldset
(
Fieldset
(
_
(
'IPv6'
),
_
(
'IPv6'
),
'network6'
,
'network6'
,
'ipv6_template'
,
FieldWithButtons
(
'ipv6_template'
,
StrictButton
(
'<i class="fa fa-magic"></i>'
,
css_id
=
"ipv6-tpl-magic"
,
title
=
_
(
"Generate sensible template."
))),
'host_ipv6_prefixlen'
,
'host_ipv6_prefixlen'
,
),
),
Fieldset
(
Fieldset
(
...
@@ -277,6 +283,9 @@ class VlanForm(ModelForm):
...
@@ -277,6 +283,9 @@ class VlanForm(ModelForm):
class
Meta
:
class
Meta
:
model
=
Vlan
model
=
Vlan
widgets
=
{
'ipv6_template'
:
widgets
.
TextInput
,
}
class
VlanGroupForm
(
ModelForm
):
class
VlanGroupForm
(
ModelForm
):
...
...
circle/network/static/js/network.js
View file @
ca137eda
...
@@ -28,6 +28,49 @@ function getURLParameter(name) {
...
@@ -28,6 +28,49 @@ function getURLParameter(name) {
);
);
}
}
function
doBlink
(
id
,
count
)
{
if
(
count
>
0
)
{
$
(
id
).
parent
().
delay
(
200
).
queue
(
function
()
{
$
(
this
).
delay
(
200
).
queue
(
function
()
{
$
(
this
).
removeClass
(
"has-warning"
).
dequeue
();
doBlink
(
id
,
count
-
1
);});
$
(
this
).
addClass
(
"has-warning"
).
dequeue
()
});
}
}
$
(
function
()
{
$
(
function
()
{
$
(
"[title]"
).
tooltip
();
$
(
"[title]"
).
tooltip
();
$
(
"#ipv6-magic"
).
click
(
function
()
{
$
.
ajax
({
url
:
window
.
location
,
data
:
{
ipv4
:
$
(
"[name=ipv4]"
).
val
(),
vlan
:
$
(
"[name=vlan]"
).
val
()},
success
:
function
(
data
)
{
$
(
"[name=ipv6]"
).
val
(
data
.
ipv6
);
}});
});
$
(
"#ipv4-magic"
).
click
(
function
()
{
$
.
ajax
({
url
:
window
.
location
,
data
:
{
vlan
:
$
(
"[name=vlan]"
).
val
()},
success
:
function
(
data
)
{
$
(
"[name=ipv4]"
).
val
(
data
.
ipv4
);
if
(
$
(
"[name=ipv6]"
).
val
()
!=
data
.
ipv6
)
{
doBlink
(
"[name=ipv6]"
,
3
);
}
$
(
"[name=ipv6]"
).
val
(
data
.
ipv6
);
}});
});
$
(
"#ipv6-tpl-magic"
).
click
(
function
()
{
$
.
ajax
({
url
:
window
.
location
,
data
:
{
network4
:
$
(
"[name=network4]"
).
val
(),
network6
:
$
(
"[name=network6]"
).
val
()},
success
:
function
(
data
)
{
$
(
"[name=ipv6_template]"
).
val
(
data
.
ipv6_template
);
if
(
$
(
"[name=host_ipv6_prefixlen]"
).
val
()
!=
data
.
host_ipv6_prefixlen
)
{
doBlink
(
"[name=host_ipv6_prefixlen]"
,
3
);
}
$
(
"[name=host_ipv6_prefixlen]"
).
val
(
data
.
host_ipv6_prefixlen
);
}});
});
});
});
circle/network/tables.py
View file @
ca137eda
...
@@ -15,14 +15,30 @@
...
@@ -15,14 +15,30 @@
# You should have received a copy of the GNU General Public License along
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from
netaddr
import
EUI
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.html
import
format_html
from
django_tables2
import
Table
,
A
from
django_tables2
import
Table
,
A
from
django_tables2.columns
import
LinkColumn
,
TemplateColumn
from
django_tables2.columns
import
LinkColumn
,
TemplateColumn
,
Column
from
firewall.models
import
Host
,
Vlan
,
Domain
,
Group
,
Record
,
Rule
,
SwitchPort
from
firewall.models
import
Host
,
Vlan
,
Domain
,
Group
,
Record
,
Rule
,
SwitchPort
class
MACColumn
(
Column
):
def
render
(
self
,
value
):
if
isinstance
(
value
,
basestring
):
try
:
value
=
EUI
(
value
)
except
:
return
value
try
:
return
format_html
(
'<abbr title="{0}">{1}</abbr>'
,
value
.
oui
.
registration
()
.
org
,
value
)
except
:
return
value
class
BlacklistItemTable
(
Table
):
class
BlacklistItemTable
(
Table
):
ipv4
=
LinkColumn
(
'network.blacklist'
,
args
=
[
A
(
'pk'
)])
ipv4
=
LinkColumn
(
'network.blacklist'
,
args
=
[
A
(
'pk'
)])
...
@@ -55,9 +71,7 @@ class GroupTable(Table):
...
@@ -55,9 +71,7 @@ class GroupTable(Table):
class
HostTable
(
Table
):
class
HostTable
(
Table
):
hostname
=
LinkColumn
(
'network.host'
,
args
=
[
A
(
'pk'
)])
hostname
=
LinkColumn
(
'network.host'
,
args
=
[
A
(
'pk'
)])
mac
=
TemplateColumn
(
mac
=
MACColumn
()
template_name
=
"network/columns/mac.html"
)
class
Meta
:
class
Meta
:
model
=
Host
model
=
Host
...
@@ -108,6 +122,20 @@ class SmallHostTable(Table):
...
@@ -108,6 +122,20 @@ class SmallHostTable(Table):
attrs
=
{
'class'
:
'table table-striped table-condensed'
}
attrs
=
{
'class'
:
'table table-striped table-condensed'
}
fields
=
(
'hostname'
,
'ipv4'
)
fields
=
(
'hostname'
,
'ipv4'
)
order_by
=
(
'vlan'
,
'hostname'
,
)
order_by
=
(
'vlan'
,
'hostname'
,
)
empty_text
=
_
(
"No hosts."
)
class
SmallDhcpTable
(
Table
):
mac
=
MACColumn
(
verbose_name
=
_
(
"MAC address"
))
hostname
=
Column
(
verbose_name
=
_
(
"hostname"
))
ip
=
Column
(
verbose_name
=
_
(
"requested IP"
))
register
=
TemplateColumn
(
template_name
=
"network/columns/host-register.html"
,
attrs
=
{
"th"
:
{
"style"
:
"display: none;"
}})
class
Meta
:
attrs
=
{
'class'
:
'table table-striped table-condensed'
}
empty_text
=
_
(
"No hosts."
)
class
RecordTable
(
Table
):
class
RecordTable
(
Table
):
...
...
circle/network/templates/network/columns/host-register.html
0 → 100644
View file @
ca137eda
{% load i18n %}
<a
href=
"{% url "
network
.
host_create
"
%}?
vlan=
{{
object
.
pk
}}&
amp
;
mac=
{{
record
.
mac
}}&
amp
;
hostname=
{{
record
.
hostname
}}&
amp
;
ipv4=
{{
record
.
ip
}}"
title=
"{% trans "
register
host
"
%}"
><i
class=
"fa fa-plus-circle"
></i></a>
circle/network/templates/network/columns/mac.html
deleted
100644 → 0
View file @
bad4afd4
{% load i18n %}
<span
title=
"{% blocktrans with vendor=record.hw_vendor|default:"
n
/
a
"
%}
Vendor:
{{
vendor
}}{%
endblocktrans
%}"
>
{{ record.mac }}
</span>
circle/network/templates/network/vlan-edit.html
View file @
ca137eda
...
@@ -19,9 +19,16 @@
...
@@ -19,9 +19,16 @@
</div>
</div>
<div
class=
"col-sm-6"
>
<div
class=
"col-sm-6"
>
<div
class=
"page-header"
>
<div
class=
"page-header"
>
<a
href=
"{% url "
network
.
host_create
"
%}?
vlan=
{{vlan.pk}}"
class=
"btn btn-success pull-right"
><i
class=
"fa fa-plus-circle"
></i>
{% trans "Create a new host" %}
</a>
<h3>
{% trans "Host list" %}
</h3>
<h3>
{% trans "Host list" %}
</h3>
</div>
</div>
{% render_table host_list %}
{% render_table host_list %}
<div
class=
"page-header"
>
<h3>
{% trans "Unregistered hosts" %}
</h3>
</div>
{% render_table dhcp_list %}
<div
class=
"page-header"
>
<div
class=
"page-header"
>
<h3>
{% trans "Manage access" %}
</h3>
<h3>
{% trans "Manage access" %}
</h3>
</div>
</div>
...
...
circle/network/views.py
View file @
ca137eda
...
@@ -15,11 +15,13 @@
...
@@ -15,11 +15,13 @@
# You should have received a copy of the GNU General Public License along
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from
netaddr
import
IPNetwork
from
django.views.generic
import
(
TemplateView
,
UpdateView
,
DeleteView
,
from
django.views.generic
import
(
TemplateView
,
UpdateView
,
DeleteView
,
CreateView
)
CreateView
)
from
django.core.exceptions
import
ValidationError
from
django.core.urlresolvers
import
reverse_lazy
from
django.core.urlresolvers
import
reverse_lazy
from
django.shortcuts
import
render
,
redirect
from
django.shortcuts
import
render
,
redirect
,
get_object_or_404
from
django.http
import
HttpResponse
from
django.http
import
HttpResponse
,
Http404
from
django_tables2
import
SingleTableView
from
django_tables2
import
SingleTableView
...
@@ -29,7 +31,7 @@ from vm.models import Interface
...
@@ -29,7 +31,7 @@ from vm.models import Interface
from
.tables
import
(
HostTable
,
VlanTable
,
SmallHostTable
,
DomainTable
,
from
.tables
import
(
HostTable
,
VlanTable
,
SmallHostTable
,
DomainTable
,
GroupTable
,
RecordTable
,
BlacklistItemTable
,
RuleTable
,
GroupTable
,
RecordTable
,
BlacklistItemTable
,
RuleTable
,
VlanGroupTable
,
SmallRuleTable
,
SmallGroupRuleTable
,
VlanGroupTable
,
SmallRuleTable
,
SmallGroupRuleTable
,
SmallRecordTable
,
SwitchPortTable
)
SmallRecordTable
,
SwitchPortTable
,
SmallDhcpTable
,
)
from
.forms
import
(
HostForm
,
VlanForm
,
DomainForm
,
GroupForm
,
RecordForm
,
from
.forms
import
(
HostForm
,
VlanForm
,
DomainForm
,
GroupForm
,
RecordForm
,
BlacklistItemForm
,
RuleForm
,
VlanGroupForm
,
SwitchPortForm
)
BlacklistItemForm
,
RuleForm
,
VlanGroupForm
,
SwitchPortForm
)
...
@@ -41,10 +43,36 @@ from braces.views import LoginRequiredMixin, SuperuserRequiredMixin
...
@@ -41,10 +43,36 @@ from braces.views import LoginRequiredMixin, SuperuserRequiredMixin
# from django.db.models import Q
# from django.db.models import Q
from
operator
import
itemgetter
from
operator
import
itemgetter
from
itertools
import
chain
from
itertools
import
chain
import
json
from
dashboard.views
import
AclUpdateView
from
dashboard.views
import
AclUpdateView
from
dashboard.forms
import
AclUserOrGroupAddForm
from
dashboard.forms
import
AclUserOrGroupAddForm
from
django.utils
import
simplejson
try
:
from
django.http
import
JsonResponse
except
ImportError
:
class
JsonResponse
(
HttpResponse
):
"""JSON response for Django < 1.7
https://gist.github.com/philippeowagner/3179eb475fe1795d6515
"""
def
__init__
(
self
,
content
,
mimetype
=
'application/json'
,
status
=
None
,
content_type
=
None
):
super
(
JsonResponse
,
self
)
.
__init__
(
content
=
simplejson
.
dumps
(
content
),
mimetype
=
mimetype
,
status
=
status
,
content_type
=
content_type
)
class
MagicMixin
(
object
):
def
get
(
self
,
*
args
,
**
kwargs
):
if
self
.
request
.
is_ajax
():
result
=
self
.
_get_ajax
(
*
args
,
**
kwargs
)
return
JsonResponse
({
k
:
unicode
(
result
[
k
]
or
""
)
for
k
in
result
})
else
:
return
super
(
MagicMixin
,
self
)
.
get
(
*
args
,
**
kwargs
)
class
InitialOwnerMixin
(
FormMixin
):
class
InitialOwnerMixin
(
FormMixin
):
def
get_initial
(
self
):
def
get_initial
(
self
):
...
@@ -310,6 +338,25 @@ class GroupDelete(LoginRequiredMixin, SuperuserRequiredMixin, DeleteView):
...
@@ -310,6 +338,25 @@ class GroupDelete(LoginRequiredMixin, SuperuserRequiredMixin, DeleteView):
return
context
return
context
class
HostMagicMixin
(
MagicMixin
):
def
_get_ajax
(
self
,
*
args
,
**
kwargs
):
GET
=
self
.
request
.
GET
result
=
{}
vlan
=
get_object_or_404
(
Vlan
.
objects
,
pk
=
GET
.
get
(
"vlan"
,
""
))
if
"ipv4"
in
GET
:
try
:
result
[
"ipv6"
]
=
vlan
.
convert_ipv4_to_ipv6
(
GET
[
"ipv4"
])
or
""
except
:
result
[
"ipv6"
]
=
""
else
:
try
:
result
.
update
(
vlan
.
get_new_address
())
except
ValidationError
:
result
[
"ipv4"
]
=
""
result
[
"ipv6"
]
=
""
return
result
class
HostList
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SingleTableView
):
class
HostList
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SingleTableView
):
model
=
Host
model
=
Host
table_class
=
HostTable
table_class
=
HostTable
...
@@ -331,15 +378,15 @@ class HostList(LoginRequiredMixin, SuperuserRequiredMixin, SingleTableView):
...
@@ -331,15 +378,15 @@ class HostList(LoginRequiredMixin, SuperuserRequiredMixin, SingleTableView):
return
data
return
data
class
HostDetail
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
class
HostDetail
(
HostMagicMixin
,
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
UpdateView
):
SuccessMessageMixin
,
UpdateView
):
model
=
Host
model
=
Host
template_name
=
"network/host-edit.html"
template_name
=
"network/host-edit.html"
form_class
=
HostForm
form_class
=
HostForm
success_message
=
_
(
u'Successfully modified host
%(hostname)
s!'
)
success_message
=
_
(
u'Successfully modified host
%(hostname)
s!'
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
_get_ajax
(
self
,
*
args
,
**
kwargs
):
if
request
.
is_ajax
()
:
if
"vlan"
not
in
self
.
request
.
GET
:
host
=
Host
.
objects
.
get
(
pk
=
kwargs
[
'pk'
])
host
=
Host
.
objects
.
get
(
pk
=
kwargs
[
'pk'
])
host
=
{
host
=
{
'hostname'
:
host
.
hostname
,
'hostname'
:
host
.
hostname
,
...
@@ -347,11 +394,13 @@ class HostDetail(LoginRequiredMixin, SuperuserRequiredMixin,
...
@@ -347,11 +394,13 @@ class HostDetail(LoginRequiredMixin, SuperuserRequiredMixin,
'ipv6'
:
str
(
host
.
ipv6
),
'ipv6'
:
str
(
host
.
ipv6
),
'fqdn'
:
host
.
get_fqdn
()
'fqdn'
:
host
.
get_fqdn
()
}
}
return
HttpResponse
(
json
.
dumps
(
host
),
return
host
content_type
=
"application/json"
)
else
:
else
:
self
.
object
=
self
.
get_object
()
return
super
(
HostDetail
,
self
)
.
_get_ajax
(
*
args
,
**
kwargs
)
return
super
(
HostDetail
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
()
return
super
(
HostDetail
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
pk
=
self
.
kwargs
.
get
(
'pk'
)
pk
=
self
.
kwargs
.
get
(
'pk'
)
...
@@ -402,13 +451,29 @@ class HostDetail(LoginRequiredMixin, SuperuserRequiredMixin,
...
@@ -402,13 +451,29 @@ class HostDetail(LoginRequiredMixin, SuperuserRequiredMixin,
return
reverse_lazy
(
'network.host'
,
kwargs
=
self
.
kwargs
)
return
reverse_lazy
(
'network.host'
,
kwargs
=
self
.
kwargs
)
class
HostCreate
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
class
HostCreate
(
HostMagicMixin
,
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
InitialOwnerMixin
,
CreateView
):
SuccessMessageMixin
,
InitialOwnerMixin
,
CreateView
):
model
=
Host
model
=
Host
template_name
=
"network/host-create.html"
template_name
=
"network/host-create.html"
form_class
=
HostForm
form_class
=
HostForm
success_message
=
_
(
u'Successfully created host
%(hostname)
s!'
)
success_message
=
_
(
u'Successfully created host
%(hostname)
s!'
)
def
get_initial
(
self
):
initial
=
super
(
HostCreate
,
self
)
.
get_initial
()
for
i
in
(
"vlan"
,
"mac"
,
"hostname"
):
if
i
in
self
.
request
.
GET
and
i
not
in
self
.
request
.
POST
:
initial
[
i
]
=
self
.
request
.
GET
[
i
]
if
"vlan"
in
initial
:
if
not
initial
[
'vlan'
]
.
isnumeric
():
raise
Http404
()
vlan
=
get_object_or_404
(
Vlan
.
objects
,
pk
=
initial
[
'vlan'
])
try
:
initial
.
update
(
vlan
.
get_new_address
())
except
ValidationError
as
e
:
messages
.
error
(
self
.
request
,
e
.
message
)
return
initial
class
HostDelete
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
DeleteView
):
class
HostDelete
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
DeleteView
):
model
=
Host
model
=
Host
...
@@ -644,7 +709,21 @@ class VlanAclUpdateView(AclUpdateView):
...
@@ -644,7 +709,21 @@ class VlanAclUpdateView(AclUpdateView):
model
=
Vlan
model
=
Vlan
class
VlanDetail
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
class
VlanMagicMixin
(
MagicMixin
):
def
_get_ajax
(
self
,
*
args
,
**
kwargs
):
GET
=
self
.
request
.
GET
result
=
{}
if
"network4"
in
GET
and
"network6"
in
GET
:
try
:
result
[
"ipv6_template"
],
result
[
"host_ipv6_prefixlen"
]
=
(
Vlan
.
_magic_ipv6_template
(
IPNetwork
(
GET
[
'network4'
]),
IPNetwork
(
GET
[
'network6'
])))
except
:
result
[
"ipv6_template"
]
=
result
[
"host_ipv6_prefixlen"
]
=
""
return
result
class
VlanDetail
(
VlanMagicMixin
,
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
UpdateView
):
SuccessMessageMixin
,
UpdateView
):
model
=
Vlan
model
=
Vlan
template_name
=
"network/vlan-edit.html"
template_name
=
"network/vlan-edit.html"
...
@@ -656,6 +735,7 @@ class VlanDetail(LoginRequiredMixin, SuperuserRequiredMixin,
...
@@ -656,6 +735,7 @@ class VlanDetail(LoginRequiredMixin, SuperuserRequiredMixin,
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
VlanDetail
,
self
)
.
get_context_data
(
**
kwargs
)
context
=
super
(
VlanDetail
,
self
)
.
get_context_data
(
**
kwargs
)
context
[
'host_list'
]
=
SmallHostTable
(
self
.
object
.
host_set
.
all
())
context
[
'host_list'
]
=
SmallHostTable
(
self
.
object
.
host_set
.
all
())
context
[
'dhcp_list'
]
=
SmallDhcpTable
(
self
.
object
.
get_dhcp_clients
())
context
[
'vlan_vid'
]
=
self
.
kwargs
.
get
(
'vid'
)
context
[
'vlan_vid'
]
=
self
.
kwargs
.
get
(
'vid'
)
context
[
'acl'
]
=
AclUpdateView
.
get_acl_data
(
context
[
'acl'
]
=
AclUpdateView
.
get_acl_data
(
self
.
object
,
self
.
request
.
user
,
'network.vlan-acl'
)
self
.
object
,
self
.
request
.
user
,
'network.vlan-acl'
)
...
@@ -665,7 +745,7 @@ class VlanDetail(LoginRequiredMixin, SuperuserRequiredMixin,
...
@@ -665,7 +745,7 @@ class VlanDetail(LoginRequiredMixin, SuperuserRequiredMixin,
success_url
=
reverse_lazy
(
'network.vlan_list'
)
success_url
=
reverse_lazy
(
'network.vlan_list'
)
class
VlanCreate
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
class
VlanCreate
(
VlanMagicMixin
,
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
InitialOwnerMixin
,
CreateView
):
SuccessMessageMixin
,
InitialOwnerMixin
,
CreateView
):
model
=
Vlan
model
=
Vlan
template_name
=
"network/vlan-create.html"
template_name
=
"network/vlan-create.html"
...
...
circle/vm/tests/test_models.py
View file @
ca137eda
...
@@ -177,6 +177,7 @@ class InterfaceTestCase(TestCase):
...
@@ -177,6 +177,7 @@ class InterfaceTestCase(TestCase):
d
.
save
()
d
.
save
()
v
=
Vlan
(
vid
=
55
,
network4
=
'127.0.0.1/8'
,
v
=
Vlan
(
vid
=
55
,
network4
=
'127.0.0.1/8'
,
network6
=
'2001::1/32'
,
domain
=
d
)
network6
=
'2001::1/32'
,
domain
=
d
)
v
.
clean
()
v
.
save
()
v
.
save
()
Interface
.
create
(
i
,
v
,
managed
=
True
,
owner
=
owner
)
Interface
.
create
(
i
,
v
,
managed
=
True
,
owner
=
owner
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment