# 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 = [
['', '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 `
`/`
` 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=` |
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