These switches have no CLI at all — no SSH, no Telnet and no ArubaOS-Switch REST API — so the ProCurve driver cannot serve them despite the shared vendor. The only management surface is the web UI, which ships its table data as JavaScript array literals; those parse with ast.literal_eval, so the driver needs no HTML parser and no dependency beyond napalm/requests. Read-only by design: the platform exposes a single administrator account with no privilege levels, and serves HTTPS only after a certificate has been uploaded, so the polling credential is necessarily the admin credential over a plain channel. Implements get_facts, get_interfaces, get_vlans, get_vlans_detail and get_mac_address_table, plus HTTP/SNMP fingerprints for discovery. Tested against an HPE OfficeConnect 1820 8G PoE+ (65W), J9982A, PT.02.19.
137 lines
4.9 KiB
Markdown
137 lines
4.9 KiB
Markdown
# napalm-hpe-officeconnect
|
|
|
|
NAPALM driver for **HPE OfficeConnect** web-managed switches — 1820 and 1920S.
|
|
|
|
## Why this is not part of `napalm-hpe-aruba-procurve`
|
|
|
|
Despite the shared vendor, these are unrelated platforms:
|
|
|
|
| | ProCurve / ArubaOS-Switch | OfficeConnect 1820 / 1920S |
|
|
|---|---|---|
|
|
| Base OS | ProVision / ArubaOS-Switch | Broadcom FASTPATH derivative |
|
|
| SSH / Telnet | yes | **none at all** |
|
|
| REST API | ArubaOS-Switch REST v3/v6/v7 | none |
|
|
| Management | CLI + REST + web | web only |
|
|
|
|
The ProCurve driver's four transports (REST, SSH, legacy-KEX SSH, Telnet) all
|
|
require something this hardware does not have. There is no shared transport,
|
|
no shared command set and no shared parser, so the two drivers share nothing
|
|
but a vendor name.
|
|
|
|
The real HP **1920** (without the S) is a *third* platform — Comware 5, with a
|
|
`display`-style CLI — and would need its own driver again.
|
|
|
|
## Design
|
|
|
|
The switch has no machine API, so the driver reads the web UI. Every list page
|
|
is a jQuery DataTable whose payload is embedded as JavaScript:
|
|
|
|
```js
|
|
var aDataSet = [
|
|
['<input type="checkbox" ...>', '1', '', 'Enabled', 'Normal', 'Link Up', ...]
|
|
];
|
|
var aColumns = [ { "sTitle": "Interface", ... }, ... ];
|
|
```
|
|
|
|
That array literal is also valid Python, so `parsers.extract_data_set` parses
|
|
it with `ast.literal_eval`. No HTML parser is involved and the package needs
|
|
no dependency beyond `napalm` and `requests`.
|
|
|
|
This is a property of firmware PT.02.xx and newer. Older 1820 firmware
|
|
server-rendered the same tables as `<tr>`/`<td>` markup — which is why the
|
|
(unmaintained, last commit 2017) [hp1820-cli](https://github.com/BookGin/hp1820-cli)
|
|
scraper does not work on current firmware. Its endpoint list was nonetheless a
|
|
useful map when writing this driver.
|
|
|
|
## Endpoints
|
|
|
|
| Purpose | Path |
|
|
|---|---|
|
|
| Login | `POST /htdocs/login/login.lua` |
|
|
| Logout | `/htdocs/pages/main/logout.lsp` |
|
|
| Facts | `/htdocs/pages/base/dashboard.lsp` |
|
|
| Interfaces | `/htdocs/pages/base/port_summary.lsp` |
|
|
| MAC table | `/htdocs/pages/base/mac_address_table.lsp` |
|
|
| VLANs | `/htdocs/pages/switching/vlan_status.lsp` |
|
|
| VLAN membership | `/htdocs/pages/switching/vlan_per_port.lsp?vlan=<id>` |
|
|
|
|
Authentication is a form POST answering JSON; an empty `error` field means
|
|
success. Firmware generations disagree about the other fields, so `error` is
|
|
the only one worth branching on.
|
|
|
|
## Read-only by design
|
|
|
|
The driver implements no write path. Two properties of the platform make that
|
|
the right default:
|
|
|
|
- **One account, no privilege levels.** `user_accounts.lsp` offers a username
|
|
and a password change — there is no read-only role — so the polling
|
|
credential is necessarily the administrator credential.
|
|
- **HTTP unless a certificate was uploaded.** The switch serves HTTPS only
|
|
after an operator installs a certificate; out of the box the session, and
|
|
therefore that admin credential, crosses the network in the clear.
|
|
|
|
Set `optional_args={"scheme": "https"}` once a certificate is in place.
|
|
|
|
**Session hygiene:** the switch keeps a small table of concurrent sessions and
|
|
reclaims them only on idle timeout. `close()` always logs out, including on
|
|
the failure path, or repeated polling will eventually lock the administrator
|
|
out of the web UI.
|
|
|
|
## Supported methods
|
|
|
|
| Method | Status |
|
|
|---|---|
|
|
| `open` / `close` / `is_alive` | ✅ |
|
|
| `get_facts` | ✅ |
|
|
| `get_interfaces` | ✅ |
|
|
| `get_vlans` | ✅ |
|
|
| `get_vlans_detail` | ✅ tagged/untagged split |
|
|
| `get_mac_address_table` | ✅ |
|
|
| `get_interfaces_counters` | ❌ see below |
|
|
| `get_config` | ❌ not yet |
|
|
| config load / commit / rollback | ❌ by design |
|
|
|
|
### Known gaps
|
|
|
|
- **`get_interfaces_counters`** raises `NotImplementedError`.
|
|
`port_summary_stats.lsp` declares its columns but ships an empty dataset on
|
|
PT.02.19 and carries no AJAX endpoint that would fill it. Returning zeros
|
|
would be indistinguishable from a switch that has genuinely passed no
|
|
traffic, so the driver refuses rather than inventing data.
|
|
- **`get_config`** is unimplemented. The source would be
|
|
`/htdocs/lua/ajax/file_download_ajax.lua?protocol=6`, reachable but not yet
|
|
mapped.
|
|
- **SNMP.** The switch answers SNMPv2c (verified against a J9982A: `sysDescr`
|
|
repeats the model string and `sysObjectID` is `1.3.6.1.4.1.11.2.3.7.11.170`),
|
|
and the driver declares SNMP fingerprints accordingly. It does not yet
|
|
implement `get_snmp_config` or `get_health_metrics`, so CPU/memory readings —
|
|
which the web dashboard does show — are not surfaced.
|
|
|
|
## Usage
|
|
|
|
```python
|
|
from napalm import get_network_driver
|
|
|
|
Driver = get_network_driver("hpe_officeconnect")
|
|
|
|
with Driver("192.0.2.20", "admin", "secret") as dev:
|
|
print(dev.get_facts())
|
|
print(dev.get_vlans())
|
|
```
|
|
|
|
## Tests
|
|
|
|
Fixtures are real pages captured from an HPE OfficeConnect 1820 8G PoE+
|
|
(J9982A, PT.02.19), scrubbed of serial number, MAC addresses, IP addresses,
|
|
hostname and location.
|
|
|
|
```bash
|
|
pip install -e ".[dev]"
|
|
pytest tests/
|
|
```
|
|
|
|
## License
|
|
|
|
Apache 2.0
|