74 lines
2.6 KiB
Python
74 lines
2.6 KiB
Python
|
from lxml.etree import Element, QName, SubElement
|
||
|
|
||
|
|
||
|
class Constructor:
|
||
|
"""
|
||
|
The XML constructor. This class builds XML configs for libvirt.
|
||
|
"""
|
||
|
|
||
|
def construct_xml(self,
|
||
|
tag: dict,
|
||
|
namespace: str | None = None,
|
||
|
nsprefix: str | None = None,
|
||
|
root: Element = None) -> Element:
|
||
|
"""
|
||
|
Shortly this recursive function transforms dictonary to XML.
|
||
|
Return etree.Element built from dict with following structure::
|
||
|
|
||
|
{
|
||
|
'name': 'device', # tag name
|
||
|
'text': '', # optional key
|
||
|
'values': { # optional key, must be a dict of key-value pairs
|
||
|
'type': 'disk'
|
||
|
},
|
||
|
children: [] # optional key, must be a list of dicts
|
||
|
}
|
||
|
|
||
|
Child elements must have the same structure. Infinite `children` nesting
|
||
|
is allowed.
|
||
|
"""
|
||
|
use_ns = False
|
||
|
if isinstance(namespace, str) and isinstance(nsprefix, str):
|
||
|
use_ns = True
|
||
|
# Create element
|
||
|
if root is None:
|
||
|
if use_ns:
|
||
|
element = Element(QName(namespace, tag['name']),
|
||
|
nsmap={nsprefix: namespace})
|
||
|
else:
|
||
|
element = Element(tag['name'])
|
||
|
else:
|
||
|
if use_ns:
|
||
|
element = SubElement(root, QName(namespace, tag['name']))
|
||
|
else:
|
||
|
element = SubElement(root, tag['name'])
|
||
|
# Fill up element with content
|
||
|
if 'text' in tag.keys():
|
||
|
element.text = tag['text']
|
||
|
if 'values' in tag.keys():
|
||
|
for key in tag['values'].keys():
|
||
|
element.set(str(key), str(tag['values'][key]))
|
||
|
if 'children' in tag.keys():
|
||
|
for child in tag['children']:
|
||
|
element.append(
|
||
|
self.construct_xml(child,
|
||
|
namespace=namespace,
|
||
|
nsprefix=nsprefix,
|
||
|
root=element))
|
||
|
return element
|
||
|
|
||
|
def add_meta(self, xml: Element, data: dict,
|
||
|
namespace: str, nsprefix: str) -> None:
|
||
|
"""
|
||
|
Add metadata to domain. See:
|
||
|
https://libvirt.org/formatdomain.html#general-metadata
|
||
|
"""
|
||
|
metadata = metadata_old = xml.xpath('/domain/metadata')[0]
|
||
|
metadata.append(
|
||
|
self.construct_xml(
|
||
|
data,
|
||
|
namespace=namespace,
|
||
|
nsprefix=nsprefix,
|
||
|
))
|
||
|
xml.replace(metadata_old, metadata)
|