Christian Manivong f35b59ec2d fix(cli): read J.15 port status, and say why each transport failed
A 2800-series switch on J.15.09 polled over CLI came back with no
interfaces and an empty OS version, while VLANs and ARP parsed fine.

`show interfaces brief` on that firmware has an Intrusion Alert column
between the `|` and Enabled, and puts Mode before MDI rather than after:

      Port   Type      | Alert     Enabled Status Mode       Mode ...
      3-Trk3 100/1000T | No        Yes     Down   1000FDx    MDI  ...

The regex read Alert as Enabled, then failed on Yes where it wanted
Up|Down, so no line matched. It now skips the Alert column where there is
one and takes the speed from either position. Trunk members are listed as
`<port>-Trk<n>`; the port is `<port>` and the suffix becomes its
trunk_group, so the per-port `show interfaces 3` is a command the switch
knows.

The empty OS version was the alternatives list in _send_command. It moved
to the next command on "% Invalid" or "Error", but ProCurve rejects an
unknown command with "Invalid input: system-information" -- so that line
was parsed as system information. "Invalid input" now counts as failure.

Getting there took longer than it should have, because the first symptom
was "Authentication failed: Login failed". That was Telnet's error, the
last transport tried; the REST probe and both SSH attempts had failed
before it and said nothing above debug level. In fact the switch had run
out of CLI sessions and closed SSH straight after the password. open()
now records why each transport failed, and both the auth error and the
final "Cannot connect" carry that list.

Fixtures are that switch's output, with hostname, serial and MAC
replaced.

Closes #2
Closes #3
Closes #4
2026-09-25 08:55:11 +02:00

napalm-hpe-aruba-procurve

NAPALM driver for HPE / Aruba ProCurve switches — from ancient 2520G-8-PoE to modern 2530/2540 series.

Transport auto-detection

The driver probes transports in order and uses the first one that succeeds:

Priority Transport Notes
1 REST API (HTTPS → HTTP, v7 → v6) Newer 2530/2540 with rest-interface enabled
2 SSH (standard) hp_procurve netmiko driver
3 SSH (legacy KEX) Forces older kex/cipher negotiation for 2520G-8-PoE etc.
4 Telnet Oldest devices without SSH or with broken SSH

Override the transport with optional_args={"transport": "ssh_legacy"} to skip auto-detection.

Switch prerequisites

REST API (newer switches, e.g. 2530, 2540)

web-management ssl
rest-interface
rest-interface session-idle-timeout 120

SSH (all ProCurve)

crypto key generate ssh rsa
ip ssh

Telnet is enabled by default on most ProCurve switches.

Installation

pip install napalm napalm-hpe-aruba-procurve

Or from source:

git clone https://github.com/chrismanivong/napalm-hpe-aruba-procurve
pip install -e napalm-hpe-aruba-procurve/

Quick start

from napalm import get_network_driver

Driver = get_network_driver("procurve")

with Driver(
    "10.0.0.1",
    "manager",
    "secret",
    optional_args={
        # "transport": "ssh",          # force transport (api/ssh/ssh_legacy/telnet)
        # "port": 22,
        # "ssl_verify": False,         # disable SSL cert check for API
        # "api_version": "v7",         # API version hint (v3/v6/v7)
        # "secret": "enablepassword",  # enable password for CLI
    },
) as dev:
    print(dev.get_facts())
    print(dev.get_interfaces())

Supported NAPALM methods

Method API SSH/Telnet
open() ✅ ✅
close() ✅ ✅
is_alive() ✅ ✅
get_facts() ✅ ✅
get_interfaces() ✅ ✅
get_interfaces_ip() ✅ ✅
get_arp_table() ✅ ✅
get_mac_address_table() ✅ ✅
get_lldp_neighbors() ✅ ✅
get_lldp_neighbors_detail() ✅ ✅
get_config() ✅ ✅
get_ntp_servers() ✅ ✅
get_environment() ❌ ✅
get_users() ❌ ✅
get_snmp_information() ❌ ✅
ping() ✅ ✅
cli() ✅ ✅
load_merge_candidate() ❌ ✅
load_replace_candidate() ❌ ✅
compare_config() ❌ ✅
commit_config() ❌ ✅
discard_config() ❌ ✅
rollback() ❌ ✅

Tested devices

  • HP ProCurve 2520G-8-PoE (J9565A) — SSH legacy / Telnet
  • HP ProCurve 2920-48G — SSH
  • Aruba 2530-8-PoE+ — SSH + REST API

License

Apache 2.0

S
Description
No description provided
Readme
516 KiB
Languages
Python 100%