1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 19:26:48 +00:00
webvirtcloud/vrtManager/nwfilters.py
catborise f9c8c36a6b fix(nwfilters): a filter is changed in place, also while a VM uses it
Every change to a filter (a rule or reference removed or added, the XML
edited) undefined it and defined the new XML. libvirt refuses to
undefine a filter a running VM uses, so none of these worked on such a
filter; on an unused one a refused definition was undone by defining
the old XML without its UUID, so the filter came back as another one.
The filter is now defined again with its own UUID, which libvirt does
in place, while VMs use it too; XML it cannot parse or apply to the
running VMs is refused and reported. The XML editor shows the UUID.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 09:55:27 +03:00

129 lines
4.3 KiB
Python

from xml.etree import ElementTree
from vrtManager.connection import wvmConnect
class wvmNWFilters(wvmConnect):
def get_nwfilter_info(self, name):
nwfilter = self.get_nwfilter(name)
xml = nwfilter.XMLDesc(0)
uuid = nwfilter.UUIDString()
return {"name": name, "uuid": uuid, "xml": xml}
def create_nwfilter(self, xml):
self.wvm.nwfilterDefineXML(xml)
def clone_nwfilter(self, name, cln_name):
nwfilter = self.get_nwfilter(name)
if nwfilter:
tree = ElementTree.fromstring(nwfilter.XMLDesc(0))
tree.set("name", cln_name)
uuid = tree.find("uuid")
tree.remove(uuid)
self.create_nwfilter(ElementTree.tostring(tree).decode())
class wvmNWFilter(wvmConnect):
def __init__(self, host, login, passwd, conn, nwfiltername):
wvmConnect.__init__(self, host, login, passwd, conn)
self.nwfilter = self.get_nwfilter(nwfiltername)
def _XMLDesc(self, flags):
return self.nwfilter.XMLDesc(flags)
def get_uuid(self):
return self.nwfilter.UUIDString()
def get_name(self):
return self.nwfilter.name()
def get_xml(self):
"""With the UUID: defined again with it, libvirt changes the filter in
place, also while a VM uses it. It refuses XML it cannot parse or
apply to the running VMs' interfaces."""
return self._XMLDesc(0)
def get_filter_refs(self):
tree = ElementTree.fromstring(self._XMLDesc(0))
return [ref.get("filter") for ref in tree.findall("./filterref")]
def get_rules(self):
rules = []
tree = ElementTree.fromstring(self._XMLDesc(0))
for r in tree.findall("./rule"):
rule_action = r.get("action")
rule_direction = r.get("direction")
rule_priority = r.get("priority")
rule_statematch = r.get("statematch")
rule_directives = r.find("./")
if rule_directives is not None:
rule_directives = ElementTree.tostring(rule_directives).decode()
rule_info = {
"action": rule_action,
"direction": rule_direction,
"priority": rule_priority,
"statematch": rule_statematch,
"directives": rule_directives,
}
rules.append(rule_info)
return rules
def delete_ref(self, name):
tree = ElementTree.fromstring(self._XMLDesc(0))
for ref in tree.findall("./filterref"):
if name == ref.get("filter"):
tree.remove(ref)
break
return ElementTree.tostring(tree).decode()
@staticmethod
def _rules(tree, action, direction, priority):
# compared, not put into an XPath predicate: the values come from forms
return [
rule
for rule in tree.findall("./rule")
if (rule.get("action"), rule.get("direction"), rule.get("priority")) == (action, direction, priority)
]
def delete_rule(self, action, direction, priority):
tree = ElementTree.fromstring(self._XMLDesc(0))
rule_tree = self._rules(tree, action, direction, priority)
if rule_tree:
tree.remove(rule_tree[0])
return ElementTree.tostring(tree).decode()
def add_ref(self, name):
tree = ElementTree.fromstring(self._XMLDesc(0))
element = ElementTree.Element("filterref")
element.attrib["filter"] = name
tree.append(element)
return ElementTree.tostring(tree).decode()
def add_rule(self, xml):
tree = ElementTree.fromstring(self._XMLDesc(0))
rule = ElementTree.fromstring(xml)
rule_action = rule.get("action")
rule_direction = rule.get("direction")
rule_priority = rule.get("priority")
rule_directives = rule.find("./")
rule_tree = self._rules(tree, rule_action, rule_direction, rule_priority)
if rule_tree:
rule_tree[0].append(rule_directives)
else:
element = ElementTree.Element("rule")
element.attrib["action"] = rule_action
element.attrib["direction"] = rule_direction
element.attrib["priority"] = rule_priority
element.append(rule_directives)
tree.append(element)
return ElementTree.tostring(tree).decode()