mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 19:56:48 +00:00
feat(networks): the network pages on Bootstrap's cards, tables and dialogs
As the storage pages; reviewed with Codex. - The list is a card per network: its name with Active or Stopped and Autostart badges, its type (network_mode: Isolated, NAT, Routed, Open, Bridge, Macvtap, SR-IOV), its device, and each address with its DHCP range; a bridge or macvtap network's addresses come from the outside network. - A network's page: its heading starts or stops it, the menu sets autostart and deletes a stopped one. A Network card tells its state, type, bridge or interface, MAC and what the type does; a card per address (every <ip>, each with its DHCP range dialog, which libvirt takes on a stopped network); its fixed addresses of every subnet in one table, searched, each with Edit and Delete, one dialog adding and editing them; the VMs whose definition names it, connected or configured, linked (wvmNetwork.get_vms, one domain listing, a VM undefined meanwhile left out); its bandwidth limits where libvirt sets them (not on macvtap or SR-IOV networks), in KiB/s, from the saved definition with a note that a running network takes them when restarted; its XML in an accordion. The page reads the running and the saved definition once each, and only to render itself: its actions, which all redirect, read nothing of it first. - The New network dialog is one form, as the New pool one: the type as radio cards (the radio_card.html include, now shared by both), the chosen type's fields only, IPv6 with its box, a bridge or interface suggested from the host's (get_host_interfaces, not the bridges libvirt made for its own networks); a refused network or one libvirt refuses opens the dialog again with what was entered, the reasons beside the fields and focus on the first. - What the New pool and New network dialogs share is one script, static/js/choice_dialog.js: the radio cards show their fieldsets (data-kinds) and a refused form opens again focused on its first refused field; each dialog keeps only its own changes. - The fixed-address dialogs per family go to the page's own dialog.
This commit is contained in:
parent
0c9a002ef4
commit
0ee03c0971
15 changed files with 947 additions and 757 deletions
|
|
@ -1,10 +1,10 @@
|
|||
"""A network's addresses are read from its XML however libvirt writes it,
|
||||
each <ip> by its own index; a change starts from the saved definition, so
|
||||
two in a row keep each other; a fixed address is found by the address it
|
||||
had and checked against its subnet; the XML editor defines only this
|
||||
network; a network that does not start is not left defined. Runs on a
|
||||
private libvirt test driver: "test:///default" is shared by the whole
|
||||
process."""
|
||||
"""A network's addresses are read from its XML however libvirt writes it, each
|
||||
<ip> by its own index; a page reads each definition once; a change starts
|
||||
from the saved definition, so two in a row keep each other; a fixed address
|
||||
is found by the address it had and checked against its subnet; the XML
|
||||
editor defines only this network; a network that does not start is not left
|
||||
defined. Runs on a private libvirt test driver: "test:///default" is shared
|
||||
by the whole process."""
|
||||
|
||||
import tempfile
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
|
@ -61,12 +61,13 @@ class NetworkChangeTests(SimpleTestCase):
|
|||
def saved(self):
|
||||
return etree.fromstring(self.conn.networkLookupByName("lab").XMLDesc(libvirt.VIR_NETWORK_XML_INACTIVE))
|
||||
|
||||
def test_the_page_reads_the_xml_once(self):
|
||||
def test_the_page_reads_each_definition_once(self):
|
||||
# the running one for its addresses, the saved one for its limits and the XML editor
|
||||
net = self.network()
|
||||
with patch.object(net.net, "XMLDesc", wraps=net.net.XMLDesc) as xml:
|
||||
net.get_ip_networks(), net.get_network_forward(), net.get_network_mac(), net.get_qos()
|
||||
net.get_bridge_device()
|
||||
self.assertEqual(xml.call_count, 1)
|
||||
net.get_bridge_device(), net.get_mode(), net.saved_xml
|
||||
self.assertEqual(xml.call_count, 2)
|
||||
|
||||
def test_the_ipv4_address_after_an_ipv6_one_keeps_its_index(self):
|
||||
ipv6, ipv4 = self.network().get_ip_networks()
|
||||
|
|
@ -151,7 +152,7 @@ class NetworkChangeTests(SimpleTestCase):
|
|||
def test_the_xml_editor_takes_an_encoding_declaration(self):
|
||||
self.conn.networkLookupByName("lab").destroy()
|
||||
net = self.network()
|
||||
net.edit_network('<?xml version="1.0" encoding="UTF-8"?>\n' + net.config_xml().replace("virbr9", "virbr6"))
|
||||
net.edit_network('<?xml version="1.0" encoding="UTF-8"?>\n' + net.saved_xml.replace("virbr9", "virbr6"))
|
||||
self.assertEqual(self.saved().xpath("bridge/@name"), ["virbr6"])
|
||||
|
||||
def test_a_fixed_address_is_of_the_subnet_and_its_own(self):
|
||||
|
|
@ -165,7 +166,7 @@ class NetworkChangeTests(SimpleTestCase):
|
|||
def test_the_xml_editor_defines_this_network_only(self):
|
||||
self.conn.networkLookupByName("lab").destroy() # its definition read back at once
|
||||
net = self.network()
|
||||
xml = net.config_xml()
|
||||
xml = net.saved_xml
|
||||
for other, why in ((xml.replace("<name>lab</name>", "<name>other</name>"), "must define network lab"),
|
||||
(xml.replace(net.net.UUIDString(), "11111111-2222-3333-4444-555555555555"), "keep the network's UUID"),
|
||||
("<network>", "not valid")):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue