[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