From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <pve-devel-bounces@lists.proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
	by lore.proxmox.com (Postfix) with ESMTPS id 7841F1FF16F
	for <inbox@lore.proxmox.com>; Tue, 27 May 2025 16:06:08 +0200 (CEST)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
	by firstgate.proxmox.com (Proxmox) with ESMTP id 5F1D116B26;
	Tue, 27 May 2025 16:06:12 +0200 (CEST)
From: Gabriel Goller <g.goller@proxmox.com>
To: pve-devel@lists.proxmox.com
Date: Tue, 27 May 2025 16:04:45 +0200
Message-Id: <20250527140446.365983-2-g.goller@proxmox.com>
X-Mailer: git-send-email 2.39.5
In-Reply-To: <20250527140446.365983-1-g.goller@proxmox.com>
References: <20250527140446.365983-1-g.goller@proxmox.com>
MIME-Version: 1.0
X-SPAM-LEVEL: Spam detection results:  0
 AWL -0.171 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DMARC_MISSING             0.1 Missing DMARC policy
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 POISEN_SPAM_PILL          0.1 Meta: its spam
 POISEN_SPAM_PILL_1        0.1 random spam to be learned in bayes
 POISEN_SPAM_PILL_3        0.1 random spam to be learned in bayes
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
Subject: [pve-devel] [PATCH pve-manager v5 1/2] lxc: show dynamically
 assigned IPs in network tab
X-BeenThere: pve-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/>
List-Post: <mailto:pve-devel@lists.proxmox.com>
List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe>
Reply-To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: pve-devel-bounces@lists.proxmox.com
Sender: "pve-devel" <pve-devel-bounces@lists.proxmox.com>

Adds a call to /nodes/{node}/lxc/{vmid}/interfaces and merges the
returned data with the existing configuration. This will update the
IPv4 and IPv6 address, as well as the interface name (in case the
container changed it).

Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
---
 www/manager6/lxc/Network.js | 115 ++++++++++++++++++++++++++----------
 1 file changed, 84 insertions(+), 31 deletions(-)

diff --git a/www/manager6/lxc/Network.js b/www/manager6/lxc/Network.js
index b2cd94109485..bfe918d516ae 100644
--- a/www/manager6/lxc/Network.js
+++ b/www/manager6/lxc/Network.js
@@ -351,33 +351,72 @@ Ext.define('PVE.lxc.NetworkView', {
     stateful: true,
     stateId: 'grid-lxc-network',
 
-    load: function() {
+    load: async function() {
 	let me = this;
 
 	Proxmox.Utils.setErrorMask(me, true);
 
-	Proxmox.Utils.API2Request({
-	    url: me.url,
-	    failure: function(response, opts) {
-		Proxmox.Utils.setErrorMask(me, gettext('Error') + ': ' + response.htmlStatus);
-	    },
-	    success: function(response, opts) {
-		Proxmox.Utils.setErrorMask(me, false);
-		let result = Ext.decode(response.responseText);
-		me.dataCache = result.data || {};
-		let records = [];
-		for (const [key, value] of Object.entries(me.dataCache)) {
-		    if (key.match(/^net\d+/)) {
-			let net = PVE.Parser.parseLxcNetwork(value);
-			net.id = key;
-			records.push(net);
+	let nodename = me.pveSelNode.data.node;
+	let vmid = me.pveSelNode.data.vmid;
+
+	try {
+	    let ifResponse = await Proxmox.Async.api2({
+		url: `/nodes/${nodename}/lxc/${vmid}/interfaces`,
+		method: 'GET',
+	    });
+	    let confResponse = await Proxmox.Async.api2({
+		url: me.url,
+	    });
+	    Proxmox.Utils.setErrorMask(me, false);
+
+	    let interfaces = [];
+	    for (const [, iface] of Object.entries(ifResponse?.result?.data || {})) {
+		interfaces[iface['hardware-address']] = iface;
+	    }
+
+	    let records = [];
+	    me.dataCache = confResponse.result.data || {};
+	    for (const [key, value] of Object.entries(confResponse.result.data)) {
+		if (!key.match(/^net\d+/)) {
+		    continue;
+		}
+		let config = PVE.Parser.parseLxcNetwork(value);
+		let net = structuredClone(config);
+		net.id = key;
+
+		let iface = interfaces[config.hwaddr.toLowerCase()];
+		if (iface) {
+		    net.name = iface.name;
+		    net.ip = [];
+		    net.ip6 = [];
+		    for (const i of iface['ip-addresses']) {
+			let ip_with_prefix = `${i['ip-address']}/${i.prefix}`;
+			if (i['ip-address-type'] === "inet") {
+			    if (config.ip === ip_with_prefix) {
+				net.ip.push(`${ip_with_prefix} (static)`);
+			    } else {
+				// this could be dhcp, but also a static address set directly on the container
+				net.ip.push(`${ip_with_prefix} (dynamic)`);
+			    }
+			} else if (i['ip-address-type'] === "inet6") {
+			    if (config.ip6 === ip_with_prefix) {
+				net.ip6.push(`${ip_with_prefix} (static)`);
+			    } else {
+				// this could be dhcp, slaac, but also a static address set directly on the container
+				net.ip6.push(`${ip_with_prefix} (dynamic)`);
+			    }
+			}
 		    }
 		}
-		me.store.loadData(records);
-		me.down('button[name=addButton]').setDisabled(records.length >= 32);
-	    },
-	});
-    },
+		records.push(net);
+	    }
+
+	    me.store.loadData(records);
+	    me.down('button[name=addButton]').setDisabled(records.length >= 32);
+	} catch (error) {
+	    Proxmox.Utils.setErrorMask(me, gettext('Error') + ': ' + error);
+	}
+},
 
     initComponent: function() {
 	let me = this;
@@ -504,7 +543,7 @@ Ext.define('PVE.lxc.NetworkView', {
 		},
 		{
 		    header: gettext('VLAN Tag'),
-		    width: 80,
+		    width: 70,
 		    dataIndex: 'tag',
 		},
 		{
@@ -514,16 +553,30 @@ Ext.define('PVE.lxc.NetworkView', {
 		},
 		{
 		    header: gettext('IP address'),
-		    width: 150,
+		    width: 300,
 		    dataIndex: 'ip',
-		    renderer: function(value, metaData, rec) {
-			if (rec.data.ip && rec.data.ip6) {
-			    return rec.data.ip + "<br>" + rec.data.ip6;
-			} else if (rec.data.ip6) {
-			    return rec.data.ip6;
-			} else {
-			    return rec.data.ip;
-			}
+		    renderer: function(_value, _metaData, rec) {
+			const formatIpValue = (value, prefix) => {
+			    if (Array.isArray(value) && value.length > 0) {
+				// multiple addresses (usually from the api)
+				return value.join("<br>") + "<br>";
+			    } else if (typeof value === 'string') {
+				if (value === "dhcp") {
+				    // ipv4 and ipv6 dhcp
+				    return `${prefix}dhcp <br>`;
+				} else if (value === "auto") {
+				    // ipv6 slaac
+				    return `${prefix}auto <br>`;
+				} else if (value.length > 0) {
+				    // single address (usually from config)
+				    return value + "<br>";
+				}
+			    }
+			    return '';
+			};
+
+			return formatIpValue(rec.data.ip, 'ip: ') +
+			       formatIpValue(rec.data.ip6, 'ip6: ');
 		    },
 		},
 		{
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel