When clicking on the fabric resources a new content view is available. It shows the routes and the neighbors of the fabric on that specific node.
Signed-off-by: Gabriel Goller <g.gol...@proxmox.com> --- www/manager6/Makefile | 1 + www/manager6/sdn/Browser.js | 120 ++++++++++++++++++++----- www/manager6/sdn/FabricsContentView.js | 91 +++++++++++++++++++ www/manager6/sdn/StatusView.js | 2 +- 4 files changed, 191 insertions(+), 23 deletions(-) create mode 100644 www/manager6/sdn/FabricsContentView.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index 07401f21520b..8b4d672f5145 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -313,6 +313,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/sdn/Browser.js b/www/manager6/sdn/Browser.js index f7694ae91864..af82bd6390d3 100644 --- a/www/manager6/sdn/Browser.js +++ b/www/manager6/sdn/Browser.js @@ -15,39 +15,115 @@ Ext.define('PVE.sdn.Browser', { if (!sdnId) { throw 'no sdn ID specified'; } + let sdnType = me.pveSelNode.data.sdn_type; + if (!sdnType) { + throw 'no sdn object type specified'; + } me.items = []; + const caps = Ext.state.Manager.get('GuiCap'); + + switch (sdnType) { + case 'zone': + me.items.push({ + nodename: nodename, + zone: sdnId, + 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/${sdnId}`, + }); + } + break; + case 'fabric': + { + let neighborStore = new Ext.data.Store({ + model: 'Neighbor', + proxy: { + type: 'proxmox', + url: '/api2/json/cluster/sdn/fabrics/neighbors', + reader: { + type: 'json', + rootProperty: 'data', + }, + extraParams: { + node: nodename, + }, + }, + autoLoad: true, + }); + + let routeStore = new Ext.data.Store({ + model: 'Route', + proxy: { + type: 'proxmox', + url: '/api2/json/cluster/sdn/fabrics/routes', + reader: { + type: 'json', + rootProperty: 'data', + }, + extraParams: { + node: nodename, + }, + }, + autoLoad: true, + }); + + me.items.push({ + nodename: nodename, + routeStore: routeStore, + fabricId: sdnId, + protocol: me.pveSelNode.data.protocol, + xtype: 'pveSDNFabricRoutesContentView', + title: gettext('Routes'), + iconCls: 'fa fa-th', + itemId: 'routes', + width: '100%', + }); + me.items.push({ + nodename: nodename, + neighborStore: neighborStore, + fabricId: sdnId, + protocol: me.pveSelNode.data.protocol, + xtype: 'pveSDNFabricNeighborsContentView', + title: gettext('Neighbors'), + iconCls: 'fa fa-th', + itemId: 'neighbors', + width: '100%', + }); + } + break; + } + Ext.apply(me, { title: Ext.String.format( - gettext('Zone {0} on node {1}'), + gettext('{0} {1} on node {2}'), + `${sdnType}`, `'${sdnId}'`, `'${nodename}'`, ), hstateid: 'sdntab', }); - const caps = Ext.state.Manager.get('GuiCap'); - - me.items.push({ - nodename: nodename, - zone: sdnId, - 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/${sdnId}`, - }); - } - me.callParent(); }, }); + +Ext.define('Route', { + extend: 'Ext.data.Model', + fields: ['route', 'via', 'fabric_id', 'protocol'], +}); +Ext.define('Neighbor', { + extend: 'Ext.data.Model', + fields: ['neighbor', 'status', 'fabric_id', 'protocol'], +}); diff --git a/www/manager6/sdn/FabricsContentView.js b/www/manager6/sdn/FabricsContentView.js new file mode 100644 index 000000000000..f1e5ec146b8b --- /dev/null +++ b/www/manager6/sdn/FabricsContentView.js @@ -0,0 +1,91 @@ +Ext.define('PVE.sdn.FabricRoutesContentView', { + extend: 'Ext.grid.GridPanel', + alias: 'widget.pveSDNFabricRoutesContentView', + + initComponent: function () { + let me = this; + let sm = Ext.create('Ext.selection.RowModel', {}); + + me.routeStore.addFilter([ + { + property: 'fabric_id', + value: me.fabricId, + }, + { + property: 'protocol', + value: me.protocol, + }, + ]); + me.routeStore.sort('route', 'ASC'); + + Ext.apply(me, { + store: me.routeStore, + selModel: sm, + columns: [ + { + header: 'Route', + sortable: true, + dataIndex: 'route', + flex: 1, + }, + { + header: 'Via', + sortable: true, + dataIndex: 'via', + renderer: (value) => { + if (Ext.isArray(value)) { + return value.join('<br>'); + } + return value || ''; + }, + flex: 1, + }, + ], + }); + + me.callParent(); + }, +}); + +Ext.define('PVE.sdn.FabricNeighborsContentView', { + extend: 'Ext.grid.GridPanel', + alias: 'widget.pveSDNFabricNeighborsContentView', + + initComponent: function () { + let me = this; + let sm = Ext.create('Ext.selection.RowModel', {}); + + me.neighborStore.addFilter([ + { + property: 'fabric_id', + value: me.fabricId, + }, + { + property: 'protocol', + value: me.protocol, + }, + ]); + me.neighborStore.sort('neighbor', 'ASC'); + + Ext.apply(me, { + store: me.neighborStore, + selModel: sm, + columns: [ + { + header: 'Neighbor', + sortable: true, + dataIndex: 'neighbor', + flex: 1, + }, + { + header: 'Status', + sortable: true, + dataIndex: 'status', + flex: 0.5, + }, + ], + }); + + me.callParent(); + }, +}); diff --git a/www/manager6/sdn/StatusView.js b/www/manager6/sdn/StatusView.js index dd05c73fdfcf..e66e3f624354 100644 --- a/www/manager6/sdn/StatusView.js +++ b/www/manager6/sdn/StatusView.js @@ -102,7 +102,7 @@ Ext.define( function () { Ext.define('pve-sdn-status', { extend: 'Ext.data.Model', - fields: ['id', 'type', 'node', 'status', 'sdn'], + fields: ['id', 'type', 'node', 'status', 'sdn', 'sdn_type'], idProperty: 'id', }); }, -- 2.47.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel