From 38ae62d093811bde4bd8848deb124e3d607dcfcb Mon Sep 17 00:00:00 2001
From: catborise
Date: Wed, 30 Oct 2019 11:02:38 +0300
Subject: [PATCH 1/5] define network with XML is related with network object.
It is converted
---
networks/views.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/networks/views.py b/networks/views.py
index 71a0b9a..0bc9c1d 100644
--- a/networks/views.py
+++ b/networks/views.py
@@ -161,7 +161,7 @@ def network(request, compute_id, pool):
compute.login,
compute.password,
compute.type)
- conn.define_network(edit_xml)
+ new_conn.define_network(edit_xml)
if conn.is_active():
messages.success(request, _("Network XML is changed. Stop and start network to activate new config."))
else:
From 568ff92449495b7dcec77e8f6724cf8bb3712480 Mon Sep 17 00:00:00 2001
From: catborise
Date: Wed, 30 Oct 2019 11:05:00 +0300
Subject: [PATCH 2/5] libvirt does not have the connection close reason
contants anymore. pep8 conventions apply
---
vrtManager/connection.py | 44 +++++++++++++++++-----------------------
1 file changed, 19 insertions(+), 25 deletions(-)
diff --git a/vrtManager/connection.py b/vrtManager/connection.py
index 278232c..062ee91 100644
--- a/vrtManager/connection.py
+++ b/vrtManager/connection.py
@@ -124,16 +124,7 @@ class wvmConnection(object):
# on server shutdown libvirt module gets freed before the close callbacks are called
# so we just check here if it is still present
if libvirt is not None:
- if (reason == libvirt.VIR_CONNECT_CLOSE_REASON_ERROR):
- self.last_error = 'connection closed: Misc I/O error'
- elif (reason == libvirt.VIR_CONNECT_CLOSE_REASON_EOF):
- self.last_error = 'connection closed: End-of-file from server'
- elif (reason == libvirt.VIR_CONNECT_CLOSE_REASON_KEEPALIVE):
- self.last_error = 'connection closed: Keepalive timer triggered'
- elif (reason == libvirt.VIR_CONNECT_CLOSE_REASON_CLIENT):
- self.last_error = 'connection closed: Client requested it'
- else:
- self.last_error = 'connection closed: Unknown error'
+ self.last_error = reason
# prevent other threads from using the connection (in the future)
self.connection = None
@@ -255,11 +246,11 @@ class wvmConnectionManager(object):
"""
self._connections_lock.acquireRead()
try:
- if (host in self._connections):
+ if host in self._connections:
connections = self._connections[host]
for connection in connections:
- if (connection.login == login and connection.passwd == passwd and connection.type == conn):
+ if connection.login == login and connection.passwd == passwd and connection.type == conn:
return connection
finally:
self._connections_lock.release()
@@ -278,13 +269,13 @@ class wvmConnectionManager(object):
connection = self._search_connection(host, login, passwd, conn)
- if (connection is None):
+ if connection is None:
self._connections_lock.acquireWrite()
try:
# we have to search for the connection again after aquireing the write lock
# as the thread previously holding the write lock may have already added our connection
connection = self._search_connection(host, login, passwd, conn)
- if (connection is None):
+ if connection is None:
# create a new connection if a matching connection does not already exist
connection = wvmConnection(host, login, passwd, conn)
@@ -317,7 +308,7 @@ class wvmConnectionManager(object):
socket_host.settimeout(1)
if conn_type == CONN_SSH:
if ':' in hostname:
- LIBVIRT_HOST, PORT = (hostname).split(":")
+ LIBVIRT_HOST, PORT = hostname.split(":")
PORT = int(PORT)
else:
PORT = SSH_PORT
@@ -332,6 +323,7 @@ class wvmConnectionManager(object):
except Exception as err:
return err
+
connection_manager = wvmConnectionManager(
settings.LIBVIRT_KEEPALIVE_INTERVAL if hasattr(settings, 'LIBVIRT_KEEPALIVE_INTERVAL') else 5,
settings.LIBVIRT_KEEPALIVE_COUNT if hasattr(settings, 'LIBVIRT_KEEPALIVE_COUNT') else 5
@@ -368,7 +360,7 @@ class wvmConnect(object):
minor = ver / 1000
ver = ver % 1000
release = ver
- return "%s.%s.%s" % (major,minor,release)
+ return "%s.%s.%s" % (major, minor, release)
def get_lib_version(self):
ver = self.wvm.getLibVersion()
@@ -432,7 +424,7 @@ class wvmConnect(object):
for arch in ctx.xpath('/capabilities/guest/arch'):
domain_types = arch.xpath('domain/@type')
arch_name = arch.xpath('@name')[0]
- result[arch_name]= domain_types
+ result[arch_name] = domain_types
return result
return util.get_xml_path(self.get_cap_xml(), func=hypervisors)
@@ -446,7 +438,7 @@ class wvmConnect(object):
for arch in ctx.xpath('/capabilities/guest/arch'):
emulator = arch.xpath('emulator')
arch_name = arch.xpath('@name')[0]
- result[arch_name]= emulator
+ result[arch_name] = emulator
return result
return util.get_xml_path(self.get_cap_xml(), func=emulators)
@@ -460,8 +452,8 @@ class wvmConnect(object):
def get_bus_list(ctx):
result = []
for disk_enum in ctx.xpath('/domainCapabilities/devices/disk/enum'):
- if disk_enum.xpath("@name")[0] == "bus":
- for values in disk_enum: result.append(values.text)
+ if disk_enum.xpath("@name")[0] == "bus":
+ for values in disk_enum: result.append(values.text)
return result
# return [ 'ide', 'scsi', 'usb', 'virtio' ]
@@ -482,11 +474,11 @@ class wvmConnect(object):
def get_image_formats(self):
"""Get available image formats"""
- return [ 'raw', 'qcow', 'qcow2' ]
+ return ['raw', 'qcow', 'qcow2']
def get_file_extensions(self):
"""Get available image filename extensions"""
- return [ 'img', 'qcow', 'qcow2' ]
+ return ['img', 'qcow', 'qcow2']
def get_video(self):
""" Get available graphics video types """
@@ -496,7 +488,7 @@ class wvmConnect(object):
if video_enum.xpath("@name")[0] == "modelType":
for values in video_enum: result.append(values.text)
return result
- return util.get_xml_path(self.get_dom_cap_xml(),func=get_video_list)
+ return util.get_xml_path(self.get_dom_cap_xml(), func=get_video_list)
def get_iface(self, name):
return self.wvm.interfaceLookupByName(name)
@@ -560,6 +552,7 @@ class wvmConnect(object):
def get_host_instances(self, raw_mem_size=False):
vname = {}
+
def get_info(doc):
mem = util.get_xpath(doc, "/domain/currentMemory")
mem = int(mem) / 1024
@@ -574,7 +567,7 @@ class wvmConnect(object):
title = title if title else ''
description = util.get_xpath(doc, "/domain/description")
description = description if description else ''
- return (mem, vcpu, title, description)
+ return mem, vcpu, title, description
for name in self.get_instances():
dom = self.get_instance(name)
xml = dom.XMLDesc(0)
@@ -592,6 +585,7 @@ class wvmConnect(object):
def get_user_instances(self, name):
dom = self.get_instance(name)
xml = dom.XMLDesc(0)
+
def get_info(ctx):
mem = util.get_xpath(ctx, "/domain/currentMemory")
mem = int(mem) / 1024
@@ -604,7 +598,7 @@ class wvmConnect(object):
title = title if title else ''
description = util.get_xpath(ctx, "/domain/description")
description = description if description else ''
- return (mem, vcpu, title, description)
+ return mem, vcpu, title, description
(mem, vcpu, title, description) = util.get_xml_path(xml, func=get_info)
return {
'name': dom.name(),
From f3f4f0afe801d4bcdb44466e5d83ed4dbb1ae29b Mon Sep 17 00:00:00 2001
From: catborise
Date: Wed, 30 Oct 2019 11:05:50 +0300
Subject: [PATCH 3/5] Fix typos. Code Inspection for pep8 conventions
---
instances/views.py | 10 +++++++---
interfaces/views.py | 1 +
nwfilters/views.py | 31 +++++++++++++++----------------
secrets/views.py | 1 +
vrtManager/IPy.py | 16 ++++++++--------
vrtManager/instance.py | 8 +++++---
6 files changed, 37 insertions(+), 30 deletions(-)
diff --git a/instances/views.py b/instances/views.py
index 1a1c5c0..474bfd2 100644
--- a/instances/views.py
+++ b/instances/views.py
@@ -73,6 +73,7 @@ def allinstances(request):
def instances(request, compute_id):
"""
:param request:
+ :param compute_id
:return:
"""
all_host_vms = {}
@@ -224,9 +225,9 @@ def instance(request, compute_id, vname):
def get_network_tuple(network_source_str):
network_source_pack = network_source_str.split(":", 1)
if len(network_source_pack) > 1:
- return (network_source_pack[1], network_source_pack[0])
+ return network_source_pack[1], network_source_pack[0]
else:
- return (network_source_pack[0], 'net')
+ return network_source_pack[0], 'net'
def migrate_instance(new_compute, instance, live=False, unsafe=False, xml_del=False, offline=False):
status = connection_manager.host_is_up(new_compute.type, new_compute.hostname)
@@ -1104,10 +1105,13 @@ def instances_actions(request):
return HttpResponseRedirect(request.get_full_path())
return HttpResponseRedirect(request.get_full_path())
+
@login_required
def inst_graph(request, compute_id, vname):
"""
:param request:
+ :param compute_id:
+ :param vname:
:return:
"""
json_blk = []
@@ -1298,7 +1302,7 @@ def delete_instance(instance, delete_disk=False):
conn.delete()
instance.delete()
- print("Instance {} on compute {} sucessfully deleted".format(instance_name, compute.hostname))
+ print("Instance {} on compute {} successfully deleted".format(instance_name, compute.hostname))
except libvirtError as lib_err:
print("Error removing instance {} on compute {}".format(instance_name, compute.hostname))
diff --git a/interfaces/views.py b/interfaces/views.py
index f71289c..acbf440 100644
--- a/interfaces/views.py
+++ b/interfaces/views.py
@@ -61,6 +61,7 @@ def interfaces(request, compute_id):
def interface(request, compute_id, iface):
"""
:param request:
+ :param compute_id:
:param iface:
:return:
"""
diff --git a/nwfilters/views.py b/nwfilters/views.py
index c0dd8d8..6f2529b 100644
--- a/nwfilters/views.py
+++ b/nwfilters/views.py
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.utils.translation import ugettext_lazy as _
@@ -19,6 +18,7 @@ from logs.views import addlogmsg
def nwfilters(request, compute_id):
"""
:param request:
+ :param compute_id:
:return:
"""
@@ -31,9 +31,9 @@ def nwfilters(request, compute_id):
try:
conn = wvmNWFilters(compute.hostname,
- compute.login,
- compute.password,
- compute.type)
+ compute.login,
+ compute.password,
+ compute.type)
if request.method == 'POST':
if 'create_nwfilter' in request.POST:
@@ -63,7 +63,7 @@ def nwfilters(request, compute_id):
addlogmsg(request.user.username, compute.hostname, lib_err.message)
if 'del_nwfilter' in request.POST:
- name = request.POST.get('nwfiltername','')
+ name = request.POST.get('nwfiltername', '')
msg = _("Deleting NWFilter: %s" % name)
in_use = False
nwfilter = conn.get_nwfilter(name)
@@ -71,7 +71,6 @@ def nwfilters(request, compute_id):
is_conn = wvmInstances(compute.hostname, compute.login, compute.password, compute.type)
instances = is_conn.get_instances()
for inst in instances:
- # if in_use: break
i_conn = wvmInstance(compute.hostname, compute.login, compute.password, compute.type, inst)
dom_filterrefs = i_conn.get_filterrefs()
@@ -90,10 +89,10 @@ def nwfilters(request, compute_id):
if 'cln_nwfilter' in request.POST:
- name = request.POST.get('nwfiltername','')
+ name = request.POST.get('nwfiltername', '')
cln_name = request.POST.get('cln_name', name + '-clone')
- conn.clone_nwfilter(name,cln_name)
+ conn.clone_nwfilter(name, cln_name)
msg = _("Cloning NWFilter %s as %s" % (name, cln_name))
addlogmsg(request.user.username, compute.hostname, msg)
@@ -122,14 +121,14 @@ def nwfilter(request, compute_id, nwfltr):
try:
nwfilter = wvmNWFilter(compute.hostname,
- compute.login,
- compute.password,
- compute.type,
- nwfltr)
+ compute.login,
+ compute.password,
+ compute.type,
+ nwfltr)
conn = wvmNWFilters(compute.hostname,
- compute.login,
- compute.password,
- compute.type)
+ compute.login,
+ compute.password,
+ compute.type)
for nwf in conn.get_nwfilters():
nwfilters_all.append(conn.get_nwfilter_info(nwf))
@@ -208,4 +207,4 @@ def nwfilter(request, compute_id, nwfltr):
except Exception as error_msg:
error_messages.append(error_msg)
- return render(request, 'nwfilter.html', locals())
\ No newline at end of file
+ return render(request, 'nwfilter.html', locals())
diff --git a/secrets/views.py b/secrets/views.py
index 90e5e36..efc0a09 100644
--- a/secrets/views.py
+++ b/secrets/views.py
@@ -12,6 +12,7 @@ from libvirt import libvirtError
def secrets(request, compute_id):
"""
:param request:
+ :param compute_id:
:return:
"""
diff --git a/vrtManager/IPy.py b/vrtManager/IPy.py
index 6dbdf6b..b157f3d 100644
--- a/vrtManager/IPy.py
+++ b/vrtManager/IPy.py
@@ -318,9 +318,9 @@ class IPint(object):
(self._ipversion == 6 and self._prefixlen == 128):
if self.NoPrefixForSingleIp:
want = 0
- if want == None:
+ if want is None:
want = self.WantPrefixLen
- if want == None:
+ if want is None:
want = 1
if want:
if want == 2:
@@ -354,7 +354,7 @@ class IPint(object):
"""
bits = _ipVersionToLen(self._ipversion)
- if self.WantPrefixLen == None and wantprefixlen == None:
+ if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 0
ret = _intToBin(self.ip)
return '0' * (bits - len(ret)) + ret + self._printPrefix(wantprefixlen)
@@ -370,7 +370,7 @@ class IPint(object):
'ffff:ffff:ffff:ffff:ffff:f:f:fffc/127'
"""
- if self.WantPrefixLen == None and wantprefixlen == None:
+ if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 1
if self._ipversion == 4:
@@ -413,7 +413,7 @@ class IPint(object):
2001:658:22a:cafe:200:0:0:1
"""
- if self.WantPrefixLen == None and wantprefixlen == None:
+ if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 1
if self._ipversion == 4:
@@ -434,7 +434,7 @@ class IPint(object):
2001:0658:022a:cafe:0200:0000:0000:0001
"""
- if self.WantPrefixLen == None and wantprefixlen == None:
+ if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 1
return intToIp(self.ip, self._ipversion) + self._printPrefix(wantprefixlen)
@@ -448,7 +448,7 @@ class IPint(object):
0x20010658022acafe0200000000000001
"""
- if self.WantPrefixLen == None and wantprefixlen == None:
+ if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 0
x = '0x%x' % self.ip
@@ -463,7 +463,7 @@ class IPint(object):
42540616829182469433547762482097946625
"""
- if self.WantPrefixLen == None and wantprefixlen == None:
+ if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 0
x = '%d' % self.ip
diff --git a/vrtManager/instance.py b/vrtManager/instance.py
index eb4147f..c929160 100644
--- a/vrtManager/instance.py
+++ b/vrtManager/instance.py
@@ -247,7 +247,7 @@ class wvmInstance(wvmConnect):
def get_disk_devices(self):
def disks(doc):
result = []
- dev = volume = storage = src_file = None
+ dev = volume = storage = src_file = bus = None
disk_format = used_size = disk_size = disk_cache = None
for disk in doc.xpath('/domain/devices/disk'):
@@ -288,7 +288,7 @@ class wvmInstance(wvmConnect):
def get_media_devices(self):
def disks(doc):
result = []
- dev = volume = storage = None
+ dev = volume = storage = bus = None
src_file = None
for media in doc.xpath('/domain/devices/disk'):
device = media.xpath('@device')[0]
@@ -341,6 +341,7 @@ class wvmInstance(wvmConnect):
def get_bootorder(self):
boot_order = {}
+ type = target = None
tree = ElementTree.fromstring(self._XMLDesc(0))
os = tree.find('os')
boot = os.findall('boot')
@@ -363,7 +364,7 @@ class wvmInstance(wvmConnect):
devices = tree.find('devices')
for dev in devices:
- dev_target = dev_type = dev_device = dev_alias = None
+ dev_target = None
boot_dev = dev.find('boot')
if boot_dev is not None:
idx = boot_dev.get('order')
@@ -439,6 +440,7 @@ class wvmInstance(wvmConnect):
disk.insert(2, src_media)
return True
+ vol = None
storages = self.get_storages(only_actives=True)
for storage in storages:
stg = self.get_storage(storage)
From 0738ec7ec48710c34bd1a525b270ee2153dcaa07 Mon Sep 17 00:00:00 2001
From: catborise
Date: Mon, 4 Nov 2019 12:03:13 +0300
Subject: [PATCH 4/5] adds bridge slave list to details of interface
---
interfaces/templates/interface.html | 34 ++++++++++++++++++++++++++---
interfaces/views.py | 1 +
vrtManager/interface.py | 30 +++++++++++++++++++++++--
3 files changed, 60 insertions(+), 5 deletions(-)
diff --git a/interfaces/templates/interface.html b/interfaces/templates/interface.html
index 1693d81..2ac89d9 100644
--- a/interfaces/templates/interface.html
+++ b/interfaces/templates/interface.html
@@ -38,12 +38,12 @@
{% trans "Interface" %}:
-
{% trans "IPv4" %}: ({% ifequal ipv4 None %}{% trans 'None' %}{% else %}{{ ipv4_type }}{% endifequal %})
-
{% trans "IPv6" %}: ({% ifequal ipv6 None %}{% trans 'None' %}{% else %}{{ ipv6_type }}{% endifequal %})
+
{% trans "IPv4" %} ({% ifequal ipv4 None %}{% trans 'None' %}{% else %}{{ ipv4_type }}{% endifequal %}):
+
{% trans "IPv6" %} ({% ifequal ipv6 None %}{% trans 'None' %}{% else %}{{ ipv6_type }}{% endifequal %}):
{% trans "MAC Adress" %}:
{% trans "Interface Type" %}:
{% ifequal itype 'bridge' %}
-
{% trans "Bridge device" %}
+
{% trans "Bridge Device" %}:
{% endifequal %}
{% trans "Boot Mode" %}:
{% trans "State" %}:
@@ -69,5 +69,33 @@
+
+ {% ifequal itype 'bridge' %}
+
+ {% trans 'Slaves' %}
+
+
+ {% trans 'MAC' %}
+ {% trans 'Name' %}
+ {% trans 'Type' %}
+ {% trans 'Speed' %}
+ {% trans 'State' %}
+
+
+
+ {% for iface in slave_ifaces %}
+
+ {{ iface.mac }}
+ {{ iface.name }}
+ {{ iface.type }}
+ {{ iface.speed }}
+ {{ iface.state }}
+
+ {% endfor %}
+
+
+ {% endifequal %}
+
+
{% endblock %}
\ No newline at end of file
diff --git a/interfaces/views.py b/interfaces/views.py
index acbf440..a747120 100644
--- a/interfaces/views.py
+++ b/interfaces/views.py
@@ -88,6 +88,7 @@ def interface(request, compute_id, iface):
ipv6 = conn.get_ipv6()
ipv6_type = conn.get_ipv6_type()
bridge = conn.get_bridge()
+ slave_ifaces = conn.get_bridge_slave_ifaces()
if request.method == 'POST':
if 'stop' in request.POST:
diff --git a/vrtManager/interface.py b/vrtManager/interface.py
index c91aaf9..ceaea18 100644
--- a/vrtManager/interface.py
+++ b/vrtManager/interface.py
@@ -1,5 +1,6 @@
from vrtManager.connection import wvmConnect
from vrtManager import util
+from xml.etree import ElementTree
from libvirt import VIR_INTERFACE_XML_INACTIVE
@@ -119,9 +120,34 @@ class wvmInterface(wvmConnect):
return int_ipv6_ip + '/' + int_ipv6_mask
def get_bridge(self):
+ bridge = None
if self.get_type() == 'bridge':
- xml = self._XMLDesc()
- return util.get_xml_path(xml, "/interface/bridge/interface/@name")
+ bridge = util.get_xml_path(self._XMLDesc(), "/interface/bridge/interface/@name")
+ for iface in self.get_bridge_slave_ifaces():
+ if iface.get('state') == 'up' and iface.get('speed') is not 'unknown':
+ bridge = iface.get('name')
+ return bridge
+ return bridge
+ else:
+ return None
+
+ def get_bridge_slave_ifaces(self):
+ ifaces = list()
+ if self.get_type() == 'bridge':
+ tree = ElementTree.fromstring(self._XMLDesc())
+ for iface in tree.findall("./bridge/"):
+ address = state = speed = None
+ name = iface.get('name')
+ type = iface.get('type')
+ link = iface.find('link')
+ if link is not None:
+ state = link.get('state')
+ speed = link.get('speed')
+ mac = iface.find('mac')
+ if mac is not None:
+ address = mac.get('address')
+ ifaces.append({'name': name, 'type': type, 'state': state, 'speed': speed, 'mac': address})
+ return ifaces
else:
return None
From c5a96b7662e21ca21fc058e4809e6a6875b9087d Mon Sep 17 00:00:00 2001
From: catborise
Date: Thu, 7 Nov 2019 10:33:36 +0300
Subject: [PATCH 5/5] Add IPv6 support.
---
...ss.html => modify_ipv4_fixed_address.html} | 21 +-
.../templates/modify_ipv6_fixed_address.html | 53 +++++
networks/templates/network.html | 204 +++++++++++++++---
networks/views.py | 47 ++--
vrtManager/network.py | 194 ++++++++++-------
5 files changed, 391 insertions(+), 128 deletions(-)
rename networks/templates/{modify_fixed_address.html => modify_ipv4_fixed_address.html} (85%)
create mode 100644 networks/templates/modify_ipv6_fixed_address.html
diff --git a/networks/templates/modify_fixed_address.html b/networks/templates/modify_ipv4_fixed_address.html
similarity index 85%
rename from networks/templates/modify_fixed_address.html
rename to networks/templates/modify_ipv4_fixed_address.html
index fd1c938..7c1addb 100644
--- a/networks/templates/modify_fixed_address.html
+++ b/networks/templates/modify_ipv4_fixed_address.html
@@ -1,16 +1,16 @@
{% load i18n %}
{% if request.user.is_superuser %}
-
+
-
diff --git a/networks/templates/modify_ipv6_fixed_address.html b/networks/templates/modify_ipv6_fixed_address.html
new file mode 100644
index 0000000..fcc7eff
--- /dev/null
+++ b/networks/templates/modify_ipv6_fixed_address.html
@@ -0,0 +1,53 @@
+{% load i18n %}
+{% if request.user.is_superuser %}
+
+
+
+
+
+
+{% endif %}
\ No newline at end of file
diff --git a/networks/templates/network.html b/networks/templates/network.html
index 46c79ab..c5d8cd5 100644
--- a/networks/templates/network.html
+++ b/networks/templates/network.html
@@ -68,6 +68,7 @@
+
@@ -93,31 +94,32 @@
-
+
+
-
{% trans "IPv4 Forwarding:" %}
-
{% trans "Network:" %}
-
{% trans "DHCP:" %}
+
{% trans "IPv4 Forwarding" %}:
+
{% trans "Network" %}:
{% if ipv4_dhcp_range_start and ipv4_dhcp_range_end %}
-
{% trans "Start:" %}
-
{% trans "End:" %}
+
{% trans "DHCP" %}:
+
{% trans "Start" %}:
+
{% trans "End" %}:
{% endif %}
- {% ifequal ipv4_forward.0 'nat' %}
+ {% ifequal net_forward.0 'nat' %}
{% trans "NAT" %}
{% endifequal %}
- {% ifequal ipv4_forward.0 'route' %}
+ {% ifequal net_forward.0 'route' %}
{% trans "ROUTE" %}
{% endifequal %}
- {% ifequal ipv4_forward.0 'bridge' %}
+ {% ifequal net_forward.0 'bridge' %}
{% trans "BRIDGE" %}
{% endifequal %}
- {% if not ipv4_forward.0 %}
+ {% if not net_forward.0 %}
{% trans "ISOLATE" %}
{% endif %}
@@ -137,6 +139,7 @@
{% else %}
+
- {% ifequal ipv4_forward.0 'nat' %}
+ {% if ipv4_dhcp_range_start and ipv4_dhcp_range_end %}
{% if state %}
- {% include 'modify_fixed_address.html' %}
+ {% include 'modify_ipv4_fixed_address.html' %}
{% endif %}
-
+
- {% endifequal %}
- {% if fixed_address %}
+ {% endif %}
+ {% if ipv4_fixed_address %}
@@ -175,7 +178,7 @@
{% trans 'Clear' %}
-
+
{% trans "MAC" %}
@@ -185,14 +188,132 @@
- {% for fix in fixed_address %}
+ {% for fix4 in ipv4_fixed_address %}
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+ {% endif %}
+
+
+
+
+
+
+
{% trans "IPv6 Forwarding" %}:
+
{% trans "Network" %}:
+ {% if ipv6_dhcp_range_start and ipv6_dhcp_range_end %}
+
{% trans "DHCP" %}:
+
{% trans "Start" %}:
+
{% trans "End" %}:
+ {% endif %}
+
+
+
+ {% if not net_forward.0 %}
+ {% trans "ISOLATE" %}
+ {% else %}
+ {% trans "ROUTE" %}
+ {% endif %}
+
+
{{ ipv6_network }}
+
+ {% if ipv6_dhcp_range_start and ipv6_dhcp_range_end %}
+ {% trans "ON" %}
+ {% else %}
+ {% trans "OFF" %}
+ {% endif %}
+
+ {% if ipv6_dhcp_range_start and ipv6_dhcp_range_end %}
+
+ {% endif %}
+
+
+ {% if ipv6_dhcp_range_start and ipv6_dhcp_range_end %}
+ {% if state %}
+ {% include 'modify_ipv6_fixed_address.html' %}
+ {% endif %}
+
+
+
+ {% endif %}
+ {% if ipv6_fixed_address %}
+
+
+
+
+
+
+
+
+
+
+
+
+ {% trans "ID" %}
+ {% trans "Address" %}
+ {% trans "Name" %}
+ {% trans "Action" %}
+
+
+
+ {% for fix6 in ipv6_fixed_address %}
+
+