From 576752da234765fc8f096099cb38885cbf70becf Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Fri, 12 Jun 2026 14:47:00 +0200 Subject: [PATCH] feat: synthesize LAG/trunk interfaces and support trunk member editing get_interfaces() now fills in ports missing from the /ports collection (e.g. the 4th SFP uplink on a 2530-48G) using system/status/switch, and synthesizes a logical interface for each configured LAG/trunk group with lag_members/lag_mode. New set_lag_members() adds/removes trunk members via the REST /cli passthrough (PUT ports/{id} silently ignores trunk_group). Co-Authored-By: Claude Sonnet 4.6 --- .../__pycache__/api_client.cpython-312.pyc | Bin 0 -> 28583 bytes .../__pycache__/procurve.cpython-312.pyc | Bin 0 -> 59009 bytes napalm_procurve/api_client.py | 48 ++++++++++++++++- napalm_procurve/procurve.py | 49 ++++++++++++++++++ 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 napalm_procurve/__pycache__/api_client.cpython-312.pyc create mode 100644 napalm_procurve/__pycache__/procurve.cpython-312.pyc diff --git a/napalm_procurve/__pycache__/api_client.cpython-312.pyc b/napalm_procurve/__pycache__/api_client.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2de6d5c8a24c54e18a90d7957cb72a23b235740e GIT binary patch literal 28583 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 Ig)IC33yRqoLI3~& literal 0 HcmV?d00001 diff --git a/napalm_procurve/__pycache__/procurve.cpython-312.pyc b/napalm_procurve/__pycache__/procurve.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..caa1f9b80a97dc119b6c16f4a1efd33918e8478b GIT binary patch literal 59009 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 Vsa7Oox&oB$ktox9kDPq4{uc>ZUpxQ+ literal 0 HcmV?d00001 diff --git a/napalm_procurve/api_client.py b/napalm_procurve/api_client.py index f2ac1a8..015f380 100644 --- a/napalm_procurve/api_client.py +++ b/napalm_procurve/api_client.py @@ -242,8 +242,33 @@ class ProcurveApiClient: stats_data = self.get("port-statistics") output: Dict[str, Dict] = {} + trunk_groups: Dict[str, list] = {} + trunk_modes: Dict[str, str] = {} - for port in ports_data.get("port_element", []): + port_elements = list(ports_data.get("port_element", [])) + + # The /ports collection can under-report the switch's true port + # count (observed: a 2530-48G reports 51 of its 52 ports). Fill in + # any ports known to system/status/switch but missing from /ports. + seen_ids = {p.get("id") for p in port_elements} + try: + sw_status = self.get("system/status/switch") + for blade in sw_status.get("blades", []): + for p in blade.get("data_ports", []): + pid = p.get("port_name", "") + if pid and pid not in seen_ids: + port_elements.append({ + "id": pid, + "name": "", + "is_port_up": p.get("operStatus") == "OPER_UP", + "is_port_enabled": p.get("adminStatus") == "ADMIN_UP", + "trunk_group": "", + }) + seen_ids.add(pid) + except Exception: + pass + + for port in port_elements: pid = port.get("id", "") output[pid] = { "is_up": bool(port.get("is_port_up", False)), @@ -254,12 +279,33 @@ class ProcurveApiClient: "mtu": -1, "mac_address": "", } + group = port.get("trunk_group") or "" + if group: + output[pid]["trunk_group"] = group + trunk_groups.setdefault(group, []).append(pid) + if port.get("trunk_mode"): + trunk_modes[group] = port["trunk_mode"] for stat in stats_data.get("port_statistics_element", []): pid = stat.get("id", "") if pid in output: output[pid]["speed"] = float(stat.get("port_speed_mbps", 0)) + # Synthesize a logical interface entry for each configured LAG/trunk + # group so it shows up as its own row alongside its member ports. + for group, members in trunk_groups.items(): + output[group] = { + "is_up": any(output[m]["is_up"] for m in members), + "is_enabled": any(output[m]["is_enabled"] for m in members), + "description": f"LAG ({', '.join(sorted(members, key=lambda s: int(s) if s.isdigit() else 0))})", + "last_flapped": -1.0, + "speed": sum(output[m]["speed"] for m in members), + "mtu": -1, + "mac_address": "", + "lag_members": members, + "lag_mode": "lacp" if trunk_modes.get(group) == "PTT_LACP" else "trunk", + } + return output def get_interfaces_ip(self) -> Dict[str, Dict]: diff --git a/napalm_procurve/procurve.py b/napalm_procurve/procurve.py index 1e8ff39..7934f98 100644 --- a/napalm_procurve/procurve.py +++ b/napalm_procurve/procurve.py @@ -796,6 +796,55 @@ class ProcurveDriver(SwitchDriver): self._exit_config_mode() self._save_config() + # ------------------------------------------------------------------ + # LAG / trunk membership + # ------------------------------------------------------------------ + + def set_lag_members(self, lag_name: str, members: List[str]) -> None: + """Set the full member-port list of a LAG/trunk group. + + Diffs ``members`` against the trunk's current members (as reported + by ``get_interfaces()``) and issues ``trunk``/``no trunk`` commands + for the difference. Available on both REST API and CLI transports — + ArubaOS-Switch only exposes trunk membership via the CLI, including + through the REST API's ``/cli`` passthrough endpoint (``PUT /ports`` + does not apply ``trunk_group``/``trunk_mode`` changes). + """ + current = self.get_interfaces().get(lag_name, {}) + current_members = set(current.get("lag_members") or []) + desired = set(members) + to_remove = sorted(current_members - desired, key=lambda s: int(s) if s.isdigit() else 0) + to_add = sorted(desired - current_members, key=lambda s: int(s) if s.isdigit() else 0) + + if not to_remove and not to_add: + return + + mode = current.get("lag_mode") or "trunk" + trk_name = lag_name.lower() + + commands: List[str] = [] + if to_remove: + commands.append(f"no trunk {','.join(to_remove)}") + if to_add: + commands.append(f"trunk {','.join(to_add)} {trk_name} {mode}") + + if self._transport == "api": + for cmd in ["configure terminal", *commands]: + resp = self._api.post("cli", json={"cmd": cmd}) + if not resp.ok or resp.json().get("status") == "CCS_FAILURE": + raise CommandErrorException( + f"set_lag_members({lag_name}): '{cmd}' -> {resp.text[:200]}" + ) + else: + self._enter_config_mode() + try: + errors = self._apply_config_lines("\n".join(commands)) + if errors: + raise CommandErrorException(f"set_lag_members({lag_name}) errors: {errors}") + finally: + self._exit_config_mode() + self._save_config() + def set_interface(self, interface: str, config: InterfaceConfigDict) -> None: """Configure a switch interface (mode, VLAN membership).""" if self._transport == "api":