From: Stefan Hanreich <s.hanreich@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH pve-manager v3 5/9] ui: resource tree: add network resource
Date: Fri, 7 Nov 2025 15:31:49 +0100 [thread overview]
Message-ID: <20251107143201.689035-36-s.hanreich@proxmox.com> (raw)
In-Reply-To: <20251107143201.689035-1-s.hanreich@proxmox.com>
From: Gabriel Goller <g.goller@proxmox.com>
Add the newly introduced network resource to the resource tree, so the
the status of network resources can be displayed in the UI. For this
matter, a new NetworkBrowser widget is added, which is responsible for
showing the contents of a network resource. The old SDN browser is
still kept around, so the UI can handle nodes that are still sending
the old sdn resource type.
Co-authored-by: Stefan Hanreich <s.hanreich@proxmox.com>
Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
www/manager6/Makefile | 2 +
www/manager6/Utils.js | 12 ++
www/manager6/Workspace.js | 1 +
www/manager6/sdn/FabricsContentView.js | 77 ++++++++++++
www/manager6/sdn/NetworkBrowser.js | 167 +++++++++++++++++++++++++
www/manager6/tree/ResourceTree.js | 6 +
6 files changed, 265 insertions(+)
create mode 100644 www/manager6/sdn/FabricsContentView.js
create mode 100644 www/manager6/sdn/NetworkBrowser.js
diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 85f9268d1..ba762578e 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -278,6 +278,7 @@ JSSRC= \
qemu/USBEdit.js \
qemu/VirtiofsEdit.js \
sdn/Browser.js \
+ sdn/NetworkBrowser.js \
sdn/ControllerView.js \
sdn/Status.js \
sdn/StatusView.js \
@@ -313,6 +314,7 @@ JSSRC= \
sdn/zones/VlanEdit.js \
sdn/zones/VxlanEdit.js \
sdn/FabricsView.js \
+ sdn/FabricsContentView.js \
sdn/fabrics/Common.js \
sdn/fabrics/InterfacePanel.js \
sdn/fabrics/NodeEdit.js \
diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index c48ee0b25..7b3d88aa7 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -1276,6 +1276,13 @@ Ext.define('PVE.Utils', {
// templates
objType = 'template';
status = type;
+ } else if (type === 'network') {
+ const network_type_mapping = {
+ fabric: 'fa fa-road',
+ zone: 'fa fa-th',
+ };
+
+ return network_type_mapping[record.network_type] ?? '';
} else if (type === 'storage' && record.content === 'import') {
return 'fa fa-cloud-download';
} else {
@@ -1299,6 +1306,11 @@ Ext.define('PVE.Utils', {
var cls = PVE.Utils.get_object_icon_class(value, record.data);
var fa = '<i class="fa-fw x-grid-icon-custom ' + cls + '"></i> ';
+
+ if (value === 'network') {
+ return fa + record.data.network_type;
+ }
+
return fa + value;
},
diff --git a/www/manager6/Workspace.js b/www/manager6/Workspace.js
index 60c499cbb..51fb2d817 100644
--- a/www/manager6/Workspace.js
+++ b/www/manager6/Workspace.js
@@ -252,6 +252,7 @@ Ext.define('PVE.StdWorkspace', {
lxc: 'pveLXCConfig',
storage: 'PVE.storage.Browser',
sdn: 'PVE.sdn.Browser',
+ network: 'PVE.network.Browser',
pool: 'pvePoolConfig',
tag: 'pveTagConfig',
};
diff --git a/www/manager6/sdn/FabricsContentView.js b/www/manager6/sdn/FabricsContentView.js
new file mode 100644
index 000000000..47e8bce7f
--- /dev/null
+++ b/www/manager6/sdn/FabricsContentView.js
@@ -0,0 +1,77 @@
+Ext.define('PVE.sdn.FabricRoutesContentView', {
+ extend: 'Ext.grid.GridPanel',
+ alias: 'widget.pveSDNFabricRoutesContentView',
+
+ columns: [
+ {
+ header: gettext('Route'),
+ sortable: true,
+ dataIndex: 'route',
+ flex: 1,
+ },
+ {
+ header: gettext('Via'),
+ sortable: true,
+ dataIndex: 'via',
+ renderer: (value) => {
+ if (Ext.isArray(value)) {
+ return value.join('<br>');
+ }
+ return value || '';
+ },
+ flex: 1,
+ },
+ ],
+});
+
+Ext.define('PVE.sdn.FabricNeighborsContentView', {
+ extend: 'Ext.grid.GridPanel',
+ alias: 'widget.pveSDNFabricNeighborsContentView',
+
+ columns: [
+ {
+ header: gettext('Neighbor'),
+ sortable: true,
+ dataIndex: 'neighbor',
+ flex: 1,
+ },
+ {
+ header: gettext('Status'),
+ sortable: true,
+ dataIndex: 'status',
+ flex: 0.5,
+ },
+ {
+ header: gettext('Uptime'),
+ sortable: true,
+ dataIndex: 'uptime',
+ flex: 0.5,
+ },
+ ],
+});
+
+Ext.define('PVE.sdn.FabricInterfacesContentView', {
+ extend: 'Ext.grid.GridPanel',
+ alias: 'widget.pveSDNFabricInterfacesContentView',
+
+ columns: [
+ {
+ header: gettext('Name'),
+ sortable: true,
+ dataIndex: 'name',
+ flex: 1,
+ },
+ {
+ header: gettext('Type'),
+ sortable: true,
+ dataIndex: 'type',
+ flex: 1,
+ },
+ {
+ header: gettext('State'),
+ sortable: true,
+ dataIndex: 'state',
+ flex: 1,
+ },
+ ],
+});
diff --git a/www/manager6/sdn/NetworkBrowser.js b/www/manager6/sdn/NetworkBrowser.js
new file mode 100644
index 000000000..ab6e32a91
--- /dev/null
+++ b/www/manager6/sdn/NetworkBrowser.js
@@ -0,0 +1,167 @@
+Ext.define('PVE.network.Browser', {
+ extend: 'PVE.panel.Config',
+ alias: 'widget.PVE.network.Browser',
+
+ initComponent: function () {
+ let me = this;
+ let data = me.pveSelNode.data;
+
+ let node = data.node;
+ if (!node) {
+ throw 'no node name specified';
+ }
+
+ let name = data.network;
+ if (!name) {
+ throw 'no name specified';
+ }
+
+ let networkType = data.network_type;
+ if (!networkType) {
+ throw 'no type specified';
+ }
+
+ me.items = [];
+
+ if (networkType === 'fabric') {
+ me.onlineHelp = 'pvesdn_config_fabrics';
+
+ me.items.push({
+ nodename: node,
+ fabricId: name,
+ protocol: me.pveSelNode.data.protocol,
+ xtype: 'pveSDNFabricRoutesContentView',
+ title: gettext('Routes'),
+ iconCls: 'fa fa-exchange',
+ itemId: 'routes',
+ width: '100%',
+ store: {
+ proxy: {
+ type: 'proxmox',
+ url: `/api2/json/nodes/${node}/sdn/fabrics/${name}/routes`,
+ reader: {
+ type: 'json',
+ rootProperty: 'data',
+ },
+ },
+ autoLoad: true,
+ },
+ });
+
+ me.items.push({
+ nodename: node,
+ fabricId: name,
+ protocol: me.pveSelNode.data.protocol,
+ xtype: 'pveSDNFabricNeighborsContentView',
+ title: gettext('Neighbors'),
+ iconCls: 'fa fa-handshake-o',
+ itemId: 'neighbors',
+ width: '100%',
+ store: {
+ proxy: {
+ type: 'proxmox',
+ url: `/api2/json/nodes/${node}/sdn/fabrics/${name}/neighbors`,
+ reader: {
+ type: 'json',
+ rootProperty: 'data',
+ },
+ },
+ autoLoad: true,
+ },
+ });
+
+ me.items.push({
+ nodename: node,
+ fabricId: name,
+ protocol: me.pveSelNode.data.protocol,
+ xtype: 'pveSDNFabricInterfacesContentView',
+ title: gettext('Interfaces'),
+ iconCls: 'fa fa-upload',
+ itemId: 'interfaces',
+ width: '100%',
+ store: {
+ proxy: {
+ type: 'proxmox',
+ url: `/api2/json/nodes/${node}/sdn/fabrics/${name}/interfaces`,
+ reader: {
+ type: 'json',
+ rootProperty: 'data',
+ },
+ },
+ autoLoad: true,
+ },
+ });
+ } else if (networkType === 'zone') {
+ const caps = Ext.state.Manager.get('GuiCap');
+
+ me.items.push({
+ nodename: node,
+ zone: name,
+ xtype: 'pveSDNZoneContentPanel',
+ title: gettext('Content'),
+ iconCls: 'fa fa-th',
+ itemId: 'content',
+ });
+
+ if (caps.sdn['Permissions.Modify']) {
+ me.items.push({
+ xtype: 'pveACLView',
+ title: gettext('Permissions'),
+ iconCls: 'fa fa-unlock',
+ itemId: 'permissions',
+ path: `/sdn/zones/${name}`,
+ });
+ }
+
+ me.items.push({
+ nodename: node,
+ zone: name,
+ xtype: 'pveSDNZoneBridgePanel',
+ title: gettext('Bridges'),
+ iconCls: 'fa fa-network-wired x-fa-sdn-treelist',
+ itemId: 'bridges',
+ });
+
+ if (data.zone_type && data.zone_type === 'evpn') {
+ me.items.push({
+ nodename: node,
+ zone: name,
+ xtype: 'pveSDNEvpnZoneIpVrfPanel',
+ title: gettext('IP-VRF'),
+ iconCls: 'fa fa-th-list',
+ itemId: 'ip-vrf',
+ });
+
+ me.items.push({
+ nodename: node,
+ zone: name,
+ xtype: 'pveSDNEvpnZoneMacVrfPanel',
+ title: gettext('MAC-VRFs'),
+ iconCls: 'fa fa-th-list',
+ itemId: 'mac-vrfs',
+ });
+ }
+ } else {
+ me.items.push({
+ xtype: 'container',
+ title: gettext('Content'),
+ iconCls: 'fa fa-th',
+ itemId: 'content',
+ html: `unknown network type: ${networkType}`,
+ width: '100%',
+ });
+ }
+
+ Ext.apply(me, {
+ title: Ext.String.format(
+ gettext('{0} {1} on node {2}'),
+ `${networkType}`,
+ `'${name}'`,
+ `'${node}'`,
+ ),
+ hstateid: 'networktab',
+ });
+
+ me.callParent();
+ },
+});
diff --git a/www/manager6/tree/ResourceTree.js b/www/manager6/tree/ResourceTree.js
index e83ccfc85..b6ab9a1e9 100644
--- a/www/manager6/tree/ResourceTree.js
+++ b/www/manager6/tree/ResourceTree.js
@@ -25,6 +25,10 @@ Ext.define('PVE.tree.ResourceTree', {
iconCls: 'fa fa-th',
text: gettext('SDN'),
},
+ network: {
+ iconCls: 'fa fa-globe',
+ text: gettext('Network'),
+ },
qemu: {
iconCls: 'fa fa-desktop',
text: gettext('Virtual Machine'),
@@ -55,6 +59,8 @@ Ext.define('PVE.tree.ResourceTree', {
return 2;
case 'sdn':
return 3;
+ case 'network':
+ return 3.5;
case 'storage':
return 4;
default:
--
2.47.3
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
next prev parent reply other threads:[~2025-11-07 14:33 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-07 14:31 [pve-devel] [PATCH common/manager/network/proxmox{-ve-rs, -perl-rs} v3 00/39] Improve status reporting for SDN / networking Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-common v3 1/2] iproute2: add helper for detecting bridge members Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-common v3 2/2] iproute2: add helper for querying vlan information Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-ve-rs v3 1/7] frr: make room for deserialization structs Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-ve-rs v3 2/7] frr: add deserialization types for openfabric and ospf Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-ve-rs v3 3/7] ve-config: add helper function to iterate over all nodes in all fabrics Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-ve-rs v3 4/7] ve-config: add optional tag property to vnet Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-ve-rs v3 5/7] frr: fix some route deserialization types Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-ve-rs v3 6/7] frr: add deserialization types for EVPN Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-ve-rs v3 7/7] add derive PartialEq, Eq and HashMap->BTreeMap for tests Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 01/12] pve-rs: firewall: cargo: fmt Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 02/12] pve-rs: firewall: add missing documentation comments Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 03/12] pve-rs: cargo: bump proxmox-apt and proxmox-ve-config versions Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 04/12] pve-rs: fabrics: update proxmox-frr import path Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 05/12] pve-rs: fabrics: fix clippy lint warnings Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 06/12] pve-rs: fabrics: add function to get status of fabric Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 07/12] pve-rs: fabrics: add function to get l2vpn and l3vpn routes for evpn Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 08/12] pve-rs: fabrics: add function to get routes learned by a fabric Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 09/12] pve-rs: fabrics: add function to get the interfaces used for " Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 10/12] pve-rs: fabrics: add function to get the neighbors " Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 11/12] pve-rs: fabrics: add unit-tests for fabrics Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH proxmox-perl-rs v3 12/12] pve-rs: fabrics: add unit-tests for evpn l2vpn and l3vpn routes Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-network v3 1/9] refactor: rework api module structure for the /nodes/{node}/sdn subdir Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-network v3 2/9] fabrics: add fabrics status to SDN::status function Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-network v3 3/9] sdn: status: add zone type to sdn resource Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-network v3 4/9] api: nodes: fabrics: add endpoint for querying route status Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-network v3 5/9] api: nodes: fabrics: add endpoint for querying neighbor information Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-network v3 6/9] api: nodes: fabrics: add endpoint for querying interface status Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-network v3 7/9] api: nodes: zones: add bridge status Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-network v3 8/9] api: nodes: zones: add ip vrf endpoint for evpn zones Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-network v3 9/9] api: nodes: vnets: add mac-vrf endpoint for evpn vnets Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-manager v3 1/9] api: nodes: use new status module for sdn subdirectory Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-manager v3 2/9] refactor: ui: sdn browser: parametrize zone content panel Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-manager v3 3/9] pvestatd: add network resource to status reporting Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-manager v3 4/9] pvestatd: sdn: adapt to changes in " Stefan Hanreich
2025-11-07 14:31 ` Stefan Hanreich [this message]
2025-11-07 14:31 ` [pve-devel] [PATCH pve-manager v3 6/9] ui: network browser: Add ip-vrf panel for evpn zones Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-manager v3 7/9] ui: network browser: add mac vrf panel Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-manager v3 8/9] ui: network browser: add zone bridge view Stefan Hanreich
2025-11-07 14:31 ` [pve-devel] [PATCH pve-manager v3 9/9] ui: sdn: status view: adapt to new network resource Stefan Hanreich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251107143201.689035-36-s.hanreich@proxmox.com \
--to=s.hanreich@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox