[Kimchi-devel] [PATCH 2/2] Move networkxml.py to xmlutils module and update it to use lxml.builder
Aline Manera
alinefm at linux.vnet.ibm.com
Thu Oct 16 14:01:36 UTC 2014
networkxml.py was moved to xmlutils/network.py and it was also updated
to use lxml.builder instead of plan text while generating the XML.
Update the imports accordinly to this changes and also the test cases.
Signed-off-by: Aline Manera <alinefm at linux.vnet.ibm.com>
---
src/kimchi/model/networks.py | 8 +--
src/kimchi/networkxml.py | 127 -----------------------------------------
src/kimchi/xmlutils/network.py | 123 +++++++++++++++++++++++++++++++++++++++
tests/test_networkxml.py | 27 +++++----
4 files changed, 140 insertions(+), 145 deletions(-)
delete mode 100644 src/kimchi/networkxml.py
create mode 100644 src/kimchi/xmlutils/network.py
diff --git a/src/kimchi/model/networks.py b/src/kimchi/model/networks.py
index 92fae4d..6d21e9e 100644
--- a/src/kimchi/model/networks.py
+++ b/src/kimchi/model/networks.py
@@ -27,11 +27,12 @@ from xml.sax.saxutils import escape
from kimchi import netinfo
from kimchi import network as knetwork
-from kimchi import networkxml
from kimchi.exception import InvalidOperation, InvalidParameter
from kimchi.exception import MissingParameter, NotFoundError, OperationFailed
from kimchi.rollbackcontext import RollbackContext
from kimchi.utils import kimchi_log, run_command
+from kimchi.xmlutils.network import create_vlan_tagged_bridge_xml
+from kimchi.xmlutils.network import to_network_xml
from kimchi.xmlutils.utils import xpath_get_text
@@ -100,7 +101,7 @@ class NetworksModel(object):
self._set_network_bridge(params)
params['name'] = escape(params['name'])
- xml = networkxml.to_network_xml(**params)
+ xml = to_network_xml(**params)
try:
network = conn.networkDefineXML(xml.encode("utf-8"))
@@ -206,8 +207,7 @@ class NetworksModel(object):
# Truncate the interface name if it exceeds 8 characters to make sure
# the length of bridge name is less than 15 (its maximum value).
br_name = KIMCHI_BRIDGE_PREFIX + interface[-8:] + '-' + vlan_id
- br_xml = networkxml.create_vlan_tagged_bridge_xml(br_name, interface,
- vlan_id)
+ br_xml = create_vlan_tagged_bridge_xml(br_name, interface, vlan_id)
conn = self.conn.get()
if br_name in [net.bridgeName() for net in conn.listAllNetworks()]:
diff --git a/src/kimchi/networkxml.py b/src/kimchi/networkxml.py
deleted file mode 100644
index ff30f16..0000000
--- a/src/kimchi/networkxml.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import ipaddr
-import lxml.etree as ET
-
-
-from lxml.builder import E
-
-
-# FIXME, do not support ipv6
-
-def _get_dhcp_xml(**kwargs):
- """
- <dhcp>
- <range start="192.168.122.100" end="192.168.122.254" />
- <host mac="00:16:3e:77:e2:ed" name="foo.test.com" ip="192.168.122.10" />
- <host mac="00:16:3e:3e:a9:1a" name="bar.test.com" ip="192.168.122.11" />
- </dhcp>
- """
- xml = ''
- dhcp_range = " <range start='%(start)s' end='%(end)s' />"
- ipv4host = " <host mac='%(mac)s' name='%(name)s' ip='%(ip)s' />"
- dhcp = []
- if 'range' in kwargs.keys():
- dhcp.append(dhcp_range % kwargs['range'])
- if 'hosts' in kwargs.keys():
- dhcp.extend([ipv4host % host for host in kwargs['hosts']])
- if dhcp:
- xml = "\n".join(["<dhcp>"] + dhcp + ["</dhcp>"])
- return xml
-
-
-def _get_ip_xml(**kwargs):
- """
- <ip address="192.168.152.1" netmask="255.255.255.0">
- <dhcp>
- <range start="192.168.152.2" end="192.168.152.254" />
- </dhcp>
- </ip>
- """
- xml = ""
- if 'net' in kwargs.keys():
- net = ipaddr.IPNetwork(kwargs['net'])
- address = str(net.ip)
- netmask = str(net.netmask)
- dhcp_params = kwargs.get('dhcp', {})
- dhcp = _get_dhcp_xml(**dhcp_params)
- xml = """
- <ip address='%s' netmask='%s'>"
- %s
- </ip>""" % (address, netmask, dhcp)
- return xml
-
-
-def _get_forward_xml(**kwargs):
- """
- <forward mode='hostdev' dev='eth0' managed='yes'>
- </forward>
- """
-
- if "mode" in kwargs.keys() and kwargs['mode'] is None:
- return ""
- mode = " mode='%s'" % kwargs['mode'] if 'mode' in kwargs.keys() else ""
- dev = " dev='%s'" % kwargs['dev'] if 'dev' in kwargs.keys() else ""
- managed = (" managed='%s'" % kwargs['managed']
- if 'managed' in kwargs.keys() else "")
- xml = """
- <forward %s%s%s>
- </forward>
- """ % (mode, dev, managed)
- return xml
-
-
-def to_network_xml(**kwargs):
-
- params = {'name': kwargs['name']}
- # None means is Isolated network, {} means default mode nat
- forward = kwargs.get('forward', {"mode": None})
- ip = {'net': kwargs['net']} if 'net' in kwargs else {}
- ip['dhcp'] = kwargs.get('dhcp', {})
- bridge = kwargs.get('bridge')
- params = {'name': kwargs['name'],
- 'forward': _get_forward_xml(**forward),
- 'bridge': "<bridge name='%s' />" % bridge if bridge else "",
- 'ip': _get_ip_xml(**ip)}
-
- xml = """
- <network>
- <name>%(name)s</name>
- %(bridge)s
- %(forward)s
- %(ip)s
- </network>
- """ % params
- return xml
-
-
-def create_vlan_tagged_bridge_xml(bridge, interface, vlan_id):
- vlan = E.vlan(E.interface(name=interface))
- vlan.set('tag', vlan_id)
- m = E.interface(
- E.start(mode='onboot'),
- E.bridge(
- E.interface(
- vlan,
- type='vlan',
- name='.'.join([interface, vlan_id]))),
- type='bridge',
- name=bridge)
- return ET.tostring(m)
diff --git a/src/kimchi/xmlutils/network.py b/src/kimchi/xmlutils/network.py
new file mode 100644
index 0000000..e78779c
--- /dev/null
+++ b/src/kimchi/xmlutils/network.py
@@ -0,0 +1,123 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import ipaddr
+import lxml.etree as ET
+
+from lxml.builder import E
+
+
+# FIXME, do not support ipv6
+def _get_dhcp_elem(**kwargs):
+ """
+ <dhcp>
+ <range start="192.168.122.100" end="192.168.122.254" />
+ <host mac="00:16:3e:77:e2:ed" name="foo.test.com" ip="192.168.122.10" />
+ <host mac="00:16:3e:3e:a9:1a" name="bar.test.com" ip="192.168.122.11" />
+ </dhcp>
+ """
+ dhcp = E.dhcp()
+ if 'range' in kwargs.keys():
+ dhcp_range = E.range(start=kwargs['range']['start'],
+ end=kwargs['range']['end'])
+ dhcp.append(dhcp_range)
+
+ if 'hosts' in kwargs.keys():
+ for host in kwargs['hosts']:
+ dhcp.append(E.host(mac=host['mac'],
+ name=host['name'],
+ ip=host['ip']))
+
+ return dhcp if len(dhcp) > 0 else None
+
+
+def _get_ip_elem(**kwargs):
+ """
+ <ip address="192.168.152.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="192.168.152.2" end="192.168.152.254" />
+ </dhcp>
+ </ip>
+ """
+ if 'net' not in kwargs.keys():
+ return None
+
+ net = ipaddr.IPNetwork(kwargs['net'])
+ ip = E.ip(address=str(net.ip), netmask=str(net.netmask))
+
+ dhcp_params = kwargs.get('dhcp', {})
+ dhcp = _get_dhcp_elem(**dhcp_params)
+ if dhcp is not None:
+ ip.append(dhcp)
+
+ return ip
+
+
+def _get_forward_elem(**kwargs):
+ """
+ <forward mode='hostdev' dev='eth0' managed='yes'>
+ </forward>
+ """
+ if "mode" in kwargs.keys() and kwargs['mode'] is None:
+ return None
+
+ forward = E.forward()
+ if 'mode' in kwargs.keys():
+ forward.set('mode', kwargs['mode'])
+
+ if 'dev' in kwargs.keys():
+ forward.set('dev', kwargs['dev'])
+
+ if 'managed' in kwargs.keys():
+ forward.set('managed', kwargs['managed'])
+
+ return forward
+
+
+def to_network_xml(**kwargs):
+ network = E.network(E.name(kwargs['name']))
+ bridge = kwargs.get('bridge')
+ if bridge:
+ network.append(E.bridge(name=bridge))
+
+ # None means is Isolated network, {} means default mode nat
+ params = kwargs.get('forward', {"mode": None})
+ forward = _get_forward_elem(**params)
+ if forward is not None:
+ network.append(forward)
+
+ if 'net' in kwargs:
+ network.append(_get_ip_elem(**kwargs))
+
+ return ET.tostring(network)
+
+
+def create_vlan_tagged_bridge_xml(bridge, interface, vlan_id):
+ vlan = E.vlan(E.interface(name=interface))
+ vlan.set('tag', vlan_id)
+ m = E.interface(
+ E.start(mode='onboot'),
+ E.bridge(
+ E.interface(
+ vlan,
+ type='vlan',
+ name='.'.join([interface, vlan_id]))),
+ type='bridge',
+ name=bridge)
+ return ET.tostring(m)
diff --git a/tests/test_networkxml.py b/tests/test_networkxml.py
index 674008d..3706a71 100644
--- a/tests/test_networkxml.py
+++ b/tests/test_networkxml.py
@@ -19,12 +19,11 @@
import ipaddr
import unittest
+import lxml.etree as ET
-
-import kimchi.networkxml as nxml
import utils
-
+from kimchi.xmlutils import network as nxml
from kimchi.xmlutils.utils import xpath_get_text
@@ -42,18 +41,18 @@ class NetworkXmlTests(unittest.TestCase):
"ip": "192.168.122.11"}
params = {}
- xml = nxml._get_dhcp_xml(**params)
- self.assertEquals("", xml)
+ dhcp = nxml._get_dhcp_elem(**params)
+ self.assertEquals(None, dhcp)
params["range"] = dhcp_range
- xml = nxml._get_dhcp_xml(**params)
+ xml = ET.tostring(nxml._get_dhcp_elem(**params))
start = xpath_get_text(xml, "/dhcp/range/@start")
end = xpath_get_text(xml, "/dhcp/range/@end")
self.assertEquals(dhcp_range['start'], start[0])
self.assertEquals(dhcp_range['end'], end[0])
params["hosts"] = [host1, host2]
- xml = nxml._get_dhcp_xml(**params)
+ xml = ET.tostring(nxml._get_dhcp_elem(**params))
ip = xpath_get_text(xml, "/dhcp/host/@ip")
self.assertEquals(ip, [host1['ip'], host2['ip']])
@@ -64,12 +63,12 @@ class NetworkXmlTests(unittest.TestCase):
dhcp_range = {"start": "192.168.122.100", "end": "192.168.122.254"}
params = {}
- xml = nxml._get_dhcp_xml(**params)
- self.assertEquals("", xml)
+ dhcp = nxml._get_dhcp_elem(**params)
+ self.assertEquals(None, dhcp)
params["net"] = "192.168.122.0/255.255.255.0"
params["dhcp"] = {'range': dhcp_range}
- xml = nxml._get_ip_xml(**params)
+ xml = ET.tostring(nxml._get_ip_elem(**params))
start = xpath_get_text(xml, "/ip/dhcp/range/@start")[0]
end = xpath_get_text(xml, "/ip/dhcp/range/@end")[0]
self.assertEquals(dhcp_range['start'], start)
@@ -83,7 +82,7 @@ class NetworkXmlTests(unittest.TestCase):
# test _get_ip_xml can accepts strings: '192.168.122.0/24',
# which is same as "192.168.122.0/255.255.255.0"
params["net"] = "192.168.122.0/24"
- xml = nxml._get_ip_xml(**params)
+ xml = ET.tostring(nxml._get_ip_elem(**params))
netmask = xpath_get_text(xml, "/ip/@netmask")[0]
self.assertEquals(netmask,
str(ipaddr.IPNetwork(params["net"]).netmask))
@@ -94,12 +93,12 @@ class NetworkXmlTests(unittest.TestCase):
"""
params = {"mode": None}
- xml = nxml._get_forward_xml(**params)
- self.assertEquals("", xml)
+ forward = nxml._get_forward_elem(**params)
+ self.assertEquals(None, forward)
params["mode"] = 'nat'
params["dev"] = 'eth0'
- xml = nxml._get_forward_xml(**params)
+ xml = ET.tostring(nxml._get_forward_elem(**params))
mode = xpath_get_text(xml, "/forward/@mode")[0]
dev = xpath_get_text(xml, "/forward/@dev")[0]
self.assertEquals(params['mode'], mode)
--
1.9.3
More information about the Kimchi-devel
mailing list