Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
CIRCLE
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
94
Merge Requests
10
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 () {
e
.
stopImmediatePropagation
();
return
false
;
});
$
(
'[title]:not(.title-favourite)'
).
tooltip
();
$
(
'.title-favourite'
).
tooltip
({
'placement'
:
'right'
});
$
(
':input[title]'
).
tooltip
({
trigger
:
'focus'
,
placement
:
'auto right'
});
$
(
'
body
[title]:not(.title-favourite)'
).
tooltip
();
$
(
'
body
.title-favourite'
).
tooltip
({
'placement'
:
'right'
});
$
(
'
body
:input[title]'
).
tooltip
({
trigger
:
'focus'
,
placement
:
'auto right'
});
$
(
".knob"
).
knob
();
$
(
'[data-toggle="pill"]'
).
click
(
function
()
{
...
...
circle/dashboard/templates/dashboard/base.html
View file @
ca137eda
...
...
@@ -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/introjs/introjs.min.css"
>
<link
href=
"{{ STATIC_URL }}dashboard/dashboard.css"
rel=
"stylesheet"
>
{% block extra_link_2 %}{% endblock %}
{% endblock %}
...
...
circle/dashboard/templates/dashboard/index.html
View file @
ca137eda
...
...
@@ -3,6 +3,13 @@
{% 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 %}
<div
class=
"body-content dashboard-index"
>
<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 (
VmGraphView
,
NodeGraphView
,
NodeListGraphView
,
TransferInstanceOwnershipView
,
TransferInstanceOwnershipConfirmView
,
TransferTemplateOwnershipView
,
TransferTemplateOwnershipConfirmView
,
OpenSearchDescriptionView
,
)
from
.views.vm
import
vm_ops
,
vm_mass_ops
from
.views.node
import
node_ops
...
...
@@ -221,6 +222,8 @@ urlpatterns = patterns(
name
=
"dashboard.views.client-check"
),
url
(
r'^token-login/(?P<token>.*)/$'
,
TokenLogin
.
as_view
(),
name
=
"dashboard.views.token-login"
),
url
(
r'^vm/opensearch.xml$'
,
OpenSearchDescriptionView
.
as_view
(),
name
=
"dashboard.views.vm-opensearch"
),
)
urlpatterns
+=
patterns
(
...
...
circle/dashboard/views/index.py
View file @
ca137eda
...
...
@@ -19,6 +19,7 @@ from __future__ import unicode_literals, absolute_import
import
logging
from
django.core.cache
import
get_cache
from
django.core.urlresolvers
import
reverse
from
django.conf
import
settings
from
django.contrib.auth.models
import
Group
from
django.views.generic
import
TemplateView
...
...
@@ -121,3 +122,15 @@ class HelpView(TemplateView):
ctx
.
update
({
"saml"
:
hasattr
(
settings
,
"SAML_CONFIG"
),
"store"
:
settings
.
STORE_URL
})
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 @@
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from
string
import
ascii_letters
from
django.core.exceptions
import
ValidationError
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
...
...
@@ -22,7 +23,7 @@ from django.utils.ipv6 import is_valid_ipv6_address
from
south.modelsinspector
import
add_introspection_rules
from
django
import
forms
from
netaddr
import
(
IPAddress
,
IPNetwork
,
AddrFormatError
,
ZEROFILL
,
EUI
,
mac_unix
)
EUI
,
mac_unix
,
AddrConversionError
)
import
re
...
...
@@ -31,7 +32,6 @@ domain_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]+)$'
)
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
):
...
...
@@ -246,15 +246,60 @@ def val_reverse_domain(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
):
"""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
)
"""Validate whether the parameter is a valid ipv6 template.
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
):
...
...
@@ -284,12 +329,3 @@ def val_mx(value):
domain_re
.
match
(
mx
[
1
])):
raise
ValidationError
(
_
(
"Bad MX address format. "
"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 @@
# You should have received a copy of the GNU General Public License along
# 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
from
netaddr
import
IPSet
,
EUI
,
IPNetwork
import
random
from
django.contrib.auth.models
import
User
from
django.db
import
models
...
...
@@ -28,15 +30,17 @@ from django.utils.translation import ugettext_lazy as _
from
firewall.fields
import
(
MACAddressField
,
val_alfanum
,
val_reverse_domain
,
val_ipv6_template
,
val_domain
,
val_ipv4
,
val_domain_wildcard
,
val_ipv6
,
val_mx
,
convert_ipv4_to_ipv6
,
val_ipv6
,
val_mx
,
IPNetworkField
,
IPAddressField
)
from
django.core.validators
import
MinValueValidator
,
MaxValueValidator
import
django.conf
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
firewall.tasks.local_tasks
import
reloadtask
from
firewall.tasks.remote_tasks
import
get_dhcp_clients
from
.iptables
import
IptRule
from
acl.models
import
AclBase
...
...
@@ -360,9 +364,19 @@ class Vlan(AclBase, models.Model):
'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"
)
ipv6_template
=
models
.
TextField
(
validators
=
[
val_ipv6_template
],
verbose_name
=
_
(
'ipv6 template'
),
default
=
"2001:738:2001:4031:
%(b)
d:
%(c)
d:
%(d)
d:0"
)
blank
=
True
,
help_text
=
_
(
'Template for translating IPv4 addresses to IPv6. '
'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'
),
help_text
=
_
(
'The address range of the DHCP pool: '
...
...
@@ -377,6 +391,87 @@ class Vlan(AclBase, models.Model):
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
,
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
):
return
"
%
s -
%
s"
%
(
"managed"
if
self
.
managed
else
"unmanaged"
,
self
.
name
)
...
...
@@ -402,7 +497,7 @@ class Vlan(AclBase, models.Model):
logger
.
debug
(
"Found unused IPv4 address
%
s."
,
ipv4
)
ipv6
=
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
:
continue
else
:
...
...
@@ -411,6 +506,20 @@ class Vlan(AclBase, models.Model):
else
:
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
):
"""
...
...
@@ -581,8 +690,7 @@ class Host(models.Model):
def
save
(
self
,
*
args
,
**
kwargs
):
if
not
self
.
id
and
self
.
ipv6
==
"auto"
:
self
.
ipv6
=
convert_ipv4_to_ipv6
(
self
.
vlan
.
ipv6_template
,
self
.
ipv4
)
self
.
ipv6
=
self
.
vlan
.
convert_ipv4_to_ipv6
(
self
.
ipv4
)
self
.
full_clean
()
super
(
Host
,
self
)
.
save
(
*
args
,
**
kwargs
)
...
...
@@ -835,7 +943,7 @@ class Firewall(models.Model):
return
self
.
name
@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.
Throws Exception if there is no worker on the queue.
...
...
@@ -848,6 +956,20 @@ class Firewall(models.Model):
else
:
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
):
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):
@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
circle/firewall/tests/test_firewall.py
View file @
ca137eda
...
...
@@ -78,6 +78,7 @@ class GetNewAddressTestCase(TestCase):
self
.
vlan
=
Vlan
(
vid
=
1
,
name
=
'test'
,
network4
=
'10.0.0.0/29'
,
network6
=
'2001:738:2001:4031::/80'
,
domain
=
d
,
owner
=
self
.
u1
)
self
.
vlan
.
clean
()
self
.
vlan
.
save
()
self
.
vlan
.
host_set
.
all
()
.
delete
()
for
i
in
[
1
]
+
range
(
3
,
6
):
...
...
@@ -85,6 +86,9 @@ class GetNewAddressTestCase(TestCase):
ipv4
=
'10.0.0.
%
d'
%
i
,
vlan
=
self
.
vlan
,
owner
=
self
.
u1
)
.
save
()
def
tearDown
(
self
):
self
.
vlan
.
delete
()
def
test_new_addr_w_empty_vlan
(
self
):
self
.
vlan
.
host_set
.
all
()
.
delete
()
self
.
vlan
.
get_new_address
()
...
...
@@ -96,12 +100,6 @@ class GetNewAddressTestCase(TestCase):
owner
=
self
.
u1
)
.
save
()
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
):
used_v4
=
IPSet
(
self
.
vlan
.
host_set
.
values_list
(
'ipv4'
,
flat
=
True
))
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 ""
msgstr ""
"Project-Id-Version: \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"
"Last-Translator: Mate Ory <ory.mate@ik.bme.hu>\n"
"Language-Team: Hungarian <cloud@ik.bme.hu>\n"
...
...
@@ -17,7 +17,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\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.0aecd87e873a.js:3443
#: static_collected/all.0db607331718.js:3443
...
...
@@ -34,13 +34,13 @@ msgstr ""
#: static_collected/dashboard/dashboard.be8725cd91bf.js:68
#: static_collected/dashboard/dashboard.e740d80401b2.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!"
msgstr "Válasszon a folytatáshoz."
#: dashboard/static/dashboard/dashboard.js:2
59
#: dashboard/static/dashboard/dashboard.js:3
07
#: dashboard/static/dashboard/dashboard.js:3
17
#: dashboard/static/dashboard/dashboard.js:2
74
#: dashboard/static/dashboard/dashboard.js:3
22
#: dashboard/static/dashboard/dashboard.js:3
32
#: static_collected/all.047675ebf594.js:3633
#: static_collected/all.047675ebf594.js:3681
#: static_collected/all.047675ebf594.js:3691
...
...
@@ -88,9 +88,9 @@ msgstr "Válasszon a folytatáshoz."
#: static_collected/dashboard/dashboard.fe0a2f126346.js:258
#: static_collected/dashboard/dashboard.fe0a2f126346.js:306
#: static_collected/dashboard/dashboard.fe0a2f126346.js:316
#: static_collected/dashboard/dashboard.js:2
59
#: static_collected/dashboard/dashboard.js:3
07
#: static_collected/dashboard/dashboard.js:3
17
#: static_collected/dashboard/dashboard.js:2
74
#: static_collected/dashboard/dashboard.js:3
22
#: static_collected/dashboard/dashboard.js:3
32
msgid "No result"
msgstr "Nincs eredmény"
...
...
@@ -129,10 +129,12 @@ msgid "Unknown error."
msgstr "Ismeretlen hiba."
#: dashboard/static/dashboard/template-list.js:103
#: static_collected/dashboard/template-list.js:103
msgid "Only the owners can delete the selected object."
msgstr "Csak a tulajdonos törölheti a kiválasztott elemet."
#: dashboard/static/dashboard/template-list.js:105
#: static_collected/dashboard/template-list.js:105
msgid "An error occurred. ("
msgstr "Hiba történt. ("
...
...
@@ -206,11 +208,12 @@ msgstr "Jelszó megjelenítése"
#: static_collected/vm-detail.js:6391
#: static_collected/dashboard/vm-tour.1562cc89a659.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"
msgstr "Tovább"
#: dashboard/static/dashboard/vm-tour.js:7
#: static_collected/dashboard/vm-tour.js:7
msgid "Previous"
msgstr "Vissza"
...
...
@@ -226,15 +229,17 @@ msgstr "Vissza"
#: static_collected/vm-detail.js:6395
#: static_collected/dashboard/vm-tour.1562cc89a659.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"
msgstr "Befejezés"
#: dashboard/static/dashboard/vm-tour.js:9
#: static_collected/dashboard/vm-tour.js:9
msgid "Done"
msgstr "Kész"
#: dashboard/static/dashboard/vm-tour.js:56
#: static_collected/dashboard/vm-tour.js:56
msgid ""
"Welcome to the template tutorial. In this quick tour, we are going to show "
"you how to do the steps described above."
...
...
@@ -254,7 +259,7 @@ msgstr ""
#: static_collected/vm-detail.js:6404
#: static_collected/dashboard/vm-tour.1562cc89a659.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 ""
"For the next tour step press the \"Next\" button or the right arrow (or "
"\"Back\" button/left arrow for the previous step)."
...
...
@@ -263,6 +268,7 @@ msgstr ""
"nyílbillentyűket."
#: dashboard/static/dashboard/vm-tour.js:61
#: static_collected/dashboard/vm-tour.js:61
msgid ""
"In this tab you can extend the expiration date of your virtual machine, add "
"tags and modify the name and description."
...
...
@@ -271,24 +277,26 @@ msgstr ""
"vagy módosíthatja a nevét, leírását."
#: dashboard/static/dashboard/vm-tour.js:65
#: static_collected/dashboard/vm-tour.js:65
msgid ""
"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 "
"template."
msgstr ""
"Kérjük, adjon meg egy informatív leírást. A név megváltoztatása is "
"ajánlott, azonban a mentéskor is van a sablon nevének "
"megválasztására."
"Kérjük, adjon meg egy informatív leírást. A név megváltoztatása is ajánlott, "
"azonban a mentéskor is van a sablon nevének megválasztására."
#: dashboard/static/dashboard/vm-tour.js:69
#: static_collected/dashboard/vm-tour.js:69
msgid ""
"You can change the lease to extend the expiration date. This will be the "
"lease of the new template."
msgstr ""
"Megváltoztathatja a bérleti módot is a lejárat bővítéséhez. Az gép "
"
bérleti
módját örökli majd a sablon is."
"Megváltoztathatja a bérleti módot is a lejárat bővítéséhez. Az gép
bérleti
"
"módját örökli majd a sablon is."
#: dashboard/static/dashboard/vm-tour.js:73
#: static_collected/dashboard/vm-tour.js:73
msgid ""
"On the resources tab you can edit the CPU/RAM options and add/remove disks "
"if you have required permissions."
...
...
@@ -308,7 +316,7 @@ msgstr ""
#: static_collected/vm-detail.js:6438
#: static_collected/dashboard/vm-tour.1562cc89a659.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"
msgstr "CPU prioritás"
...
...
@@ -324,7 +332,7 @@ msgstr "CPU prioritás"
#: static_collected/vm-detail.js:6438
#: static_collected/dashboard/vm-tour.1562cc89a659.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"
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/dashboard/vm-tour.1562cc89a659.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"
msgstr "CPU-k száma"
...
...
@@ -356,7 +364,7 @@ msgstr "CPU-k száma"
#: static_collected/vm-detail.js:6439
#: static_collected/dashboard/vm-tour.1562cc89a659.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."
msgstr "A CPU-magok száma."
...
...
@@ -372,7 +380,7 @@ msgstr "A CPU-magok száma."
#: static_collected/vm-detail.js:6440
#: static_collected/dashboard/vm-tour.1562cc89a659.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"
msgstr "RAM mennyiség"
...
...
@@ -388,7 +396,7 @@ msgstr "RAM mennyiség"
#: static_collected/vm-detail.js:6440
#: static_collected/dashboard/vm-tour.1562cc89a659.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."
msgstr "a memória mennyisége."
...
...
@@ -404,7 +412,7 @@ msgstr "a memória mennyisége."
#: static_collected/vm-detail.js:6451
#: static_collected/dashboard/vm-tour.1562cc89a659.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 ""
"You can add empty disks, download new ones and remove existing ones here."
msgstr ""
...
...
@@ -423,7 +431,7 @@ msgstr ""
#: static_collected/vm-detail.js:6462
#: static_collected/dashboard/vm-tour.1562cc89a659.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."
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
#: static_collected/vm-detail.js:6474
#: static_collected/dashboard/vm-tour.1562cc89a659.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."
msgstr "A virtuális gép elindítása."
#: dashboard/static/dashboard/vm-tour.js:113
#: static_collected/dashboard/vm-tour.js:113
msgid ""
"Use the CIRCLE client or the connection string to connect to the virtual "
"machine."
msgstr ""
"Használja a CIRCLE klienst vagy a kapcsolódási adatokat a "
"v
irtuális géphez v
aló csatlakozáshoz."
"Használja a CIRCLE klienst vagy a kapcsolódási adatokat a
virtuális géphez
"
"való csatlakozáshoz."
#: dashboard/static/dashboard/vm-tour.js:117
#: static_collected/vm-detail.09737c69abc3.js:5954
...
...
@@ -463,7 +472,7 @@ msgstr ""
#: static_collected/vm-detail.js:6490
#: static_collected/dashboard/vm-tour.1562cc89a659.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 ""
"After you have connected to the virtual machine do your modifications then "
"log off."
...
...
@@ -483,7 +492,7 @@ msgstr ""
#: static_collected/vm-detail.js:6498
#: static_collected/dashboard/vm-tour.1562cc89a659.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 ""
"Press the \"Save as template\" button and wait until the activity finishes."
msgstr ""
...
...
@@ -491,12 +500,11 @@ msgstr ""
"elkészül."
#: dashboard/static/dashboard/vm-tour.js:125
#: static_collected/dashboard/vm-tour.js:125
msgid ""
"This is the last message, if something is not clear you can do the the tour "
"again."
msgstr ""
"A túra véget ért. Ha valami nem érthető, újrakezdheti az "
"útmutatót."
msgstr "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
#: static_collected/all.0aecd87e873a.js:5309
...
...
@@ -617,7 +625,6 @@ msgstr "Biztosan törli ezt az eszközt?"
#: static_collected/vm-detail.js:6389
#: static_collected/dashboard/vm-tour.1562cc89a659.js:20
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:20
#: static_collected/dashboard/vm-tour.js:20
msgid "Prev"
msgstr "Vissza"
...
...
@@ -632,7 +639,6 @@ msgstr "Vissza"
#: static_collected/vm-detail.js:6402
#: static_collected/dashboard/vm-tour.1562cc89a659.js:33
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:33
#: static_collected/dashboard/vm-tour.js:33
msgid "Template Tutorial Tour"
msgstr "Sablon-kalauz"
...
...
@@ -647,7 +653,6 @@ msgstr "Sablon-kalauz"
#: static_collected/vm-detail.js:6403
#: static_collected/dashboard/vm-tour.1562cc89a659.js:34
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:34
#: static_collected/dashboard/vm-tour.js:34
msgid ""
"Welcome to the template tutorial. In this quick tour, we gonna show you how "
"to do the steps described above."
...
...
@@ -665,7 +670,6 @@ msgstr ""
#: static_collected/vm-detail.js:6405
#: static_collected/dashboard/vm-tour.1562cc89a659.js:36
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:36
#: static_collected/dashboard/vm-tour.js:36
msgid ""
"During the tour please don't try the functions because it may lead to "
"graphical glitches, however "
...
...
@@ -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/dashboard/vm-tour.1562cc89a659.js:45
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:45
#: static_collected/dashboard/vm-tour.js:45
msgid "Home tab"
msgstr "Kezdőoldal"
...
...
@@ -697,7 +700,6 @@ msgstr "Kezdőoldal"
#: static_collected/vm-detail.js:6415
#: static_collected/dashboard/vm-tour.1562cc89a659.js:46
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:46
#: static_collected/dashboard/vm-tour.js:46
msgid ""
"In this tab you can tag your virtual machine and modify the name and "
"description."
...
...
@@ -716,7 +718,6 @@ msgstr ""
#: static_collected/vm-detail.js:6424
#: static_collected/dashboard/vm-tour.1562cc89a659.js:55
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:55
#: static_collected/dashboard/vm-tour.js:55
msgid "Resources tab"
msgstr "Erőforrások lap"
...
...
@@ -731,7 +732,6 @@ msgstr "Erőforrások lap"
#: static_collected/vm-detail.js:6427
#: static_collected/dashboard/vm-tour.1562cc89a659.js:58
#: static_collected/dashboard/vm-tour.7b4cf596f543.js:58
#: static_collected/dashboard/vm-tour.js:58
msgid ""
"On the resources tab you can edit the CPU/RAM options and add/remove disks!"
msgstr ""
...
...
@@ -749,7 +749,6 @@ msgstr ""