From bc2b70544a959d7b1df980c6440266171d86a71e Mon Sep 17 00:00:00 2001 From: catborise Date: Thu, 29 Oct 2026 00:09:15 +0300 Subject: [PATCH] fix(nwfilters): a filter in use is not deleted, and a change replaces no other filter Plan reviewed with Codex; libvirt's behaviour checked on a host. - A filter is not deleted while a VM's interface references it, as the VM runs or as saved for its next boot (a stopped VM too), or while another filter references it: libvirt refuses only one a running VM uses, and a VM using a filter that references a deleted one does not start. The VMs are read from one listing, one or two XML reads each, instead of a connection per VM; the refusal names them. - Create refuses a name or UUID the host has, clone a name in use or one outside the panel's names, and editing the XML must keep the filter's name and UUID: each would replace another filter or make a copy. Entered XML is read for these checks without expanding entities or taking a DTD (util.parse_xml, shared with the network editor), and a rule is one element. - A rule or reference is deleted only while it reads as the page showed it, not by index and three attributes: a rule alike in those or a filter changed meanwhile loses nothing. - A reference is added only to another filter of the host not referenced yet; the picker offers those. - References keep their parameters, in order (a name may repeat); a rule shows every protocol element it has, a rule without one too. - One change a POST (two would both start from the page's reading, the second undoing the first); every change redirects and reports its refusal as a message, a POST for a filter gone meanwhile going to the list; the catch-all that showed any error goes, and so does wvmInstance.get_filterrefs, which only the old delete check used. The list reads each filter's XML once from one listing; a filter's page reads its XML once and only the other filters' names; the per-filter XML dialog of the list goes (a filter's page shows its XML). The XML editors send their text untouched too. --- networks/tests/test_network_changes.py | 4 +- nwfilters/templates/nwfilter.html | 21 +-- nwfilters/templates/nwfilters.html | 26 +-- nwfilters/tests/test_audit_rows.py | 37 ++-- nwfilters/tests/test_filters.py | 182 +++++++++++++++++++ nwfilters/tests/test_redefine.py | 55 ++++-- nwfilters/tests/test_views.py | 10 ++ nwfilters/views.py | 232 ++++++------------------ vrtManager/instance.py | 11 -- vrtManager/network.py | 7 +- vrtManager/nwfilters.py | 237 +++++++++++++++++-------- vrtManager/tests/test_xpath_values.py | 19 -- vrtManager/util.py | 13 ++ 13 files changed, 502 insertions(+), 352 deletions(-) create mode 100644 nwfilters/tests/test_filters.py diff --git a/networks/tests/test_network_changes.py b/networks/tests/test_network_changes.py index 294e34be..877c2bcb 100644 --- a/networks/tests/test_network_changes.py +++ b/networks/tests/test_network_changes.py @@ -142,11 +142,11 @@ class NetworkChangeTests(SimpleTestCase): net.net.update.assert_not_called() def test_the_xml_editor_expands_no_entity(self): - # a file of the panel's host named by an external entity is not read into the check + # a file of the panel's host named by an external entity is not read: no DTD is taken net = self.network() xml = (']>' "&name;") - with self.assertRaisesRegex(OperationError, "must define network lab"): + with self.assertRaisesRegex(OperationError, "may not declare a DTD"): net.edit_network(xml) def test_the_xml_editor_takes_an_encoding_declaration(self): diff --git a/nwfilters/templates/nwfilter.html b/nwfilters/templates/nwfilter.html index f2fed219..b3e584ac 100644 --- a/nwfilters/templates/nwfilter.html +++ b/nwfilters/templates/nwfilter.html @@ -50,8 +50,8 @@ @@ -120,13 +121,11 @@ {{ rule.direction }} {{ rule.priority }} {{ rule.statematch }} - {{ rule.directives }} + {% for protocol in rule.protocols %}
{{ protocol.name }}{% for attribute, value in protocol.attributes %} {{ attribute }}={{ value }}{% endfor %}
{% endfor %}
{% csrf_token %} - - - - + + @@ -146,6 +145,7 @@ editor.getSession().setMode("ace/mode/xml"); var edit_input = $('input[name="edit_xml"]'); + edit_input.val(editor.getSession().getValue()); editor.getSession().on("change",function () { edit_input.val(editor.getSession().getValue()); }); @@ -154,6 +154,7 @@ rule_editor.getSession().setMode("ace/mode/xml"); var rule_input = $('input[name="nwfilterrule_xml"]'); + rule_input.val(rule_editor.getSession().getValue()); rule_editor.getSession().on("change",function () { rule_input.val(rule_editor.getSession().getValue()); }); diff --git a/nwfilters/templates/nwfilters.html b/nwfilters/templates/nwfilters.html index 27daaa79..847116df 100644 --- a/nwfilters/templates/nwfilters.html +++ b/nwfilters/templates/nwfilters.html @@ -29,7 +29,7 @@ # {% trans "UUID" %} {% trans "Name" %} - {% trans "Action" %} + {% trans "Action" %} @@ -38,29 +38,6 @@ {{ forloop.counter }} {{ nwfilter.uuid }} {{ nwfilter.name }} - - - -