feat: NAPALM driver for HPE OfficeConnect 1820/1920S

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.
This commit is contained in:
Christian Manivong
2026-08-10 20:45:55 +07:00
commit c76a177ff2
23 changed files with 4302 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
__pycache__/
*.py[cod]
*.egg-info/
build/
dist/
.venv/
venv/
.pytest_cache/
.ruff_cache/
.coverage
htmlcov/
+191
View File
@@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship made available under
the License, as indicated by a copyright notice that is included in
or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other transformations
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean, as submitted to the Licensor for inclusion
in the Work by the copyright owner or by an individual or Legal Entity
authorized to submit on behalf of the copyright owner. For the purposes
of this definition, "submitted" means any form of electronic, verbal,
or written communication sent to the Licensor or its representatives,
including but not limited to communication on electronic mailing lists,
source code control systems, and issue tracking systems that are managed
by, or on behalf of, the Licensor for the purpose of discussing and
improving the Work, but excluding communication that is conspicuously
marked or designated in writing by the copyright owner as "Not a
Contribution."
"Contributor" shall mean Licensor and any Legal Entity on behalf of
whom a Contribution has been received by the Licensor and incorporated
within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by the combined Contribution(s) and the Work
to which such Contribution(s) was submitted. If You institute patent
litigation against any entity (including a cross-claim or counterclaim
in a lawsuit) alleging that the Work or any Contribution embodied
within the Work constitutes direct or contributory patent infringement,
then any patent licenses granted to You under this License for that
Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or Derivative
Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, You must include a readable copy of the
attribution notices contained within such NOTICE file, in
at least one of the following places: within a NOTICE text file
distributed as part of the Derivative Works; within the Source
form or documentation, if provided along with the Derivative
Works; or, within a display generated by the Derivative Works,
if and wherever such third-party notices normally appear. The
contents of the NOTICE file are for informational purposes only
and do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own license statement for Your modifications and
may provide additional grant of rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Work,
and to permit persons to whom the Work is furnished to do so,
subject to the following conditions:
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any conditions of TITLE,
MERCHANTIBILITY, or FITNESS FOR A PARTICULAR PURPOSE.
See the License for the specific language governing permissions and
limitations under the License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or exemplary damages of any character arising as a
result of this License or out of the use or inability to use the
Work (even if such Contributor has been advised of the possibility
of such damages).
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may offer only
conditions consistent with this License, subject to the following
additional conditions:
(a) You may offer additional warranty, indemnity, or other liability
terms and conditions; and
(b) You may offer support for the Work in return for a fee.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format in question. It may also be
possible to make it available with a creative commons license.
Copyright 2026 Christian Manivong
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+136
View File
@@ -0,0 +1,136 @@
# 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
+5
View File
@@ -0,0 +1,5 @@
"""NAPALM driver for HPE OfficeConnect 1820 / 1920S web-managed switches."""
from napalm_hpe_officeconnect.officeconnect import OfficeConnectDriver
__all__ = ["OfficeConnectDriver"]
+145
View File
@@ -0,0 +1,145 @@
"""HTTP session handling for HPE OfficeConnect switches.
The switch authenticates with a form POST that answers JSON and hands out a
``SID`` cookie::
GET /htdocs/login/login.lsp → sets the short-lived RID cookie
POST /htdocs/login/login.lua → {"redirect": "...", "error": ""}
GET /htdocs/pages/main/logout.lsp
An empty ``error`` means success. Firmware generations differ in what else
they put in that object — older builds omit ``redirect``, newer ones omit
``username`` — so ``error`` is the only field worth branching on.
Session hygiene matters here: the switch keeps a small table of concurrent
sessions and only reclaims them on idle timeout. A driver that logs in on
every poll and never logs out will eventually lock the administrator out of
the web UI, so :meth:`logout` is best-effort and always safe to call.
"""
from __future__ import annotations
import logging
import requests
from napalm.base.exceptions import (
CommandErrorException,
ConnectionClosedException,
ConnectionException,
)
logger = logging.getLogger("napalm_hpe_officeconnect")
LOGIN_PAGE = "/htdocs/login/login.lsp"
LOGIN_ENDPOINT = "/htdocs/login/login.lua"
LOGOUT_ENDPOINT = "/htdocs/pages/main/logout.lsp"
class OfficeConnectClient:
"""Authenticated HTTP session against an OfficeConnect switch."""
def __init__(
self,
host: str,
username: str,
password: str,
scheme: str = "http",
port: int | None = None,
timeout: int = 30,
verify: bool = False,
) -> None:
self.host = host
self.username = username
self.password = password
# HTTP by default: the switch only serves HTTPS once an operator has
# uploaded a certificate, which is not the common case.
self.scheme = scheme
self.port = port
self.timeout = timeout
self.verify = verify
self._session = requests.Session()
self._authenticated = False
@property
def base_url(self) -> str:
if self.port:
return f"{self.scheme}://{self.host}:{self.port}"
return f"{self.scheme}://{self.host}"
@property
def is_authenticated(self) -> bool:
return self._authenticated
def login(self) -> None:
"""Establish a session. Raises ConnectionException on any failure."""
try:
# The login page issues the RID cookie the POST is validated against.
self._session.get(self.base_url + LOGIN_PAGE, timeout=self.timeout, verify=self.verify)
response = self._session.post(
self.base_url + LOGIN_ENDPOINT,
data={"username": self.username, "password": self.password},
timeout=self.timeout,
verify=self.verify,
)
except requests.RequestException as exc:
raise ConnectionException(f"Cannot reach {self.host}: {exc}") from exc
try:
payload = response.json()
except ValueError as exc:
raise ConnectionException(
f"Login to {self.host} returned no JSON "
f"(HTTP {response.status_code}) — is this an OfficeConnect switch?"
) from exc
error = (payload.get("error") or "").strip()
if error:
raise ConnectionException(f"Login to {self.host} failed: {error}")
self._authenticated = True
def fetch(self, path: str) -> str:
"""Return the body of an authenticated page."""
if not self._authenticated:
raise ConnectionException(f"Not logged in to {self.host} — call login() first")
try:
response = self._session.get(
self.base_url + path,
timeout=self.timeout,
verify=self.verify,
# Do not follow the redirect: a 3xx here *is* the error signal.
allow_redirects=False,
)
except requests.RequestException as exc:
raise ConnectionClosedException(f"Request to {self.host}{path} failed: {exc}") from exc
if 300 <= response.status_code < 400:
# The switch bounces expired sessions to the login page instead of
# answering 401.
self._authenticated = False
raise ConnectionClosedException(f"Session to {self.host} expired while fetching {path}")
if response.status_code != 200:
raise CommandErrorException(f"{self.host}{path} returned HTTP {response.status_code}")
return response.text
def logout(self) -> None:
"""Release the session. Best-effort: never raises.
Called from ``close()``, including on the failure path, where raising
would mask the exception that actually caused the disconnect.
"""
if not self._authenticated:
return
try:
self._session.get(
self.base_url + LOGOUT_ENDPOINT,
timeout=self.timeout,
verify=self.verify,
allow_redirects=False,
)
except Exception as exc: # noqa: BLE001 — deliberate: see docstring
logger.debug("Logout from %s failed, session will idle out: %s", self.host, exc)
finally:
self._authenticated = False
+241
View File
@@ -0,0 +1,241 @@
"""NAPALM driver for HPE OfficeConnect 1820 / 1920S web-managed switches.
These are Broadcom FASTPATH-derived "smart managed" switches with **no CLI
at all** — no SSH, no Telnet, and no ArubaOS-Switch REST API. The only
management surface is the web UI, so this driver drives that UI directly.
That is why it shares no code with ``napalm-hpe-aruba-procurve``: a
ProCurve/ArubaOS-Switch speaks ``show``/``configure`` over SSH, which does
not exist here.
The driver is deliberately **read-only**. These switches expose a single
administrator account with no privilege levels, and unless an operator has
uploaded a certificate the session runs over plain HTTP — so the credential
used for polling is necessarily the admin credential. Not implementing any
write path keeps this driver from being the thing that changes a switch
over an unauthenticated channel.
Tested against: HPE OfficeConnect 1820 8G PoE+ (65W), J9982A, firmware PT.02.19.
"""
from __future__ import annotations
import logging
import re
from typing import Any, ClassVar
from napalm_device_types import FingerprintRule, SwitchDriver
from napalm_hpe_officeconnect import parsers
from napalm_hpe_officeconnect.client import OfficeConnectClient
logger = logging.getLogger("napalm_hpe_officeconnect")
_SPEED_RE = re.compile(r"(\d+)\s*Mbps", re.IGNORECASE)
# Participation values that make an interface a member of a VLAN.
_MEMBER_STATES = ("untagged", "tagged")
class OfficeConnectDriver(SwitchDriver):
"""NAPALM driver for HPE OfficeConnect web-managed switches."""
VENDOR = "HPE"
DRIVER_NAME = "hpe_officeconnect"
# The ProCurve driver claims the bare HPE enterprise arc (1.3.6.1.4.1.11).
# OfficeConnect models sit under .2.3.7.11 — claiming the longer arc keeps
# the two drivers from competing for the same device.
SNMP_OBJECT_ID_PREFIX = "1.3.6.1.4.1.11.2.3.7.11"
# Verified on a J9982A. Deliberately narrow — a wrong OUI produces false
# positives, while a missing one only costs a few points of confidence.
OUI_PREFIXES: ClassVar[list[str]] = ["70:10:6F"]
HTTP_FINGERPRINT: ClassVar[list[FingerprintRule]] = [
# The login page title reads e.g.
# "HPE OfficeConnect Switch 1820 8G PoE+ (65W) J9982A".
FingerprintRule("officeconnect", weight=9.0, mandatory=True),
FingerprintRule("1820", weight=6.0),
FingerprintRule("1920s", weight=6.0),
FingerprintRule("hewlett packard enterprise", weight=3.0),
]
# sysDescr repeats the model string, e.g. "HPE OfficeConnect Switch 1820
# 8G PoE+ (65W) J9982A, PT.02.19, Linux 3.6.5-…, U-Boot 2012.10-…".
# Not mandatory: HTTP already carries the hard requirement, and a device
# reachable only over SNMP should still be able to score.
SNMP_FINGERPRINT: ClassVar[list[FingerprintRule]] = [
FingerprintRule("officeconnect", weight=9.0),
FingerprintRule("1820", weight=6.0),
FingerprintRule("1920s", weight=6.0),
]
# --- Web UI endpoints -------------------------------------------------
DASHBOARD = "/htdocs/pages/base/dashboard.lsp"
PORT_SUMMARY = "/htdocs/pages/base/port_summary.lsp"
PORT_STATS = "/htdocs/pages/base/port_summary_stats.lsp"
MAC_TABLE = "/htdocs/pages/base/mac_address_table.lsp"
VLAN_STATUS = "/htdocs/pages/switching/vlan_status.lsp"
VLAN_PER_PORT = "/htdocs/pages/switching/vlan_per_port.lsp?vlan={vlan}"
def __init__(
self,
hostname: str,
username: str,
password: str,
timeout: int = 60,
optional_args: dict | None = None,
) -> None:
self.hostname = hostname
self.username = username
self.password = password
self.timeout = timeout
optional_args = optional_args or {}
self._client = OfficeConnectClient(
hostname,
username,
password,
# HTTP by default: HTTPS only works once a certificate has been
# uploaded to the switch, which is not the common deployment.
scheme=optional_args.get("scheme", "http"),
port=optional_args.get("port"),
timeout=timeout,
verify=optional_args.get("ssl_verify", False),
)
# ------------------------------------------------------------------
# Connection management
# ------------------------------------------------------------------
def open(self) -> None:
self._client.login()
def close(self) -> None:
# Always release the session: the switch keeps a small session table
# and only reclaims entries on idle timeout.
self._client.logout()
def is_alive(self) -> dict[str, bool]:
return {"is_alive": bool(self._client.is_authenticated)}
# ------------------------------------------------------------------
# Internal helpers
# ------------------------------------------------------------------
def _rows(self, path: str) -> list[list[str]]:
"""Fetch a page and return its table rows as plain text cells."""
page = self._client.fetch(path)
return [
[parsers.strip_markup(cell) for cell in row] for row in parsers.extract_data_set(page)
]
@staticmethod
def _speed_mbit(value: str) -> float:
"""``"100 Mbps Full Duplex"`` → ``100.0``; empty (link down) → ``0.0``."""
match = _SPEED_RE.search(value or "")
return float(match.group(1)) if match else 0.0
# ------------------------------------------------------------------
# Getters
# ------------------------------------------------------------------
def get_facts(self) -> dict[str, Any]:
facts = parsers.parse_facts(self._client.fetch(self.DASHBOARD))
hostname = facts["hostname"]
return {
"uptime": facts["uptime"],
"vendor": self.VENDOR,
"os_version": facts["os_version"],
"serial_number": facts["serial_number"],
"model": facts["model"],
"hostname": hostname,
"fqdn": hostname,
"interface_list": [row[1] for row in self._rows(self.PORT_SUMMARY)],
}
def get_interfaces(self) -> dict[str, dict[str, Any]]:
"""Physical ports and trunk interfaces.
Columns: [checkbox, Interface, Port Description, Admin Mode,
Physical Type, Port Status, Physical Mode, Link Speed, MTU]
"""
interfaces: dict[str, dict[str, Any]] = {}
for row in self._rows(self.PORT_SUMMARY):
interfaces[row[1]] = {
"is_up": row[5] == "Link Up",
"is_enabled": row[3] == "Enabled",
"description": row[2],
# The web UI reports neither flap time nor a per-port MAC.
"last_flapped": -1.0,
"speed": self._speed_mbit(row[7]),
"mtu": int(row[8]) if row[8].isdigit() else 0,
"mac_address": "",
}
return interfaces
def get_interfaces_counters(self) -> dict[str, dict[str, int]]:
"""Not available on this platform.
``port_summary_stats.lsp`` declares the expected 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 this raises instead.
"""
raise NotImplementedError(
"OfficeConnect firmware PT.02.19 does not expose interface counters"
)
def _vlan_participation(self) -> dict[str, dict[str, Any]]:
"""VLAN table joined with per-VLAN interface participation.
The participation page renders one VLAN at a time, so this costs one
request per VLAN on top of the VLAN list itself.
"""
result: dict[str, dict[str, Any]] = {}
for row in self._rows(self.VLAN_STATUS):
vlan_id, name = row[1], row[2]
tagged: list[str] = []
untagged: list[str] = []
for member in self._rows(self.VLAN_PER_PORT.format(vlan=vlan_id)):
interface, state = member[1], member[2].lower()
if state == "tagged":
tagged.append(interface)
elif state == "untagged":
untagged.append(interface)
result[vlan_id] = {"name": name, "tagged": tagged, "untagged": untagged}
return result
def get_vlans(self) -> dict[str, dict[str, Any]]:
return {
vlan_id: {
"name": data["name"],
"interfaces": sorted(
data["untagged"] + data["tagged"],
key=lambda i: (i.startswith("TRK"), i),
),
}
for vlan_id, data in self._vlan_participation().items()
}
def get_vlans_detail(self) -> dict[str, dict[str, Any]]:
"""Like :meth:`get_vlans` but keeping tagged and untagged apart."""
return self._vlan_participation()
def get_mac_address_table(self) -> list[dict[str, Any]]:
"""Columns: [VLAN ID, MAC Address, Interface, Interface Index, Status]."""
table = []
for row in self._rows(self.MAC_TABLE):
status = row[4].lower()
table.append(
{
"mac": row[1],
"interface": row[2],
"vlan": int(row[0]) if row[0].isdigit() else 0,
"static": status in ("static", "management"),
"active": True,
"moves": -1,
"last_move": -1.0,
}
)
return table
+147
View File
@@ -0,0 +1,147 @@
"""Parsers for the HPE OfficeConnect web UI.
These switches have no CLI and no REST API — the only machine-readable
surface is the web UI itself. Every list page (ports, VLANs, MAC table,
trunks, counters) is a jQuery DataTable whose payload is embedded in the
page as two JavaScript declarations::
var aDataSet = [
['<input type="checkbox" ...>', '1', '', 'Enabled', ..., '1518']
,
['<input type="checkbox" ...>', '2', '', 'Enabled', ..., '1518']
];
var aColumns = [
{ "sTitle": "Interface", "sType": "intf-sort", "sWidth": "8%" },
...
];
The array literal happens to be valid Python syntax, so it parses with
``ast.literal_eval`` — no HTML parser and no extra dependency needed.
Note that this is a property of firmware PT.02.xx and later. Older 1820
firmware server-rendered the same data as ``<tr>``/``<td>`` markup, which
is why the (unmaintained) hp1820-cli scraper does not work here.
"""
from __future__ import annotations
import ast
import html as html_module
import re
_DATASET_RE = re.compile(r"var\s+aDataSet\s*=\s*\[(.*?)\n\s*\];", re.DOTALL)
_STITLE_RE = re.compile(r"\"sTitle\"\s*:\s*(['\"])(.*?)\1", re.DOTALL)
_TAG_RE = re.compile(r"<[^>]*>")
_UPTIME_RE = re.compile(
r"(\d+)\s*days?,\s*(\d+)\s*hours?,\s*(\d+)\s*mins?,\s*(\d+)\s*secs?",
re.IGNORECASE,
)
def strip_markup(value: str) -> str:
"""Reduce a DataTable cell to its plain text.
The leading column of most tables is a row-selection checkbox whose
"value" is an ``<input>`` element; it collapses to an empty string.
"""
text = _TAG_RE.sub("", value)
text = html_module.unescape(text)
return re.sub(r"\s+", " ", text).strip()
def extract_data_set(page: str) -> list[list[str]]:
"""Return the rows of the page's ``aDataSet`` as lists of raw cell strings.
Cells are returned verbatim, markup included — callers decide per column
whether to run them through :func:`strip_markup`. Returns an empty list
if the page carries no table (e.g. an error or login-redirect page).
"""
match = _DATASET_RE.search(page)
if not match:
return []
body = match.group(1)
# Fast path: the whole literal at once.
try:
rows = ast.literal_eval("[" + body + "]")
except (SyntaxError, ValueError):
# Fall back to row-at-a-time so a single malformed row — an escape
# sequence that is valid in JS but not in Python, say — costs us that
# row rather than the entire table.
rows = []
for line in body.splitlines():
line = line.strip().rstrip(",")
if not line.startswith("["):
continue
try:
rows.append(ast.literal_eval(line))
except (SyntaxError, ValueError):
continue
return [[str(cell) for cell in row] for row in rows if isinstance(row, (list, tuple))]
def extract_column_titles(page: str) -> list[str]:
"""Return the text column titles declared in ``aColumns``.
Purely informational columns whose title is markup rather than text —
the select-all checkbox — are dropped, so the result lines up with the
data columns a caller actually reads.
"""
titles = [strip_markup(m.group(2)) for m in _STITLE_RE.finditer(page)]
return [t for t in titles if t]
def parse_uptime(value: str) -> int:
"""Convert ``"0 days, 18 hours, 44 mins, 40 secs"`` to seconds.
Returns -1 when the string cannot be parsed, which is NAPALM's
convention for an unknown uptime.
"""
match = _UPTIME_RE.search(value or "")
if not match:
return -1
days, hours, mins, secs = (int(g) for g in match.groups())
return days * 86400 + hours * 3600 + mins * 60 + secs
def _text_by_id(page: str, element_id: str) -> str:
"""Text content of the ``<td id="...">`` carrying a dashboard value."""
match = re.search(rf'id="{re.escape(element_id)}"[^>]*>(.*?)</', page, re.DOTALL)
return strip_markup(match.group(1)) if match else ""
def _input_value_by_id(page: str, element_id: str) -> str:
"""Value of the ``<input id="...">`` carrying an editable dashboard field.
The attribute often wraps across lines, hence the DOTALL search.
"""
match = re.search(rf'id="{re.escape(element_id)}"[^>]*?value="([^"]*)"', page, re.DOTALL)
return html_module.unescape(match.group(1)).strip() if match else ""
def parse_facts(page: str) -> dict[str, object]:
"""Extract system facts from ``dashboard.lsp``.
The System Description is a comma-separated tuple of model, firmware,
kernel and bootloader::
HPE OfficeConnect Switch 1820 8G PoE+ (65W) J9982A, PT.02.19,
Linux 3.6.5, U-Boot 2012.10-00116 (Jul 30 2014 - 10:52:01)
"""
descr = _text_by_id(page, "sys_descr")
parts = [p.strip() for p in descr.split(",")] if descr else []
model = parts[0] if parts else ""
os_version = _text_by_id(page, "sw_version") or (parts[1] if len(parts) > 1 else "")
return {
"hostname": _input_value_by_id(page, "sys_name"),
"model": model,
"serial_number": _text_by_id(page, "serial_number"),
"os_version": os_version,
"sys_object_id": _text_by_id(page, "sys_obj_id"),
"uptime": parse_uptime(_text_by_id(page, "sys_up_time")),
"system_description": descr,
}
+56
View File
@@ -0,0 +1,56 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "napalm-hpe-officeconnect"
version = "0.1.0"
description = "NAPALM driver for HPE OfficeConnect 1820 / 1920S web-managed switches (HTTP only, no CLI)"
readme = "README.md"
license = { text = "Apache-2.0" }
requires-python = ">=3.8"
authors = [
{ name = "Christian Manivong" },
]
classifiers = [
"Topic :: Utilities",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Operating System :: POSIX :: Linux",
"Operating System :: MacOS",
]
# No netmiko/paramiko: these switches have no CLI at all.
# No BeautifulSoup: the web UI ships its table data as JS array literals,
# which parse with ast.literal_eval — see parsers.extract_data_set.
dependencies = [
"napalm>=4.0.0",
"requests>=2.25.0",
"urllib3",
]
[project.optional-dependencies]
dev = [
"pytest",
"pytest-cov",
"black",
"ruff",
]
[project.entry-points."napalm.drivers"]
hpe_officeconnect = "napalm_hpe_officeconnect:OfficeConnectDriver"
[project.urls]
Repository = "https://git.netork.io/NAPALM/napalm-hpe-officeconnect"
[tool.setuptools.packages.find]
where = ["."]
include = ["napalm_hpe_officeconnect*"]
[tool.ruff]
line-length = 100
target-version = "py38"
View File
+397
View File
@@ -0,0 +1,397 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright &copy; 2017-2022 Hewlett Packard Enterprise Development LP. -->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Dashboard</title>
<link rel="shortcut icon" href="/htdocs/login/favicon.ico?">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/jquery-ui-1.12.1.custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/css/jquery.dataTables_themeroller.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_datatables_custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_common_pages.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/tabs.css">
<!--[if ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7.css" type="text/css">
<![endif]-->
<!--[if gte ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7plus.css" type="text/css">
<![endif]-->
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_3_5_1/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_ui_1_12_1/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables.min.js"></script>
</head>
<body class="ui-state-default fp_jqtds_page_body fp_corner_bottom">
<a name="focus_top" id="focus_top"></a>
<div id="fp_div_page_title_bar" class="fp_jqtds_h1">
<div id="fp_div_page_title_text">Dashboard</div>&nbsp;
<div id="fp_div_title_bar_tooltip">
<a class="fp_anchor_tooltip" href="/htdocs/lang/en_us/help/base/help_dashboard.lsp" target="_blank">
<img src="/htdocs/static/bt1707389424/images/icon_help_black24-helpText.png" title="Help" alt="Help" border="0">
</a>
</div><!-- fp_div_title_bar_tooltip -->
</div><!-- fp_div_page_title_bar -->
<div class="fp_page_container">
<form id="form1" name="form1" method="post" action="/htdocs/pages/base/dashboard.lsp">
<div class="fp_sub_container">
<table class="fp_page_table_class" id="table_1" cellpadding="0" cellspacing="0" >
<tbody>
<!-- System Information -->
<tr>
<td colspan="3"><div class="fp_jqtds_h2 fp_sub_title fp_sub_title_first">System Information</div></td>
</tr>
<tr> <!-- System Description -->
<td class="ui-widget-content fp_data_label_25w">System Description</td>
<td class="ui-widget-content fp_data_value" id="sys_descr">HPE OfficeConnect Switch 1820 8G PoE+ (65W) J9982A, PT.02.19, Linux 3.6.5, U-Boot 2012.10-00116 (Jul 30 2014 - 10:52:01)</td>
</tr>
<tr> <!-- System Name -->
<td class="ui-widget-content fp_data_label_25w">System Name</td>
<td class="ui-widget-content fp_data_value">
<input class="fp_inputfield" type="text" id="sys_name" name="sys_name" size="20" maxlength="64"
value="testswitch">&nbsp;&nbsp;(0 to 64 characters)</td>
</tr>
<tr> <!-- System Location -->
<td class="ui-widget-content fp_data_label_25w">System Location</td>
<td class="ui-widget-content fp_data_value"><input class="fp_inputfield" type="text" id="sys_location" name="sys_location" size="20" maxlength="255"
value="Testlab">&nbsp;&nbsp;(0 to 255 characters)</td>
</tr>
<tr> <!-- System Contact -->
<td class="ui-widget-content fp_data_label_25w">System Contact</td>
<td class="ui-widget-content fp_data_value">
<input class="fp_inputfield" type="text" id="sys_contact" name="sys_contact" size="20" maxlength="255"
value="netork">&nbsp;&nbsp;(0 to 255 characters)</td>
</tr>
<tr> <!-- System Object ID -->
<td class="ui-widget-content fp_data_label_25w">System Object ID</td>
<td class="ui-widget-content fp_data_value" id="sys_obj_id">1.3.6.1.4.1.11.2.3.7.11.170</td>
</tr>
<tr> <!-- System Up Time -->
<td class="ui-widget-content fp_data_label_25w">System Up Time</td>
<td class="ui-widget-content fp_data_value" id="sys_up_time">0 days, 18 hours, 44 mins, 40 secs</td>
</tr>
<tr> <!-- Current Time -->
<td class="ui-widget-content fp_data_label_25w">Current Time</td>
<td class="ui-widget-content fp_data_value" id="curr_time">
19:44:40</td>
</tr>
<tr> <!-- Date -->
<td class="ui-widget-content fp_data_label_25w">Date</td>
<td class="ui-widget-content fp_data_value" id="curr_date">
January 01, 1970</td>
</tr>
</tbody>
</table>
</div> <!-- fp_sub_container -->
<div class="fp_sub_container">
<table class="fp_page_table_class" id="table_2" cellpadding="0" cellspacing="0" >
<tbody>
<!-- Device Information -->
<tr>
<td colspan="3"><div class="fp_jqtds_h2 fp_sub_title">Device Information</div></td>
</tr>
<tr> <!-- Software Version -->
<td class="ui-widget-content fp_data_label_25w">Software Version</td>
<td class="ui-widget-content fp_data_value" id="sw_version" colspan="2">PT.02.19</td>
</tr>
<tr> <!-- Operating System -->
<td class="ui-widget-content fp_data_label_25w">Operating System</td>
<td class="ui-widget-content fp_data_value" id="operating_sys" colspan="2">Linux 3.6.5</td>
</tr>
<tr> <!-- Serial Number -->
<td class="ui-widget-content fp_data_label_25w">Serial Number</td>
<td class="ui-widget-content fp_data_value" id="serial_number" colspan="2">CN0FIXTURE0</td>
</tr>
</tbody>
</table>
</div> <!-- fp_sub_container -->
<div class="fp_sub_container">
<table class="fp_page_table_class" id="table_3" cellpadding="0" cellspacing="0" >
<tbody>
<!-- System Resource Usage -->
<tr>
<td colspan="3"><div class="fp_jqtds_h2 fp_sub_title">System Resource Usage</div></td>
</tr>
<tr> <!-- CPU Utilization (60 Second Average) -->
<td class="ui-widget-content fp_data_label">CPU Utilization (60 Second Average)</td>
<td class="ui-widget-content fp_data_value" id="cpu_util">
<div class="fp_progressbar" id="cpu_util_prog_bar"></div>
<div class="ui-widget-content fp_progressbar_val" id="cpu_util_prog_bar_val">14 %</div>
</td>
</tr>
<tr> <!-- Memory Usage -->
<td class="ui-widget-content fp_data_label">Memory Usage</td>
<td class="ui-widget-content fp_data_value" id="mem_util">
<div class="fp_progressbar" id="mem_util_prog_bar"></div>
<div class="ui-widget-content fp_progressbar_val" id="mem_util_prog_bar_val">36 %</div>
</td>
</tr>
<!-- Logged in Users -->
<tr>
<td colspan="3"><div class="fp_jqtds_h2 fp_sub_title">Logged In Users</div></td>
</tr>
<tr>
<td colspan="3">
<div id="dynamic_dt1"></div>
</td>
</tr>
</tbody>
</table>
</div> <!-- fp_sub_container -->
<div id="page_buttons" class="fp_button_row">
<input class="fp_button ui-button ui-widget ui-state-default" type="submit" id="b_form1_submit" name="b_form1_submit" value="Apply" onclick="jslib_b_pressed_g='submit';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default" type="submit" id="b_form1_refresh" name="b_form1_refresh" value="Refresh" onclick="jslib_b_pressed_g='refresh';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default" type="reset" id="b_form1_cancel" name="b_form1_cancel" value="Cancel" onclick="jslib_b_pressed_g='cancel';">
</div> <!-- fp_button_row -->
</form> <!-- form1 -->
</div><!-- fp_page_container -->
<script type="text/javascript" language="JavaScript">
<!--
var jslib_msgs = parent.jslib_msgs_tbl;
-->
</script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/js/web-utils-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/plugins/jquery-plugins-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables-plugins.js"></script>
<script type="text/javascript" src="/htdocs/lang/en_us/culture/globalize.culture.en-US.20120606.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_ui_1_12_1/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
var aDataSet = [
['admin', '192.0.2.100', '00:03:51', '00:05:05']
,
['admin', '192.0.2.100', '00:00:00', '00:00:16']
];
var aColumns = [
{ "sTitle": "Username", "sType": "intf-sort", "sWidth": "10%" },
{ "sTitle": "Connection From", "sType": "html", "sWidth": "10%" },
{ "sTitle": "Idle Time", "sType": "html", "sWidth": "10%" },
{ "sTitle": "Session Time", "sType": "html", "sWidth": "10%" }
];
// Construct property objects for each input field in the form
var prop =
{
sys_location: new FieldProp({ defval: "", dname: "System Location", formfield: "sys_location", max: 255, min: 0, optional: true, regex: /^[ -~]+$/, type: 2 }),
sys_name: new FieldProp({ defval: "", dname: "System Name", formfield: "sys_name", max: 64, min: 0, optional: true, regex: /^[ -~]+$/, type: 2 }),
sys_contact: new FieldProp({ defval: "", dname: "System Contact", formfield: "sys_contact", max: 255, min: 0, optional: true, regex: /^[ -~]+$/, type: 2 })
};
jslib_form_validation_bind($('#form1')[0], prop);
prop.sys_contact.uservalidate = function(field)
{
// This is a simple example of doing user validation. In actuality,
// it does not do anything (just passes through the value.)
var re = /^./ ;
if (field.value.length > 0 && !re.test(field.value))
{
return { errmsg: jsmsg.invalid_chars };
} else {
return null;
}
}
$(function()
{
$("div .fp_progressbar").each(function()
{
var sel = "#" + this.id;
var val = elem_get(this.id + "_val").innerHTML;
$(sel).progressbar({ value: val });
$(sel).css({ "background": "#eeeeee" });
$(sel + " > div").css({ "background": "green" });
});
});
function progress_bar_update(id, val, lev1, lev2)
{
var barcolor = "#00b388";
if (lev1 != null)
{
////lev1 = 101; lev2 = 0;
// lev1 designates a two-color scheme
barcolor = (val < lev1) ? "green" : "red";
if ((lev2 != null) && (lev1 < lev2) && (val >= lev1))
{
// lev1 and lev2 designates a three-color scheme
// (note: if specified, lev2 must be greater than lev1)
barcolor = (val < lev2) ? "yellow" : "red";
}
}
$(id).progressbar("option", "value", val);
$(id + " > div").css({ "background": barcolor });
}
// define form field(s) to be updated through Ajax using the specified script file
// - script must produce results in same order as those listed in the fields array
$(document).ready(function()
{
$('#dynamic_dt1').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="sorttable1"><\/table>' );
fp_dt_create("#sorttable1", { aaData: aDataSet, aoColumns: aColumns });
$("#sorttable1").width("100%");
progress_bar_update("#cpu_util_prog_bar", 14);
progress_bar_update("#mem_util_prog_bar", 36);
var fn = setInterval(function()
{
$.ajax(
{
url: "/htdocs/lua/ajax/dashboard_ajax.lua",
success: function(val)
{
var res = val.split("|");
if (res != null)
{
elem_get("sys_up_time").innerHTML = res[0];
var cpu_util = Number(res[1]);
elem_get("cpu_util_prog_bar_val").innerHTML = cpu_util + " %";
progress_bar_update("#cpu_util_prog_bar", cpu_util);
var mem_util = Number(res[2]);
elem_get("mem_util_prog_bar_val").innerHTML = mem_util + " %";
progress_bar_update("#mem_util_prog_bar", mem_util);
elem_get("curr_time").innerHTML = res[3];
elem_get("curr_date").innerHTML = res[4];
}
}
});
}, 60000);
});
-->
</script>
<script type="text/javascript" language="JavaScript">
<!--
$(document).ready( function()
{
var page_is_valid = true;
// format all culture-specific elements using the current locale
culture_format(parent.culture);
var myNav = navigator.userAgent.toLowerCase();
var isIe = false;
if (myNav.indexOf('msie') != -1)
{
var myVer = parseInt(myNav.split('msie')[1]);
}
if ((isIe == true) && (myVer < 8)) {
$('input[type=radio],[type=checkbox]').live('click', function () {
this.blur();
this.focus();
});
}
$(':input').bind('keypress', function(e) {
var key = (window.event) ? window.event.keyCode : e.which; // IE vs. FF
var $this = $(this);
if ( ($this.is(':not(:button, :submit, :reset, textarea)')) ) {
return (key != 13);
}
});
$(".fp_button").button();
$(".fp_button_cancel").button();
$('form input[type="reset"]').click(function(e) {
if( $('#sorttable1').length ){
fp_dt_reset_handler("#sorttable1");
}
return jslib_form_reset(this.form);
});
$(":submit,:button").click(function(e) {
// remember which button was clicked last by storing into hidden field
var button = $(this).attr("id");
var form_id = $(e.target).closest("form").attr("id");
if (form_id)
{
$("#b_"+form_id+"_clicked").val(button);
}
page_is_valid = jslib_form_validate(document.forms[0], prop);
return page_is_valid;
});
// add a hidden field to each form to record which submit button
// was clicked so that it gets presented in the POST data
$("form").each(function() {
var $this = $(this);
var bid = "b_" + $this.attr("id") + "_clicked";
var b_clicked = '<input type="hidden" id="' + bid + '" name="' + bid + '">';
$(b_clicked).appendTo($this);
});
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
iframe_auto_resize();
});
iframe_auto_resize();
$('form input[type="submit"]').click(function(e) {
var form_id = $(e.target).closest("form").attr("id");
var f_s = "b_"+form_id+"_submit";
var f_r = "b_"+form_id+"_refresh";
var f_click = $("#b_"+form_id+"_clicked").val();
if (((f_click == f_s) || (f_click == f_r)) && page_is_valid)
{
parent.progress_modal_open();
}
});
parent.progress_modal_handler(parent.ple.PAGE_LOADED);
check_error();
focus_init("");
});
-->
</script>
</body>
</html>
+226
View File
@@ -0,0 +1,226 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright &copy; 2017-2022 Hewlett Packard Enterprise Development LP. -->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>MAC Table</title>
<link rel="shortcut icon" href="/htdocs/login/favicon.ico?">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/jquery-ui-1.12.1.custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/css/jquery.dataTables_themeroller.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_datatables_custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_common_pages.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/tabs.css">
<!--[if ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7.css" type="text/css">
<![endif]-->
<!--[if gte ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7plus.css" type="text/css">
<![endif]-->
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_3_5_1/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_ui_1_12_1/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables.min.js"></script>
</head>
<body class="ui-state-default fp_jqtds_page_body fp_corner_bottom">
<a name="focus_top" id="focus_top"></a>
<div id="fp_div_page_title_bar" class="fp_jqtds_h1">
<div id="fp_div_page_title_text">MAC Table</div>&nbsp;
<div id="fp_div_title_bar_tooltip">
<a class="fp_anchor_tooltip" href="/htdocs/lang/en_us/help/base/help_mac_address_table.lsp" target="_blank">
<img src="/htdocs/static/bt1707389424/images/icon_help_black24-helpText.png" title="Help" alt="Help" border="0">
</a>
</div><!-- fp_div_title_bar_tooltip -->
</div><!-- fp_div_page_title_bar -->
<div class="fp_page_container">
<form id="form1" name="form1" method="post" action="/htdocs/pages/base/mac_address_table.lsp">
<div class="fp_sub_container">
<table id="fp_page_table_content" cellpadding="0" cellspacing="0">
<tbody>
<tr> <!-- Max Entries supported -->
<td class="ui-widget-content fp_data_label">Maximum Entries Supported</td>
<td class="ui-widget-content fp_data_value">8000</td>
</tr>
</tbody>
</table>
</div> <!-- fp_sub_container -->
<hr class="first"></hr>
<div class="fp_sub_container">
<div id="dynamic_dt1"></div>
</div> <!-- fp_sub_container -->
<div id="page_buttons" class="fp_button_row">
<input class="fp_button ui-button ui-widget ui-state-default fp_primary_button" type="submit" id="b_form1_refresh" name="b_form1_refresh" value="Refresh" onclick="jslib_b_pressed_g='refresh';">
</div> <!-- fp_button_row -->
</form> <!-- form1 -->
</div><!-- fp_page_container -->
<script type="text/javascript" language="JavaScript">
<!--
var jslib_msgs = parent.jslib_msgs_tbl;
-->
</script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/js/web-utils-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/plugins/jquery-plugins-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables-plugins.js"></script>
<script type="text/javascript" src="/htdocs/lang/en_us/culture/globalize.culture.en-US.20120606.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
var aDataSet = [
['1', '00:11:22:33:44:01', '7', '7', 'Learned']
,
['10', '00:11:22:33:44:02', '4', '4', 'Learned']
,
['10', '00:11:22:33:44:03', '3', '3', 'Learned']
,
['10', '00:11:22:33:44:04', '8', '8', 'Learned']
,
['10', '00:11:22:33:44:05', 'CPU', '53', 'Management']
,
['10', '00:11:22:33:44:06', '8', '8', 'Learned']
,
['30', '00:11:22:33:44:07', '3', '3', 'Learned']
,
['30', '00:11:22:33:44:08', '4', '4', 'Learned']
,
['30', '00:11:22:33:44:09', '7', '7', 'Learned']
,
['50', '00:11:22:33:44:0A', '3', '3', 'Learned']
,
['50', '00:11:22:33:44:0B', '3', '3', 'Learned']
,
['50', '00:11:22:33:44:0C', '3', '3', 'Learned']
,
['50', '00:11:22:33:44:0D', '3', '3', 'Learned']
,
['50', '00:11:22:33:44:0E', '3', '3', 'Learned']
,
['50', '00:11:22:33:44:0F', '3', '3', 'Learned']
,
['50', '00:11:22:33:44:10', '6', '6', 'Learned']
,
['50', '00:11:22:33:44:09', '7', '7', 'Learned']
];
var aColumns = [
{ "sTitle": "VLAN ID", "sType": "natural-sort" },
{ "sTitle": "MAC Address" },
{ "sTitle": "Interface", "sType": "natural-sort" },
{ "sTitle": "Interface Index", "sType": "natural-sort" },
{ "sTitle": "Status" }
];
$(document).ready(function()
{
// table pagination and sorting
$('#dynamic_dt1').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="sorttable1"><\/table>' );
fp_dt_create("#sorttable1", { aaData: aDataSet, aoColumns: aColumns });
});
-->
</script>
<script type="text/javascript" language="JavaScript">
<!--
$(document).ready( function()
{
var page_is_valid = true;
// format all culture-specific elements using the current locale
culture_format(parent.culture);
var myNav = navigator.userAgent.toLowerCase();
var isIe = false;
if (myNav.indexOf('msie') != -1)
{
var myVer = parseInt(myNav.split('msie')[1]);
}
if ((isIe == true) && (myVer < 8)) {
$('input[type=radio],[type=checkbox]').live('click', function () {
this.blur();
this.focus();
});
}
$(':input').bind('keypress', function(e) {
var key = (window.event) ? window.event.keyCode : e.which; // IE vs. FF
var $this = $(this);
if ( ($this.is(':not(:button, :submit, :reset, textarea)')) ) {
return (key != 13);
}
});
$(".fp_button").button();
$(".fp_button_cancel").button();
$('form input[type="reset"]').click(function(e) {
if( $('#sorttable1').length ){
fp_dt_reset_handler("#sorttable1");
}
return jslib_form_reset(this.form);
});
$(":submit,:button").click(function(e) {
// remember which button was clicked last by storing into hidden field
var button = $(this).attr("id");
var form_id = $(e.target).closest("form").attr("id");
if (form_id)
{
$("#b_"+form_id+"_clicked").val(button);
}
page_is_valid = jslib_form_validate(document.forms[0]);
return page_is_valid;
});
// add a hidden field to each form to record which submit button
// was clicked so that it gets presented in the POST data
$("form").each(function() {
var $this = $(this);
var bid = "b_" + $this.attr("id") + "_clicked";
var b_clicked = '<input type="hidden" id="' + bid + '" name="' + bid + '">';
$(b_clicked).appendTo($this);
});
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
iframe_auto_resize();
});
iframe_auto_resize();
$('form input[type="submit"]').click(function(e) {
var form_id = $(e.target).closest("form").attr("id");
var f_s = "b_"+form_id+"_submit";
var f_r = "b_"+form_id+"_refresh";
var f_click = $("#b_"+form_id+"_clicked").val();
if (((f_click == f_s) || (f_click == f_r)) && page_is_valid)
{
parent.progress_modal_open();
}
});
parent.progress_modal_handler(parent.ple.PAGE_LOADED);
focus_init("focus_top");
});
-->
</script>
</body>
</html>
+531
View File
@@ -0,0 +1,531 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright &copy; 2017-2022 Hewlett Packard Enterprise Development LP. -->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Get Connected</title>
<link rel="shortcut icon" href="/htdocs/login/favicon.ico?">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/jquery-ui-1.12.1.custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/css/jquery.dataTables_themeroller.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_datatables_custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_common_pages.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/tabs.css">
<!--[if ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7.css" type="text/css">
<![endif]-->
<!--[if gte ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7plus.css" type="text/css">
<![endif]-->
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_3_5_1/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_ui_1_12_1/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables.min.js"></script>
</head>
<body class="ui-state-default fp_jqtds_page_body fp_corner_bottom">
<a name="focus_top" id="focus_top"></a>
<div id="fp_div_page_title_bar" class="fp_jqtds_h1">
<div id="fp_div_page_title_text">Get Connected</div>&nbsp;
<div id="fp_div_title_bar_tooltip">
<a class="fp_anchor_tooltip" href="/htdocs/lang/en_us/help/base/help_network_ipv4_cfg.lsp" target="_blank">
<img src="/htdocs/static/bt1707389424/images/icon_help_black24-helpText.png" title="Help" alt="Help" border="0">
</a>
</div><!-- fp_div_title_bar_tooltip -->
</div><!-- fp_div_page_title_bar -->
<div class="fp_page_container">
<form id="form1" name="form1" method="post" action="/htdocs/pages/base/network_ipv4_cfg.lsp">
<div class="fp_sub_container">
<table class="fp_page_table_class" id="table_1" cellpadding="0" cellspacing="0" >
<tbody>
<!-- Network Details -->
<tr>
<td colspan="3"><div class="fp_jqtds_h2 fp_sub_title fp_sub_title_first">Network Details</div></td>
</tr>
<tr> <!-- Protocol Type -->
<td class="ui-widget-content fp_data_label">Protocol Type</td>
<td class="ui-widget-content fp_data_value" id="protocol_type">
<input type="radio" name="protocol_type_sel[]" id="protocol_type_sel_static" value="static" checked="checked" class="fp_inputfield" onchange="net_config_change(this);">
<label for="protocol_type_sel_static">Static&nbsp;&nbsp;</label>
<input type="radio" name="protocol_type_sel[]" id="protocol_type_sel_dhcp" value="dhcp" class="fp_inputfield" onchange="net_config_change(this);">
<label for="protocol_type_sel_dhcp">DHCP&nbsp;&nbsp;</label>
<button title="Refresh DHCP Lease" id="b_form1_refresh_dhcp" class="fp_button_icon ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only" type="submit" onclick="jslib_b_pressed_g='refresh_dhcp';">&nbsp;</button>
</td>
</tr>
<tr> <!-- IP Address -->
<td class="ui-widget-content fp_data_label">IP Address</td>
<td class="ui-widget-content fp_data_value">
<input class="fp_inputfield" type="text" id="ip_addr" name="ip_addr" size="15" maxlength="15"
value="192.0.2.20">&nbsp;&nbsp;(x.x.x.x)</td>
</tr>
<tr> <!-- Subnet Mask -->
<td class="ui-widget-content fp_data_label">Subnet Mask</td>
<td class="ui-widget-content fp_data_value">
<input class="fp_inputfield" type="text" id="subnet_mask" name="subnet_mask" size="15" maxlength="15"
value="255.255.255.0">&nbsp;&nbsp;(x.x.x.x)</td>
</tr>
<tr> <!-- Gateway Address -->
<td class="ui-widget-content fp_data_label">Gateway Address</td>
<td class="ui-widget-content fp_data_value">
<input class="fp_inputfield" type="text" id="gateway_address" name="gateway_address" size="15" maxlength="15"
value="192.0.2.1">&nbsp;&nbsp;(x.x.x.x)</td>
</tr>
<tr> <!-- MAC Address -->
<td class="ui-widget-content fp_data_label">MAC Address</td>
<td class="ui-widget-content fp_data_value" id="mac_address">00:11:22:33:44:05</td>
</tr>
</tbody>
</table>
</div> <!-- fp_sub_container -->
<div class="fp_sub_container">
<table class="fp_page_table_class" id="table_2" cellpadding="0" cellspacing="0" >
<tbody>
<!-- Web Parameters -->
<tr>
<td colspan="3"><div class="fp_jqtds_h2 fp_sub_title">Web Parameters</div></td>
</tr>
<tr> <!-- Session Timeout -->
<td class="ui-widget-content fp_data_label">Session Timeout&nbsp;&nbsp;(Minutes)</td>
<td class="ui-widget-content fp_data_value">
<input class="fp_inputfield" type="text" id="session_timeout" name="session_timeout" size="15" maxlength="2"
value="5">&nbsp;&nbsp;(1 to 60)</td>
</tr>
</tbody>
</table>
</div> <!-- fp_sub_container -->
<div class="fp_sub_container">
<table class="fp_page_table_class" id="table_3" cellpadding="0" cellspacing="0" >
<tbody>
<!-- Management Access -->
<tr>
<td colspan="3"><div class="fp_jqtds_h2 fp_sub_title">Management Access</div></td>
</tr>
<tr> <!-- Management VLAN ID -->
<td class="ui-widget-content fp_data_label">Management VLAN ID</td>
<td class="ui-widget-content fp_data_value" id="mvlan">
<select name="mgmt_vlan_id_sel[]" id="mgmt_vlan_id_sel">
<option id="mgmt_vlan_id_sel_1" value="1">1</option>
<option id="mgmt_vlan_id_sel_10" value="10" selected="selected">10</option>
<option id="mgmt_vlan_id_sel_20" value="20">20</option>
<option id="mgmt_vlan_id_sel_30" value="30">30</option>
<option id="mgmt_vlan_id_sel_40" value="40">40</option>
<option id="mgmt_vlan_id_sel_50" value="50">50</option>
<option id="mgmt_vlan_id_sel_60" value="60">60</option>
</select>
</td>
</tr>
<tr> <!-- Management Port -->
<td class="ui-widget-content fp_data_label">Management Port</td>
<td class="ui-widget-content fp_data_value" id="mport">
<select name="mgmt_port_sel[]" id="mgmt_port_sel">
<option id="mgmt_port_sel_none" value="none" selected="selected">None</option>
<option id="mgmt_port_sel_2" value="2">2</option>
<option id="mgmt_port_sel_3" value="3">3</option>
<option id="mgmt_port_sel_4" value="4">4</option>
<option id="mgmt_port_sel_8" value="8">8</option>
</select>
</td>
</tr>
</tbody>
</table>
</div> <!-- fp_sub_container -->
<div class="fp_sub_container">
<table class="fp_page_table_class" id="table_4" cellpadding="0" cellspacing="0" >
<tbody>
<!-- SNMP -->
<tr>
<td colspan="3"><div class="fp_jqtds_h2 fp_sub_title">SNMP</div></td>
</tr>
<tr> <!-- SNMP -->
<td class="ui-widget-content fp_data_label">SNMP</td>
<td class="ui-widget-content fp_data_value">
<input type="radio" name="snmp_sel[]" id="snmp_sel_enabled" value="enabled" checked="checked">
<label for="snmp_sel_enabled">Enabled&nbsp;&nbsp;</label>
<input type="radio" name="snmp_sel[]" id="snmp_sel_disabled" value="disabled">
<label for="snmp_sel_disabled">Disabled&nbsp;&nbsp;</label>
</td>
</tr>
<tr> <!-- Community Name -->
<td class="ui-widget-content fp_data_label">Community Name</td>
<td class="ui-widget-content fp_data_value">
<input class="fp_inputfield" type="text" id="community_name" name="community_name" size="15" maxlength="20"
value="public">&nbsp;&nbsp;(1 to 20 characters)</td>
</tr>
</tbody>
</table>
</div> <!-- fp_sub_container -->
<div id="page_buttons" class="fp_button_row">
<input class="fp_button ui-button ui-widget ui-state-default" type="submit" id="b_form1_submit" name="b_form1_submit" value="Apply" onclick="jslib_b_pressed_g='submit';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default" type="submit" id="b_form1_refresh" name="b_form1_refresh" value="Refresh" onclick="jslib_b_pressed_g='refresh';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default" type="reset" id="b_form1_cancel" name="b_form1_cancel" value="Cancel" onclick="jslib_b_pressed_g='cancel';">
</div> <!-- fp_button_row -->
<input type="hidden" id="change_mvlan" name="change_mvlan" value="no">
<input type="hidden" id="change_mport" name="change_mport" value="no">
</form> <!-- form1 -->
</div><!-- fp_page_container -->
<script type="text/javascript" language="JavaScript">
<!--
var jslib_msgs = parent.jslib_msgs_tbl;
-->
</script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/js/web-utils-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/plugins/jquery-plugins-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables-plugins.js"></script>
<script type="text/javascript" src="/htdocs/lang/en_us/culture/globalize.culture.en-US.20120606.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
var prop =
{
gateway_address: new FieldProp({ defval: "", dname: "Gateway Address", formfield: "gateway_address", max: 15, min: 7, optional: true, regex: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, type: 2 }),
ip_addr: new FieldProp({ defval: "", dname: "IP Address", formfield: "ip_addr", max: 15, min: 7, optional: true, regex: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, type: 2 }),
community_name: new FieldProp({ defval: "", dname: "Community Name", formfield: "community_name", max: 20, min: 1, regex: /^[ -~]+$/, type: 2 }),
session_timeout: new FieldProp({ defval: "5", dname: "Session Timeout", formfield: "session_timeout", max: 60, min: 1, regex: /^\d+$/, type: 3 }),
subnet_mask: new FieldProp({ defval: "", dname: "Subnet Mask", formfield: "subnet_mask", max: 15, min: 7, optional: true, regex: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, type: 2 })
};
jslib_form_validation_bind($('#form1').get(0), prop);
var errorMsg = "";
// individual form field validation function wrappers
// (used for onChange and onSubmit events)
//
function ip_cfg_validate(field)
{
var proto = $("#protocol_type :checked").val();
// Validate only for static
if(proto !== "static")
{
return true;
}
if (field.value.length > 0 && !ipv4_address_validate(field.value))
{
return { errmsg: "Improper address format" }
}
if (field.value.length === 0)
{
return true;
}
if(field.name == 'ip_addr'){
if(field.value == "255.255.255.255"){
return { errmsg: "Invalid address" }
}
if (errorMsg == "The IP address and subnet mask combination is not valid"){
return { errmsg: "Invalid address" }
}
}
if(field.name == 'subnet_mask'){
if (errorMsg == "The subnet mask is not valid"){
return { errmsg: "Invalid address" }
}
}
if(field.name == 'gateway_address'){
if (errorMsg == "Gateway is not valid"){
return { errmsg: "Invalid address" }
}
}
return null;
}
prop.ip_addr.uservalidate = ip_cfg_validate;
prop.subnet_mask.uservalidate = ip_cfg_validate;
prop.gateway_address.uservalidate = ip_cfg_validate;
prop.community_name.uservalidate = function(field) {
if($('#snmp_sel_disabled').is(':checked'))
return true;
else
return null;
}
// Enable/disable network configuration entries: IP address, netmask and gateway
// It depends on the selected network configuration protocol {'static', 'dhcp'}
function net_conf_entries_update(net_cfg_proto)
{
if(net_cfg_proto !== "static")
{
// Show warning message for protocol change
alert("Changing protocol mode will reset IP configuration!");
}
if (net_cfg_proto === "static")
{
$("#ip_addr, #subnet_mask, #gateway_address").prop("disabled", false);
$("#ip_addr").val("192.0.2.20");
$("#subnet_mask").val("255.255.255.0");
$("#gateway_address").val("192.0.2.1");
$("#b_form1_refresh_dhcp").button("disable");
}
else
{
$("#ip_addr, #subnet_mask, #gateway_address").prop("disabled", true);
$("#b_form1_refresh_dhcp").button("enable");
}
}
// Issues request to refresh DHCP
function dhcp_refresh()
{
$.get("/htdocs/lua/ajax/net_ipv4_dhcp_refresh_ajax.lua");
}
// Enable/disable DHCP refresh button
function dhcp_refresh_update(net_cfg_proto)
{
if (net_cfg_proto === "dhcp")
{
$("#b_form1_refresh_dhcp").button("enable");
}
else
{
$("#b_form1_refresh_dhcp").button("disable");
}
}
// select list onchange handlers (client-side)
function net_config_change(field)
{
net_conf_entries_update(field.value);
}
$("#mvlan").change(function() {
var val = confirm("You are changing the management VLAN. If the management VLAN is not set correctly you may lose network connection.");
if (val == false) {
$("#mgmt_vlan_id_sel_10").prop("selected", true);
$("#change_mvlan").val("yes");
}
else {
$("#change_mvlan").val("yes");
$("#b_form1_submit").trigger('click');
}
});
$("#mport").change(function() {
var val = confirm("You are changing the management port. If the management VLAN and port is not set correctly, you may lose network connection.");
if (val == false) {
$("#mgmt_port_sel_none").prop("selected", true);
$("#change_mport").val("no");
}
else {
$("#change_mport").val("yes");
}
});
$(document).ready( function ()
{
// Disable fields not related to DHCP
if(false)
{
$('#ip_addr').prop('disabled', true);
$('#subnet_mask').prop('disabled', true);
$('#gateway_address').prop('disabled', true);
}
else
{
errorMsg = "";
$('#ip_addr').change();
$('#subnet_mask').change();
$('#gateway_address').change();
errorMsg = "";
}
// Refresh DHCP Button Icon
$("#b_form1_refresh_dhcp")
.button({
icons: { primary: "ui-icon-refresh" },
text: false,
disabled: true
}).bind('click', dhcp_refresh);
// Update DHCP refresh button
dhcp_refresh_update($("#protocol_type :checked").val());
// popup message if managment port select as none
$( "#mgmt_port_sel" ).change(function() {
if($( "#mgmt_port_sel option:selected" ).val() == "none" && $( "#mgmt_vlan_id_sel option:selected" ).val() != 1){
var retVal = confirm("The management VLAN is not the default VLAN and you are changing the management port to None. If the management VLAN and port is not set correctly, you may lose network connection.");
if (retVal == false) {
$("#mgmt_port_sel_none").prop("selected", true);
}
}
});
$( "#b_form1_submit" ).click(function() {
if($( "#mgmt_port_sel option:selected" ).val() == "none" && $( "#mgmt_vlan_id_sel option:selected" ).val() != 1){
var retVal = confirm("The management VLAN is not the default VLAN and you are changing the management port to None. If the management VLAN and port is not set correctly, you may lose network connection.");
if (retVal == false) {
event.preventDefault();
return false;
}
}
});
// Add on reset handler
$("#form1").bind("reset", function() {
setTimeout(function() { // Need this delay so we read the reset values
net_conf_entries_update($("#protocol_type :checked").val());
}, 1);
});
// specific to SNMP package
if (false)
{
$('#community_name').val("");
$('#community_name').prop('disabled', true);
}
$("#snmp_sel_disabled, #snmp_sel_enabled").change(function() {
if ($(this).prop('id') === 'snmp_sel_disabled')
{
$('#community_name').val("");
$('#community_name').prop('disabled', true);
}
else
{
$('#community_name').prop('disabled', false);
var communityName = "public";
if (communityName == '')
{
communityName = "public";
}
$('#community_name').val(communityName);
}
});
$('#community_name').prop('disabled', false);
});
-->
</script>
<script type="text/javascript" language="JavaScript">
<!--
$(document).ready( function()
{
var page_is_valid = true;
// format all culture-specific elements using the current locale
culture_format(parent.culture);
var myNav = navigator.userAgent.toLowerCase();
var isIe = false;
if (myNav.indexOf('msie') != -1)
{
var myVer = parseInt(myNav.split('msie')[1]);
}
if ((isIe == true) && (myVer < 8)) {
$('input[type=radio],[type=checkbox]').live('click', function () {
this.blur();
this.focus();
});
}
$(':input').bind('keypress', function(e) {
var key = (window.event) ? window.event.keyCode : e.which; // IE vs. FF
var $this = $(this);
if ( ($this.is(':not(:button, :submit, :reset, textarea)')) ) {
return (key != 13);
}
});
$(".fp_button").button();
$(".fp_button_cancel").button();
$('form input[type="reset"]').click(function(e) {
if( $('#sorttable1').length ){
fp_dt_reset_handler("#sorttable1");
}
return jslib_form_reset(this.form);
});
$(":submit,:button").click(function(e) {
// remember which button was clicked last by storing into hidden field
var button = $(this).attr("id");
var form_id = $(e.target).closest("form").attr("id");
if (form_id)
{
$("#b_"+form_id+"_clicked").val(button);
}
page_is_valid = jslib_form_validate(document.forms[0], prop);
return page_is_valid;
});
// add a hidden field to each form to record which submit button
// was clicked so that it gets presented in the POST data
$("form").each(function() {
var $this = $(this);
var bid = "b_" + $this.attr("id") + "_clicked";
var b_clicked = '<input type="hidden" id="' + bid + '" name="' + bid + '">';
$(b_clicked).appendTo($this);
});
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
iframe_auto_resize();
});
iframe_auto_resize();
$('form input[type="submit"]').click(function(e) {
var form_id = $(e.target).closest("form").attr("id");
var f_s = "b_"+form_id+"_submit";
var f_r = "b_"+form_id+"_refresh";
var f_click = $("#b_"+form_id+"_clicked").val();
if (((f_click == f_s) || (f_click == f_r)) && page_is_valid)
{
parent.progress_modal_open();
}
});
parent.progress_modal_handler(parent.ple.PAGE_LOADED);
check_error();
focus_init("");
});
-->
</script>
</body>
</html>
+248
View File
@@ -0,0 +1,248 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright &copy; 2017-2022 Hewlett Packard Enterprise Development LP. -->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Port Status</title>
<link rel="shortcut icon" href="/htdocs/login/favicon.ico?">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/jquery-ui-1.12.1.custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/css/jquery.dataTables_themeroller.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_datatables_custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_common_pages.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/tabs.css">
<!--[if ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7.css" type="text/css">
<![endif]-->
<!--[if gte ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7plus.css" type="text/css">
<![endif]-->
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_3_5_1/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_ui_1_12_1/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables.min.js"></script>
</head>
<body class="ui-state-default fp_jqtds_page_body fp_corner_bottom">
<a name="focus_top" id="focus_top"></a>
<div id="fp_div_page_title_bar" class="fp_jqtds_h1">
<div id="fp_div_page_title_text">Port Status</div>&nbsp;
<div id="fp_div_title_bar_tooltip">
<a class="fp_anchor_tooltip" href="/htdocs/lang/en_us/help/base/help_port_summary.lsp" target="_blank">
<img src="/htdocs/static/bt1707389424/images/icon_help_black24-helpText.png" title="Help" alt="Help" border="0">
</a>
</div><!-- fp_div_title_bar_tooltip -->
</div><!-- fp_div_page_title_bar -->
<div class="fp_page_container">
<form id="form1" name="form1" method="post" action="/htdocs/pages/base/port_summary.lsp">
<div class="fp_sub_container">
<div id="dynamic_dt1"></div>
</div> <!-- fp_sub_container -->
<div id="page_buttons" class="fp_button_row">
<input class="fp_button ui-button ui-widget ui-state-default fp_primary_button" type="submit" id="b_form1_refresh" name="b_form1_refresh" value="Refresh" onclick="jslib_b_pressed_g='refresh';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default fp_dt_button" type="button" id="b_form1_dt_multi_edit" name="b_form1_dt_multi_edit" value="Edit" >
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default fp_dt_button" type="button" id="b_form1_dt_add" name="b_form1_dt_add" value="Edit All" >
</div> <!-- fp_button_row -->
</form> <!-- form1 -->
</div><!-- fp_page_container -->
<script type="text/javascript" language="JavaScript">
<!--
var jslib_msgs = parent.jslib_msgs_tbl;
-->
</script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/js/web-utils-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/plugins/jquery-plugins-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables-plugins.js"></script>
<script type="text/javascript" src="/htdocs/lang/en_us/culture/globalize.culture.en-US.20120606.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
var aDataSet = [
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_1" value="1"><label></label>', '1', '', 'Enabled', 'Normal', 'Link Down', 'Auto', '', '1518']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_2" value="2"><label></label>', '2', '', 'Enabled', 'Normal', 'Link Down', 'Auto', '', '1518']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_3" value="3"><label></label>', '3', '', 'Enabled', 'Normal', 'Link Up', 'Auto', '1000 Mbps', '1518']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_4" value="4"><label></label>', '4', '', 'Enabled', 'Normal', 'Link Up', 'Auto', '1000 Mbps', '1518']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_5" value="5"><label></label>', '5', '', 'Enabled', 'Normal', 'Link Down', 'Auto', '', '1518']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_6" value="6"><label></label>', '6', '', 'Enabled', 'Normal', 'Link Up', 'Auto', '100 Mbps Full Duplex', '1518']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_7" value="7"><label></label>', '7', '', 'Enabled', 'Normal', 'Link Up', 'Auto', '1000 Mbps', '1518']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_8" value="8"><label></label>', '8', '', 'Enabled', 'Normal', 'Link Up', 'Auto', '1000 Mbps', '1518']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_54" value="54"><label></label>', 'TRK1', '', 'Enabled', 'Normal', 'Link Down', 'Trunk', '', '1518']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_55" value="55"><label></label>', 'TRK2', '', 'Enabled', 'Normal', 'Link Down', 'Trunk', '', '1518']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_56" value="56"><label></label>', 'TRK3', '', 'Enabled', 'Normal', 'Link Down', 'Trunk', '', '1518']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_57" value="57"><label></label>', 'TRK4', '', 'Enabled', 'Normal', 'Link Down', 'Trunk', '', '1518']
];
var aColumns = [
{ "sTitle": '<input type="checkbox" class="chkall" name="chkall" id="chkall" value="chkall"><label></label>', "bSearchable": false, "bSortable": false, "sWidth": "2%" },
{ "sTitle": "Interface", "sType": "intf-sort", "sWidth": "8%" },
{ "sTitle": "Port Description", "sType": "html", "sWidth": "14%" },
{ "sTitle": "Admin Mode", "sType": "html", "sWidth": "14%" },
{ "sTitle": "Physical Type", "sType": "html", "sWidth": "14%" },
{ "sTitle": "Port Status", "sType": "html", "sWidth": "14%" },
{ "sTitle": "Physical Mode", "sType": "html", "sWidth": "14%" },
{ "sTitle": "Link Speed", "sType": "natural-sort", "sWidth": "14%" },
{ "sTitle": "MTU", "sType": "html", "sWidth": "6%" }
];
// Edit button query string callback function -
// This function name must be specified as the 'fn' parameter on 'modal_button_attrib'
// for the correct button, in this case, the 'edit' button
function fnEdit()
{
var qString = '';
var queueStr = [];
$(".chkrow:checked").each(function(idx) {
queueStr[idx] = $(this).val();
});
qString = '?intf=' + queueStr;
return qString;
}
function fnEditAll()
{
return '?intf=all';
}
$(document).ready(function()
{
// Add data table and set pagination and sorting
$('#dynamic_dt1').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="sorttable1"><\/table>' );
fp_dt_create("#sorttable1", { aaData: aDataSet, aoColumns: aColumns, dt_btn: true, multi_select: true, rw: true });
if ((12 == 0) || (false == true))
{
$("#b_form1_dt_add").button({ disabled: true });
}
});
-->
</script>
<script type="text/javascript" language="JavaScript">
<!--
$(document).ready( function()
{
var page_is_valid = true;
// format all culture-specific elements using the current locale
culture_format(parent.culture);
var myNav = navigator.userAgent.toLowerCase();
var isIe = false;
if (myNav.indexOf('msie') != -1)
{
var myVer = parseInt(myNav.split('msie')[1]);
}
if ((isIe == true) && (myVer < 8)) {
$('input[type=radio],[type=checkbox]').live('click', function () {
this.blur();
this.focus();
});
}
$(':input').bind('keypress', function(e) {
var key = (window.event) ? window.event.keyCode : e.which; // IE vs. FF
var $this = $(this);
if ( ($this.is(':not(:button, :submit, :reset, textarea)')) ) {
return (key != 13);
}
});
$(".fp_button").button();
$(".fp_button_cancel").button();
$('form input[type="reset"]').click(function(e) {
if( $('#sorttable1').length ){
fp_dt_reset_handler("#sorttable1");
}
return jslib_form_reset(this.form);
});
$(":submit,:button").click(function(e) {
// remember which button was clicked last by storing into hidden field
var button = $(this).attr("id");
var form_id = $(e.target).closest("form").attr("id");
if (form_id)
{
$("#b_"+form_id+"_clicked").val(button);
}
page_is_valid = jslib_form_validate(document.forms[0]);
return page_is_valid;
});
// add a hidden field to each form to record which submit button
// was clicked so that it gets presented in the POST data
$("form").each(function() {
var $this = $(this);
var bid = "b_" + $this.attr("id") + "_clicked";
var b_clicked = '<input type="hidden" id="' + bid + '" name="' + bid + '">';
$(b_clicked).appendTo($this);
});
// Bind to the click event for all the matching 'b_form1_dt_multi_edit' buttons to open a page as a modal dialog
$('[id*="b_form1_dt_multi_edit"]').click( function() {
var qStr = fnEdit();
main_modal_page_open('/htdocs/pages/base/port_summary_modal.lsp' + qStr, 'Edit Port Configuration', '540', '400', { btnPost : "Apply", btnClose : "Cancel" } );
});
// Bind to the click event for all the matching 'b_form1_dt_add' buttons to open a page as a modal dialog
$('[id*="b_form1_dt_add"]').click( function() {
var qStr = fnEditAll();
main_modal_page_open('/htdocs/pages/base/port_summary_modal.lsp' + qStr, 'Edit Port Configuration', '520', '320', { btnPost : "Apply", btnClose : "Cancel" } );
});
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
iframe_auto_resize();
});
iframe_auto_resize();
$('form input[type="submit"]').click(function(e) {
var form_id = $(e.target).closest("form").attr("id");
var f_s = "b_"+form_id+"_submit";
var f_r = "b_"+form_id+"_refresh";
var f_click = $("#b_"+form_id+"_clicked").val();
if (((f_click == f_s) || (f_click == f_r)) && page_is_valid)
{
parent.progress_modal_open();
}
});
parent.progress_modal_handler(parent.ple.PAGE_LOADED);
focus_init("focus_top");
});
-->
</script>
</body>
</html>
+222
View File
@@ -0,0 +1,222 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright &copy; 2017-2022 Hewlett Packard Enterprise Development LP. -->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Port Summary Statistics</title>
<link rel="shortcut icon" href="/htdocs/login/favicon.ico?">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/jquery-ui-1.12.1.custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/css/jquery.dataTables_themeroller.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_datatables_custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_common_pages.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/tabs.css">
<!--[if ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7.css" type="text/css">
<![endif]-->
<!--[if gte ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7plus.css" type="text/css">
<![endif]-->
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_3_5_1/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_ui_1_12_1/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables.min.js"></script>
</head>
<body class="ui-state-default fp_jqtds_page_body fp_corner_bottom">
<a name="focus_top" id="focus_top"></a>
<div id="fp_div_page_title_bar" class="fp_jqtds_h1">
<div id="fp_div_page_title_text">Port Summary Statistics</div>&nbsp;
<div id="fp_div_title_bar_tooltip">
<a class="fp_anchor_tooltip" href="/htdocs/lang/en_us/help/base/help_port_summary_stats.lsp" target="_blank">
<img src="/htdocs/static/bt1707389424/images/icon_help_black24-helpText.png" title="Help" alt="Help" border="0">
</a>
</div><!-- fp_div_title_bar_tooltip -->
</div><!-- fp_div_page_title_bar -->
<div class="fp_page_container">
<form id="form1" name="form1" method="post" action="/htdocs/pages/base/port_summary_stats.lsp">
<div class="fp_sub_container">
<div id="dynamic_dt1"></div>
</div> <!-- fp_sub_container -->
<div id="page_buttons" class="fp_button_row">
<input class="fp_button ui-button ui-widget ui-state-default fp_primary_button" type="submit" id="b_form1_refresh" name="b_form1_refresh" value="Refresh" onclick="jslib_b_pressed_g='refresh';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default fp_dt_button" type="submit" id="b_form1_dt_clear_all_ctrs" name="b_form1_dt_clear_all_ctrs" value="Clear All Counters" onclick="jslib_b_pressed_g='dt_clear_all_ctrs';">
</div> <!-- fp_button_row -->
</form> <!-- form1 -->
</div><!-- fp_page_container -->
<script type="text/javascript" language="JavaScript">
<!--
var jslib_msgs = parent.jslib_msgs_tbl;
-->
</script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/js/web-utils-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/plugins/jquery-plugins-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables-plugins.js"></script>
<script type="text/javascript" src="/htdocs/lang/en_us/culture/globalize.culture.en-US.20120606.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
var aDataSet = [
['1', '', '', '', '', '', '', '', '']
,
['2', '', '', '', '', '', '', '', '']
,
['3', '', '', '', '', '', '', '', '']
,
['4', '', '', '', '', '', '', '', '']
,
['5', '', '', '', '', '', '', '', '']
,
['6', '', '', '', '', '', '', '', '']
,
['7', '', '', '', '', '', '', '', '']
,
['8', '', '', '', '', '', '', '', '']
,
['TRK1', '', '', '', '', '', '', '', '']
,
['TRK2', '', '', '', '', '', '', '', '']
,
['TRK3', '', '', '', '', '', '', '', '']
,
['TRK4', '', '', '', '', '', '', '', '']
];
var aColumns = [
{ "sTitle": "Interface", "sType": "natural-sort" },
{ "sTitle": "Received Packets w/o Error", "sType": "natural-sort" },
{ "sTitle": "Received Packets with Error", "sType": "natural-sort" },
{ "sTitle": "Broadcast Received Packets", "sType": "natural-sort" },
{ "sTitle": "Transmitted Packets w/o Error", "sType": "natural-sort" },
{ "sTitle": "Transmitted Packets with Error", "sType": "natural-sort" },
{ "sTitle": "Collisions", "sType": "natural-sort" },
{ "sTitle": "Transmitted Pause Frames", "sType": "natural-sort" },
{ "sTitle": "Received Pause Frames", "sType": "natural-sort" }
];
$(document).ready(function()
{
//table pagination and sorting
$('#dynamic_dt1').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="sorttable1"><\/table>' );
fp_dt_create("#sorttable1", { aaData: aDataSet, aoColumns: aColumns, dt_btn: true, multi_select:true, rw: true });
});
-->
</script>
<script type="text/javascript" language="JavaScript">
<!--
$(document).ready( function()
{
var page_is_valid = true;
// format all culture-specific elements using the current locale
culture_format(parent.culture);
var myNav = navigator.userAgent.toLowerCase();
var isIe = false;
if (myNav.indexOf('msie') != -1)
{
var myVer = parseInt(myNav.split('msie')[1]);
}
if ((isIe == true) && (myVer < 8)) {
$('input[type=radio],[type=checkbox]').live('click', function () {
this.blur();
this.focus();
});
}
$(':input').bind('keypress', function(e) {
var key = (window.event) ? window.event.keyCode : e.which; // IE vs. FF
var $this = $(this);
if ( ($this.is(':not(:button, :submit, :reset, textarea)')) ) {
return (key != 13);
}
});
$(".fp_button").button();
$(".fp_button_cancel").button();
$('form input[type="reset"]').click(function(e) {
if( $('#sorttable1').length ){
fp_dt_reset_handler("#sorttable1");
}
return jslib_form_reset(this.form);
});
$(":submit,:button").click(function(e) {
// remember which button was clicked last by storing into hidden field
var button = $(this).attr("id");
var form_id = $(e.target).closest("form").attr("id");
if (form_id)
{
$("#b_"+form_id+"_clicked").val(button);
}
page_is_valid = jslib_form_validate(document.forms[0]);
return page_is_valid;
});
// add a hidden field to each form to record which submit button
// was clicked so that it gets presented in the POST data
$("form").each(function() {
var $this = $(this);
var bid = "b_" + $this.attr("id") + "_clicked";
var b_clicked = '<input type="hidden" id="' + bid + '" name="' + bid + '">';
$(b_clicked).appendTo($this);
});
var opt_btns = [
{ id: 'btnPost', text: 'OK', msg: 'To proceed, click OK.'},
{ id: 'btnClose', text: 'Close', msg: 'To return to the web page, click Close.'}
];
// Bind to the submit event for 'b_form1_dt_clear_all_ctrs' to open a modal confirm dialog
$('#form1').submit( function(e) {
var pattern = /dt_clear_all_ctrs/gi;
if (jslib_b_pressed_g.match(pattern)) {
e.preventDefault();
main_confirm_dialog_open_optional_buttons('dt_clear_all_ctrs', 'Are you sure you want to clear all counters?', opt_btns); }
});
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
iframe_auto_resize();
});
iframe_auto_resize();
$('form input[type="submit"]').click(function(e) {
var form_id = $(e.target).closest("form").attr("id");
var f_s = "b_"+form_id+"_submit";
var f_r = "b_"+form_id+"_refresh";
var f_click = $("#b_"+form_id+"_clicked").val();
if (((f_click == f_s) || (f_click == f_r)) && page_is_valid)
{
parent.progress_modal_open();
}
});
parent.progress_modal_handler(parent.ple.PAGE_LOADED);
focus_init("focus_top");
});
-->
</script>
</body>
</html>
+241
View File
@@ -0,0 +1,241 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright &copy; 2017-2022 Hewlett Packard Enterprise Development LP. -->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Password Manager</title>
<link rel="shortcut icon" href="/htdocs/login/favicon.ico?">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/jquery-ui-1.12.1.custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/css/jquery.dataTables_themeroller.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_datatables_custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_common_pages.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/tabs.css">
<!--[if ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7.css" type="text/css">
<![endif]-->
<!--[if gte ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7plus.css" type="text/css">
<![endif]-->
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_3_5_1/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_ui_1_12_1/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables.min.js"></script>
</head>
<body class="ui-state-default fp_jqtds_page_body fp_corner_bottom">
<a name="focus_top" id="focus_top"></a>
<div id="fp_div_page_title_bar" class="fp_jqtds_h1">
<div id="fp_div_page_title_text">Password Manager</div>&nbsp;
<div id="fp_div_title_bar_tooltip">
<a class="fp_anchor_tooltip" href="/htdocs/lang/en_us/help/base/help_user_accounts.lsp" target="_blank">
<img src="/htdocs/static/bt1707389424/images/icon_help_black24-helpText.png" title="Help" alt="Help" border="0">
</a>
</div><!-- fp_div_title_bar_tooltip -->
</div><!-- fp_div_page_title_bar -->
<div class="fp_page_container">
<!-- ******************************* form1 ******************************* -->
<form id="form1" name="form1" method="post" action="/htdocs/pages/base/user_accounts.lsp">
<div class="fp_sub_container">
<table id="fp_page_table_content" cellpadding="0" cellspacing="0" >
<tbody>
<tr> <!-- User Name -->
<td class="ui-widget-content fp_data_label">Username</td>
<td class="fp_dialog ui-widget-content fp_data_value">
<input class="fp_inputfield" type="text" id="user_name" name="user_name" maxlength="64"
value="admin">&nbsp;&nbsp;(1 to 64 characters)</td>
</tr>
<tr> <!-- Current Password -->
<td class="ui-widget-content fp_data_label">Current Password</td>
<td class="ui-widget-content fp_data_value">
<input class="fp_inputfield" type="password" id="current_password" name="current_password" maxlength="64"
value="">&nbsp;&nbsp;(8 to 64)</td>
</tr>
<tr> <!-- New Password -->
<td class="ui-widget-content fp_data_label">New Password</td>
<td class="ui-widget-content fp_data_value">
<input class="fp_inputfield" type="password" id="new_password" name="new_password" maxlength="64"
value="">&nbsp;&nbsp;(8 to 64)</td>
</tr>
<tr> <!-- Confirm New Password -->
<td class="ui-widget-content fp_data_label">Confirm New Password</td>
<td class="ui-widget-content fp_data_value">
<input class="fp_inputfield" type="password" id="confirm_new_passwd" name="confirm_new_passwd" maxlength="64"
value="">&nbsp;&nbsp;(8 to 64)</td>
</tr>
</tbody>
</table>
</div> <!-- fp_sub_container -->
<div id="page_buttons" class="fp_button_row">
<input class="fp_button ui-button ui-widget ui-state-default" type="submit" id="b_form1_submit" name="b_form1_submit" value="Apply" onclick="jslib_b_pressed_g='submit';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default" type="submit" id="b_form1_refresh" name="b_form1_refresh" value="Refresh" onclick="jslib_b_pressed_g='refresh';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default" type="reset" id="b_form1_cancel" name="b_form1_cancel" value="Cancel" onclick="jslib_b_pressed_g='cancel';">
</div> <!-- fp_button_row -->
</form> <!-- form1 -->
</div><!-- fp_page_container -->
<script type="text/javascript" language="JavaScript">
<!--
var jslib_msgs = parent.jslib_msgs_tbl;
-->
</script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/js/web-utils-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/plugins/jquery-plugins-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables-plugins.js"></script>
<script type="text/javascript" src="/htdocs/lang/en_us/culture/globalize.culture.en-US.20120606.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
// Construct property objects for each input field in the form
var prop =
{
new_password: new FieldProp({ defval: "", dname: "New Password", formfield: "new_password", max: 64, min: 8, regex: /.*/, type: 2 }),
user_name: new FieldProp({ defval: "", dname: "Username", formfield: "user_name", max: 64, min: 1, regex: /^[\w _\-\.]*$/, type: 2 }),
current_password: new FieldProp({ defval: "", dname: "Current Password", formfield: "current_password", max: 64, min: 8, optional: true, regex: /.*/, type: 2 }),
confirm_new_passwd: new FieldProp({ defval: "", dname: "Confirm New Password", formfield: "confirm_new_passwd", max: 64, min: 8, regex: /.*/, type: 2 })
};
jslib_form_validation_bind($('#form1')[0], prop);
prop.confirm_new_passwd.uservalidate = function (field)
{
var pass = $("#new_password").val();
var confirm_pass = field.value;
if (pass.match(/[?"]/g)) {
return { errmsg: jsmsg.invalid_chars };
} else if (pass !== confirm_pass) {
return { errmsg: jsmsg.same_passwd };
} else {
return null;
}
}
function local_validate()
{
if( jslib_b_pressed_g === 'submit')
{
var v1 = $('#user_name').val();
if(v1 !== "admin")
{
var r = confirm("Changing the user name! To initiate a new web session you must log in using the newly defined user name. Do you wish to change the user name?");
return r;
}
}
return true;
}
-->
</script>
<script type="text/javascript" language="JavaScript">
<!--
$(document).ready( function()
{
var page_is_valid = true;
// format all culture-specific elements using the current locale
culture_format(parent.culture);
var myNav = navigator.userAgent.toLowerCase();
var isIe = false;
if (myNav.indexOf('msie') != -1)
{
var myVer = parseInt(myNav.split('msie')[1]);
}
if ((isIe == true) && (myVer < 8)) {
$('input[type=radio],[type=checkbox]').live('click', function () {
this.blur();
this.focus();
});
}
$(':input').bind('keypress', function(e) {
var key = (window.event) ? window.event.keyCode : e.which; // IE vs. FF
var $this = $(this);
if ( ($this.is(':not(:button, :submit, :reset, textarea)')) ) {
return (key != 13);
}
});
$(".fp_button").button();
$(".fp_button_cancel").button();
$('form input[type="reset"]').click(function(e) {
if( $('#sorttable1').length ){
fp_dt_reset_handler("#sorttable1");
}
return jslib_form_reset(this.form);
});
$(":submit,:button").click(function(e) {
// remember which button was clicked last by storing into hidden field
var button = $(this).attr("id");
var form_id = $(e.target).closest("form").attr("id");
if (form_id)
{
$("#b_"+form_id+"_clicked").val(button);
}
page_is_valid = jslib_form_validate(document.forms[0], prop);
if (page_is_valid) { page_is_valid = local_validate(); }
return page_is_valid;
});
// add a hidden field to each form to record which submit button
// was clicked so that it gets presented in the POST data
$("form").each(function() {
var $this = $(this);
var bid = "b_" + $this.attr("id") + "_clicked";
var b_clicked = '<input type="hidden" id="' + bid + '" name="' + bid + '">';
$(b_clicked).appendTo($this);
});
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
iframe_auto_resize();
});
iframe_auto_resize();
$('form input[type="submit"]').click(function(e) {
var form_id = $(e.target).closest("form").attr("id");
var f_s = "b_"+form_id+"_submit";
var f_r = "b_"+form_id+"_refresh";
var f_click = $("#b_"+form_id+"_clicked").val();
if (((f_click == f_s) || (f_click == f_r)) && page_is_valid)
{
parent.progress_modal_open();
}
});
parent.progress_modal_handler(parent.ple.PAGE_LOADED);
check_error();
focus_init("focus_top");
});
-->
</script>
</body>
</html>
+212
View File
@@ -0,0 +1,212 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright &copy; 2017-2022 Hewlett Packard Enterprise Development LP. -->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Trunk Configuration</title>
<link rel="shortcut icon" href="/htdocs/login/favicon.ico?">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/jquery-ui-1.12.1.custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/css/jquery.dataTables_themeroller.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_datatables_custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_common_pages.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/tabs.css">
<!--[if ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7.css" type="text/css">
<![endif]-->
<!--[if gte ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7plus.css" type="text/css">
<![endif]-->
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_3_5_1/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_ui_1_12_1/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables.min.js"></script>
</head>
<body class="ui-state-default fp_jqtds_page_body fp_corner_bottom">
<a name="focus_top" id="focus_top"></a>
<div id="fp_div_page_title_bar" class="fp_jqtds_h1">
<div id="fp_div_page_title_text">Trunk Configuration</div>&nbsp;
<div id="fp_div_title_bar_tooltip">
<a class="fp_anchor_tooltip" href="/htdocs/lang/en_us/help/switching/help_port_channel_summary.lsp" target="_blank">
<img src="/htdocs/static/bt1707389424/images/icon_help_black24-helpText.png" title="Help" alt="Help" border="0">
</a>
</div><!-- fp_div_title_bar_tooltip -->
</div><!-- fp_div_page_title_bar -->
<div class="fp_page_container">
<form id="form1" name="form1" method="post" action="/htdocs/pages/switching/port_channel_summary.lsp">
<div class="fp_sub_container">
<div id="dynamic_dt1"></div>
</div> <!-- fp_sub_container -->
<div id="page_buttons" class="fp_button_row">
<input class="fp_button ui-button ui-widget ui-state-default fp_primary_button" type="submit" id="b_form1_refresh" name="b_form1_refresh" value="Refresh" onclick="jslib_b_pressed_g='refresh';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default fp_dt_button" type="button" id="b_form1_dt_edit" name="b_form1_dt_edit" value="Edit" >
</div> <!-- fp_button_row -->
</form> <!-- form1 -->
</div><!-- fp_page_container -->
<script type="text/javascript" language="JavaScript">
<!--
var jslib_msgs = parent.jslib_msgs_tbl;
-->
</script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/js/web-utils-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/plugins/jquery-plugins-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables-plugins.js"></script>
<script type="text/javascript" src="/htdocs/lang/en_us/culture/globalize.culture.en-US.20120606.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
var aDataSet = [
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_54" value="54"><label></label>', 'TRK1', 'TRK1', 'Static', 'Enabled', 'Down', '', '']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_55" value="55"><label></label>', 'TRK2', 'TRK2', 'Static', 'Enabled', 'Down', '', '']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_56" value="56"><label></label>', 'TRK3', 'TRK3', 'Static', 'Enabled', 'Down', '', '']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_57" value="57"><label></label>', 'TRK4', 'TRK4', 'Static', 'Enabled', 'Down', '', '']
];
var aColumns = [
{ "sTitle": '', "bSearchable": false, "bSortable": false, "sWidth": "2%" },
{ "sTitle": "Trunk", "sType": "natural-sort" },
{ "sTitle": "Name", "sType": "natural-sort" },
{ "sTitle": "Type", "sType": "natural-sort" },
{ "sTitle": "Admin Mode", "sType": "natural-sort" },
{ "sTitle": "Link Status", "sType": "natural-sort" },
{ "sTitle": "Members", "bSortable": false },
{ "sTitle": "Active Ports", "bSortable": false }
];
// Edit button query string callback function -
// This function name must be specified as the 'fn' parameter on 'modal_button_attrib'
// for the correct button, in this case, the 'edit' button
function fnEdit()
{
var selected = fp_dt_get_selected($("#sorttable1"));
var qString = '';
if (selected.length == 1)
{
qString = '?index=' + selected[0].cells[0].firstChild.value;
}
return qString;
}
$(document).ready(function()
{
// define sort technique for all permanent columns
$('#dynamic_dt1').html( '<table width="100%" cellpadding="0" cellspacing="0" border="0" class="display" id="sorttable1"><\/table>' );
fp_dt_create("#sorttable1", { aaData: aDataSet, aoColumns: aColumns, dt_btn: true, rw: true });
});
-->
</script>
<script type="text/javascript" language="JavaScript">
<!--
$(document).ready( function()
{
var page_is_valid = true;
// format all culture-specific elements using the current locale
culture_format(parent.culture);
var myNav = navigator.userAgent.toLowerCase();
var isIe = false;
if (myNav.indexOf('msie') != -1)
{
var myVer = parseInt(myNav.split('msie')[1]);
}
if ((isIe == true) && (myVer < 8)) {
$('input[type=radio],[type=checkbox]').live('click', function () {
this.blur();
this.focus();
});
}
$(':input').bind('keypress', function(e) {
var key = (window.event) ? window.event.keyCode : e.which; // IE vs. FF
var $this = $(this);
if ( ($this.is(':not(:button, :submit, :reset, textarea)')) ) {
return (key != 13);
}
});
$(".fp_button").button();
$(".fp_button_cancel").button();
$('form input[type="reset"]').click(function(e) {
if( $('#sorttable1').length ){
fp_dt_reset_handler("#sorttable1");
}
return jslib_form_reset(this.form);
});
$(":submit,:button").click(function(e) {
// remember which button was clicked last by storing into hidden field
var button = $(this).attr("id");
var form_id = $(e.target).closest("form").attr("id");
if (form_id)
{
$("#b_"+form_id+"_clicked").val(button);
}
page_is_valid = jslib_form_validate(document.forms[0]);
return page_is_valid;
});
// add a hidden field to each form to record which submit button
// was clicked so that it gets presented in the POST data
$("form").each(function() {
var $this = $(this);
var bid = "b_" + $this.attr("id") + "_clicked";
var b_clicked = '<input type="hidden" id="' + bid + '" name="' + bid + '">';
$(b_clicked).appendTo($this);
});
// Bind to the click event for all the matching 'b_form1_dt_edit' buttons to open a page as a modal dialog
$('[id*="b_form1_dt_edit"]').click( function() {
var qStr = fnEdit();
main_modal_page_open('/htdocs/pages/switching/port_channel_modal.lsp' + qStr, 'Edit Existing Trunk', '550', '520', { btnPost : "Apply", btnClose : "Cancel" } );
});
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
iframe_auto_resize();
});
iframe_auto_resize();
$('form input[type="submit"]').click(function(e) {
var form_id = $(e.target).closest("form").attr("id");
var f_s = "b_"+form_id+"_submit";
var f_r = "b_"+form_id+"_refresh";
var f_click = $("#b_"+form_id+"_clicked").val();
if (((f_click == f_s) || (f_click == f_r)) && page_is_valid)
{
parent.progress_modal_open();
}
});
parent.progress_modal_handler(parent.ple.PAGE_LOADED);
focus_init("focus_top");
});
-->
</script>
</body>
</html>
+276
View File
@@ -0,0 +1,276 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright &copy; 2017-2022 Hewlett Packard Enterprise Development LP. -->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>VLAN Port Membership</title>
<link rel="shortcut icon" href="/htdocs/login/favicon.ico?">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/jquery-ui-1.12.1.custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/css/jquery.dataTables_themeroller.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_datatables_custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_common_pages.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/tabs.css">
<!--[if ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7.css" type="text/css">
<![endif]-->
<!--[if gte ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7plus.css" type="text/css">
<![endif]-->
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_3_5_1/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_ui_1_12_1/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables.min.js"></script>
</head>
<body class="ui-state-default fp_jqtds_page_body fp_corner_bottom">
<a name="focus_top" id="focus_top"></a>
<div id="fp_div_page_title_bar" class="fp_jqtds_h1">
<div id="fp_div_page_title_text">VLAN Port Membership</div>&nbsp;
<div id="fp_div_title_bar_tooltip">
<a class="fp_anchor_tooltip" href="/htdocs/lang/en_us/help/switching/help_vlan_per_port.lsp" target="_blank">
<img src="/htdocs/static/bt1707389424/images/icon_help_black24-helpText.png" title="Help" alt="Help" border="0">
</a>
</div><!-- fp_div_title_bar_tooltip -->
</div><!-- fp_div_page_title_bar -->
<div class="fp_page_container">
<form id="form1" name="form1" method="post" action="/htdocs/pages/switching/vlan_per_port.lsp">
<div class="fp_sub_container">
<table id="fp_page_table_content" cellpadding="0" cellspacing="0">
<tbody>
<tr> <!-- VLAN ID -->
<td class="ui-widget-content fp_data_label">VLAN ID</td>
<td class="ui-widget-content fp_data_value" id="vlan">
<select name="vlan_sel[]" id="vlan_sel" onchange="selector_change(this);">
<option id="vlan_sel_1" value="1" selected="selected">1</option>
<option id="vlan_sel_10" value="10">10</option>
<option id="vlan_sel_20" value="20">20</option>
<option id="vlan_sel_30" value="30">30</option>
<option id="vlan_sel_40" value="40">40</option>
<option id="vlan_sel_50" value="50">50</option>
<option id="vlan_sel_60" value="60">60</option>
</select>
</td>
</tr>
</tbody>
</table>
</div> <!-- fp_sub_container -->
<hr class="first"></hr>
<div class="fp_sub_container">
<div id="dynamic_dt1"></div>
</div> <!-- fp_sub_container -->
<div id="page_buttons" class="fp_button_row">
<input class="fp_button ui-button ui-widget ui-state-default fp_primary_button" type="submit" id="b_form1_refresh" name="b_form1_refresh" value="Refresh" onclick="jslib_b_pressed_g='refresh';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default fp_dt_button" type="button" id="b_form1_dt_remove" name="b_form1_dt_remove" value="Edit" >
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default fp_dt_button" type="button" id="b_form1_dt_add" name="b_form1_dt_add" value="Edit All" >
</div> <!-- fp_button_row -->
</form> <!-- form1 -->
</div><!-- fp_page_container -->
<script type="text/javascript" language="JavaScript">
<!--
var jslib_msgs = parent.jslib_msgs_tbl;
-->
</script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/js/web-utils-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/plugins/jquery-plugins-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables-plugins.js"></script>
<script type="text/javascript" src="/htdocs/lang/en_us/culture/globalize.culture.en-US.20120606.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
var aDataSet = [
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_1" value="1"><label></label>', '1', 'Untagged']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_2" value="2"><label></label>', '2', 'Excluded']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_3" value="3"><label></label>', '3', 'Excluded']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_4" value="4"><label></label>', '4', 'Excluded']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_5" value="5"><label></label>', '5', 'Untagged']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_6" value="6"><label></label>', '6', 'Excluded']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_7" value="7"><label></label>', '7', 'Untagged']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_8" value="8"><label></label>', '8', 'Tagged']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_54" value="54"><label></label>', 'TRK1', 'Untagged']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_55" value="55"><label></label>', 'TRK2', 'Untagged']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_56" value="56"><label></label>', 'TRK3', 'Untagged']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_57" value="57"><label></label>', 'TRK4', 'Untagged']
];
var aColumns = [
{ "sTitle": '<input type="checkbox" class="chkall" name="chkall" id="chkall" value="chkall"><label></label>', "bSearchable": false, "bSortable": false, "sWidth": "2%" },
{ "sTitle": "Interface", "sType": "intf-sort" },
{ "sTitle": "Participation/Tagging", "sType": "html" }
];
// Select list onchange handler (client-side)
function selector_change(field)
{
field.form.submit();
}
// Edit button query string callback function
// This function name is specified as the 'fn' parameter on 'modal_button_attrib' for the 'edit' button
function fnEdit()
{
var qString = '';
var intfStr = [];
$(".chkrow:checked").each(function(idx) {
intfStr[idx] = $(this).val();
});
qString = '?vlan='+$("#vlan_sel option:selected").val() + '&intfStr='+intfStr;
return qString;
}
// Edit All button query string callback function
// This function name is specified as the 'fn' parameter on 'modal_button_attrib' for the 'editAll' button
function fnEditAll()
{
return '?vlan='+$("#vlan_sel option:selected").val() + '&intfStr=all';
}
$(document).ready( function ()
{
// Define datatable
$('#dynamic_dt1').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="sorttable1"><\/table>' );
fp_dt_create("#sorttable1", { aaData: aDataSet, aoColumns: aColumns, dt_btn: true, multi_select: true, rw: true });
var val = 0;
if ((val != 0) || (false == true))
{
$("#b_form1_dt_add").button("disable");
}
});
-->
</script>
<script type="text/javascript" language="JavaScript">
<!--
$(document).ready( function()
{
var page_is_valid = true;
// format all culture-specific elements using the current locale
culture_format(parent.culture);
var myNav = navigator.userAgent.toLowerCase();
var isIe = false;
if (myNav.indexOf('msie') != -1)
{
var myVer = parseInt(myNav.split('msie')[1]);
}
if ((isIe == true) && (myVer < 8)) {
$('input[type=radio],[type=checkbox]').live('click', function () {
this.blur();
this.focus();
});
}
$(':input').bind('keypress', function(e) {
var key = (window.event) ? window.event.keyCode : e.which; // IE vs. FF
var $this = $(this);
if ( ($this.is(':not(:button, :submit, :reset, textarea)')) ) {
return (key != 13);
}
});
$(".fp_button").button();
$(".fp_button_cancel").button();
$('form input[type="reset"]').click(function(e) {
if( $('#sorttable1').length ){
fp_dt_reset_handler("#sorttable1");
}
return jslib_form_reset(this.form);
});
$(":submit,:button").click(function(e) {
// remember which button was clicked last by storing into hidden field
var button = $(this).attr("id");
var form_id = $(e.target).closest("form").attr("id");
if (form_id)
{
$("#b_"+form_id+"_clicked").val(button);
}
page_is_valid = jslib_form_validate(document.forms[0]);
return page_is_valid;
});
// add a hidden field to each form to record which submit button
// was clicked so that it gets presented in the POST data
$("form").each(function() {
var $this = $(this);
var bid = "b_" + $this.attr("id") + "_clicked";
var b_clicked = '<input type="hidden" id="' + bid + '" name="' + bid + '">';
$(b_clicked).appendTo($this);
});
// Bind to the click event for all the matching 'b_form1_dt_remove' buttons to open a page as a modal dialog
$('[id*="b_form1_dt_remove"]').click( function() {
var qStr = fnEdit();
main_modal_page_open('/htdocs/pages/switching/vlan_per_port_modal.lsp' + qStr, 'Edit VLAN Port Membership', '750', '380', { btnPost : "Apply", btnClose : "Cancel" } );
});
// Bind to the click event for all the matching 'b_form1_dt_add' buttons to open a page as a modal dialog
$('[id*="b_form1_dt_add"]').click( function() {
var qStr = fnEditAll();
main_modal_page_open('/htdocs/pages/switching/vlan_per_port_modal.lsp' + qStr, 'Edit VLAN Port Membership', '750', '360', { btnPost : "Apply", btnClose : "Cancel" } );
});
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
iframe_auto_resize();
});
iframe_auto_resize();
$('form input[type="submit"]').click(function(e) {
var form_id = $(e.target).closest("form").attr("id");
var f_s = "b_"+form_id+"_submit";
var f_r = "b_"+form_id+"_refresh";
var f_click = $("#b_"+form_id+"_clicked").val();
if (((f_click == f_s) || (f_click == f_r)) && page_is_valid)
{
parent.progress_modal_open();
}
});
parent.progress_modal_handler(parent.ple.PAGE_LOADED);
focus_init("focus_top");
});
-->
</script>
</body>
</html>
+276
View File
@@ -0,0 +1,276 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright &copy; 2017-2022 Hewlett Packard Enterprise Development LP. -->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>VLAN Port Membership</title>
<link rel="shortcut icon" href="/htdocs/login/favicon.ico?">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/jquery-ui-1.12.1.custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/css/jquery.dataTables_themeroller.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_datatables_custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_common_pages.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/tabs.css">
<!--[if ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7.css" type="text/css">
<![endif]-->
<!--[if gte ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7plus.css" type="text/css">
<![endif]-->
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_3_5_1/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_ui_1_12_1/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables.min.js"></script>
</head>
<body class="ui-state-default fp_jqtds_page_body fp_corner_bottom">
<a name="focus_top" id="focus_top"></a>
<div id="fp_div_page_title_bar" class="fp_jqtds_h1">
<div id="fp_div_page_title_text">VLAN Port Membership</div>&nbsp;
<div id="fp_div_title_bar_tooltip">
<a class="fp_anchor_tooltip" href="/htdocs/lang/en_us/help/switching/help_vlan_per_port.lsp" target="_blank">
<img src="/htdocs/static/bt1707389424/images/icon_help_black24-helpText.png" title="Help" alt="Help" border="0">
</a>
</div><!-- fp_div_title_bar_tooltip -->
</div><!-- fp_div_page_title_bar -->
<div class="fp_page_container">
<form id="form1" name="form1" method="post" action="/htdocs/pages/switching/vlan_per_port.lsp">
<div class="fp_sub_container">
<table id="fp_page_table_content" cellpadding="0" cellspacing="0">
<tbody>
<tr> <!-- VLAN ID -->
<td class="ui-widget-content fp_data_label">VLAN ID</td>
<td class="ui-widget-content fp_data_value" id="vlan">
<select name="vlan_sel[]" id="vlan_sel" onchange="selector_change(this);">
<option id="vlan_sel_1" value="1">1</option>
<option id="vlan_sel_10" value="10" selected="selected">10</option>
<option id="vlan_sel_20" value="20">20</option>
<option id="vlan_sel_30" value="30">30</option>
<option id="vlan_sel_40" value="40">40</option>
<option id="vlan_sel_50" value="50">50</option>
<option id="vlan_sel_60" value="60">60</option>
</select>
</td>
</tr>
</tbody>
</table>
</div> <!-- fp_sub_container -->
<hr class="first"></hr>
<div class="fp_sub_container">
<div id="dynamic_dt1"></div>
</div> <!-- fp_sub_container -->
<div id="page_buttons" class="fp_button_row">
<input class="fp_button ui-button ui-widget ui-state-default fp_primary_button" type="submit" id="b_form1_refresh" name="b_form1_refresh" value="Refresh" onclick="jslib_b_pressed_g='refresh';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default fp_dt_button" type="button" id="b_form1_dt_remove" name="b_form1_dt_remove" value="Edit" >
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default fp_dt_button" type="button" id="b_form1_dt_add" name="b_form1_dt_add" value="Edit All" >
</div> <!-- fp_button_row -->
</form> <!-- form1 -->
</div><!-- fp_page_container -->
<script type="text/javascript" language="JavaScript">
<!--
var jslib_msgs = parent.jslib_msgs_tbl;
-->
</script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/js/web-utils-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/plugins/jquery-plugins-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables-plugins.js"></script>
<script type="text/javascript" src="/htdocs/lang/en_us/culture/globalize.culture.en-US.20120606.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
var aDataSet = [
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_1" value="1"><label></label>', '1', 'Excluded']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_2" value="2"><label></label>', '2', 'Untagged']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_3" value="3"><label></label>', '3', 'Untagged']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_4" value="4"><label></label>', '4', 'Untagged']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_5" value="5"><label></label>', '5', 'Excluded']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_6" value="6"><label></label>', '6', 'Excluded']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_7" value="7"><label></label>', '7', 'Excluded']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_8" value="8"><label></label>', '8', 'Untagged']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_54" value="54"><label></label>', 'TRK1', 'Excluded']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_55" value="55"><label></label>', 'TRK2', 'Excluded']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_56" value="56"><label></label>', 'TRK3', 'Excluded']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_57" value="57"><label></label>', 'TRK4', 'Excluded']
];
var aColumns = [
{ "sTitle": '<input type="checkbox" class="chkall" name="chkall" id="chkall" value="chkall"><label></label>', "bSearchable": false, "bSortable": false, "sWidth": "2%" },
{ "sTitle": "Interface", "sType": "intf-sort" },
{ "sTitle": "Participation/Tagging", "sType": "html" }
];
// Select list onchange handler (client-side)
function selector_change(field)
{
field.form.submit();
}
// Edit button query string callback function
// This function name is specified as the 'fn' parameter on 'modal_button_attrib' for the 'edit' button
function fnEdit()
{
var qString = '';
var intfStr = [];
$(".chkrow:checked").each(function(idx) {
intfStr[idx] = $(this).val();
});
qString = '?vlan='+$("#vlan_sel option:selected").val() + '&intfStr='+intfStr;
return qString;
}
// Edit All button query string callback function
// This function name is specified as the 'fn' parameter on 'modal_button_attrib' for the 'editAll' button
function fnEditAll()
{
return '?vlan='+$("#vlan_sel option:selected").val() + '&intfStr=all';
}
$(document).ready( function ()
{
// Define datatable
$('#dynamic_dt1').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="sorttable1"><\/table>' );
fp_dt_create("#sorttable1", { aaData: aDataSet, aoColumns: aColumns, dt_btn: true, multi_select: true, rw: true });
var val = 0;
if ((val != 0) || (false == true))
{
$("#b_form1_dt_add").button("disable");
}
});
-->
</script>
<script type="text/javascript" language="JavaScript">
<!--
$(document).ready( function()
{
var page_is_valid = true;
// format all culture-specific elements using the current locale
culture_format(parent.culture);
var myNav = navigator.userAgent.toLowerCase();
var isIe = false;
if (myNav.indexOf('msie') != -1)
{
var myVer = parseInt(myNav.split('msie')[1]);
}
if ((isIe == true) && (myVer < 8)) {
$('input[type=radio],[type=checkbox]').live('click', function () {
this.blur();
this.focus();
});
}
$(':input').bind('keypress', function(e) {
var key = (window.event) ? window.event.keyCode : e.which; // IE vs. FF
var $this = $(this);
if ( ($this.is(':not(:button, :submit, :reset, textarea)')) ) {
return (key != 13);
}
});
$(".fp_button").button();
$(".fp_button_cancel").button();
$('form input[type="reset"]').click(function(e) {
if( $('#sorttable1').length ){
fp_dt_reset_handler("#sorttable1");
}
return jslib_form_reset(this.form);
});
$(":submit,:button").click(function(e) {
// remember which button was clicked last by storing into hidden field
var button = $(this).attr("id");
var form_id = $(e.target).closest("form").attr("id");
if (form_id)
{
$("#b_"+form_id+"_clicked").val(button);
}
page_is_valid = jslib_form_validate(document.forms[0]);
return page_is_valid;
});
// add a hidden field to each form to record which submit button
// was clicked so that it gets presented in the POST data
$("form").each(function() {
var $this = $(this);
var bid = "b_" + $this.attr("id") + "_clicked";
var b_clicked = '<input type="hidden" id="' + bid + '" name="' + bid + '">';
$(b_clicked).appendTo($this);
});
// Bind to the click event for all the matching 'b_form1_dt_remove' buttons to open a page as a modal dialog
$('[id*="b_form1_dt_remove"]').click( function() {
var qStr = fnEdit();
main_modal_page_open('/htdocs/pages/switching/vlan_per_port_modal.lsp' + qStr, 'Edit VLAN Port Membership', '750', '380', { btnPost : "Apply", btnClose : "Cancel" } );
});
// Bind to the click event for all the matching 'b_form1_dt_add' buttons to open a page as a modal dialog
$('[id*="b_form1_dt_add"]').click( function() {
var qStr = fnEditAll();
main_modal_page_open('/htdocs/pages/switching/vlan_per_port_modal.lsp' + qStr, 'Edit VLAN Port Membership', '750', '360', { btnPost : "Apply", btnClose : "Cancel" } );
});
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
iframe_auto_resize();
});
iframe_auto_resize();
$('form input[type="submit"]').click(function(e) {
var form_id = $(e.target).closest("form").attr("id");
var f_s = "b_"+form_id+"_submit";
var f_r = "b_"+form_id+"_refresh";
var f_click = $("#b_"+form_id+"_clicked").val();
if (((f_click == f_s) || (f_click == f_r)) && page_is_valid)
{
parent.progress_modal_open();
}
});
parent.progress_modal_handler(parent.ple.PAGE_LOADED);
focus_init("focus_top");
});
-->
</script>
</body>
</html>
+259
View File
@@ -0,0 +1,259 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright &copy; 2017-2022 Hewlett Packard Enterprise Development LP. -->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>VLAN Configuration</title>
<link rel="shortcut icon" href="/htdocs/login/favicon.ico?">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/jquery-ui-1.12.1.custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/css/jquery.dataTables_themeroller.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_datatables_custom.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_common_pages.css">
<link type="text/css" media="screen" rel="stylesheet" href="/htdocs/static/bt1707389424/css/tabs.css">
<!--[if ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7.css" type="text/css">
<![endif]-->
<!--[if gte ie 7]>
<link rel="stylesheet" href="/htdocs/static/bt1707389424/css/style_browser_fixups_ie7plus.css" type="text/css">
<![endif]-->
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_3_5_1/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/jquery_ui_1_12_1/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables.min.js"></script>
</head>
<body class="ui-state-default fp_jqtds_page_body fp_corner_bottom">
<a name="focus_top" id="focus_top"></a>
<div id="fp_div_page_title_bar" class="fp_jqtds_h1">
<div id="fp_div_page_title_text">VLAN Configuration</div>&nbsp;
<div id="fp_div_title_bar_tooltip">
<a class="fp_anchor_tooltip" href="/htdocs/lang/en_us/help/switching/help_vlan_status.lsp" target="_blank">
<img src="/htdocs/static/bt1707389424/images/icon_help_black24-helpText.png" title="Help" alt="Help" border="0">
</a>
</div><!-- fp_div_title_bar_tooltip -->
</div><!-- fp_div_page_title_bar -->
<div class="fp_page_container">
<form id="form1" name="form1" method="post" action="/htdocs/pages/switching/vlan_status.lsp">
<div class="fp_sub_container">
<div id="dynamic_dt1"></div>
</div> <!-- fp_sub_container -->
<div id="page_buttons" class="fp_button_row">
<input class="fp_button ui-button ui-widget ui-state-default fp_primary_button" type="submit" id="b_form1_refresh" name="b_form1_refresh" value="Refresh" onclick="jslib_b_pressed_g='refresh';">
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default fp_dt_button" type="button" id="b_form1_dt_add" name="b_form1_dt_add" value="Add" >
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default fp_dt_button" type="button" id="b_form1_dt_edit" name="b_form1_dt_edit" value="Edit" >
&nbsp;
<input class="fp_button ui-button ui-widget ui-state-default fp_dt_button" type="submit" id="b_form1_dt_remove" name="b_form1_dt_remove" value="Remove" onclick="jslib_b_pressed_g='dt_remove';">
</div> <!-- fp_button_row -->
</form> <!-- form1 -->
</div><!-- fp_page_container -->
<script type="text/javascript" language="JavaScript">
<!--
var jslib_msgs = parent.jslib_msgs_tbl;
-->
</script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/js/web-utils-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/plugins/jquery-plugins-combo.js"></script>
<script type="text/javascript" src="/htdocs/static/bt1707389424/jquery/datatables_1_9_4/jquery.dataTables-plugins.js"></script>
<script type="text/javascript" src="/htdocs/lang/en_us/culture/globalize.culture.en-US.20120606.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
var aDataSet = [
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_1" value="1" disabled="disabled"><label></label>', '1', 'default', 'Default']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_10" value="10" disabled="disabled"><label></label>', '10', 'VLAN0010', 'Static']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_20" value="20"><label></label>', '20', 'VLAN0020', 'Static']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_30" value="30"><label></label>', '30', 'VLAN0030', 'Static']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_40" value="40"><label></label>', '40', 'VLAN0040', 'Static']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_50" value="50"><label></label>', '50', 'VLAN0050', 'Static']
,
['<input type="checkbox" class="chkrow" name="chkrow[]" id="chkrow_60" value="60"><label></label>', '60', 'VLAN0060', 'Static']
];
var aColumns = [
{ "sTitle": '<input type="checkbox" class="chkall" name="chkall" id="chkall" value="chkall"><label></label>', "bSearchable": false, "bSortable": false, "sWidth": "2%" },
{ "sTitle": "VLAN ID", "sType": "natural-sort" },
{ "sTitle": "Name", "sType": "html" },
{ "sTitle": "Type", "sType": "html" }
];
// Edit button query string callback function
// This function name is specified as the 'fn' parameter on 'modal_button_attrib' for the 'edit' button
function fnEdit()
{
var selected = fp_dt_get_selected($("#sorttable1"));
var qString = '';
if (selected.length == 1)
{
qString = '?vlan=' + selected[0].cells[0].firstChild.value;
}
return qString;
}
var vlan_count = 7;
var vlan_max = 64;
// Add button query string callback function
// This function name is specified as the 'fn' parameter on 'modal_button_attrib' for the 'add' button
function fnAdd()
{
var qString = '';
qString = '?vlancount=' + vlan_count;
return qString;
}
$(document).ready( function ()
{
// Define datatable
$('#dynamic_dt1').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="sorttable1"><\/table>' );
fp_dt_create("#sorttable1", { aaData: aDataSet, aoColumns: aColumns, dt_btn: true, multi_select: true, rw: true });
if (vlan_count >= vlan_max)
{
$("#b_form1_dt_add").button("disable");
}
//Disable add button when we press the data table buttons when it reached to max vlans
$("#sorttable1_paginate,#sorttable1_length,#sorttable1_filter").click(function() {
if (vlan_count >= vlan_max)
{
$("#b_form1_dt_add").button("disable");
}
});
});
-->
</script>
<script type="text/javascript" language="JavaScript">
<!--
$(document).ready( function()
{
var page_is_valid = true;
// format all culture-specific elements using the current locale
culture_format(parent.culture);
var myNav = navigator.userAgent.toLowerCase();
var isIe = false;
if (myNav.indexOf('msie') != -1)
{
var myVer = parseInt(myNav.split('msie')[1]);
}
if ((isIe == true) && (myVer < 8)) {
$('input[type=radio],[type=checkbox]').live('click', function () {
this.blur();
this.focus();
});
}
$(':input').bind('keypress', function(e) {
var key = (window.event) ? window.event.keyCode : e.which; // IE vs. FF
var $this = $(this);
if ( ($this.is(':not(:button, :submit, :reset, textarea)')) ) {
return (key != 13);
}
});
$(".fp_button").button();
$(".fp_button_cancel").button();
$('form input[type="reset"]').click(function(e) {
if( $('#sorttable1').length ){
fp_dt_reset_handler("#sorttable1");
}
return jslib_form_reset(this.form);
});
$(":submit,:button").click(function(e) {
// remember which button was clicked last by storing into hidden field
var button = $(this).attr("id");
var form_id = $(e.target).closest("form").attr("id");
if (form_id)
{
$("#b_"+form_id+"_clicked").val(button);
}
page_is_valid = jslib_form_validate(document.forms[0]);
return page_is_valid;
});
// add a hidden field to each form to record which submit button
// was clicked so that it gets presented in the POST data
$("form").each(function() {
var $this = $(this);
var bid = "b_" + $this.attr("id") + "_clicked";
var b_clicked = '<input type="hidden" id="' + bid + '" name="' + bid + '">';
$(b_clicked).appendTo($this);
});
// Bind to the click event for all the matching 'b_form1_dt_add' buttons to open a page as a modal dialog
$('[id*="b_form1_dt_add"]').click( function() {
var qStr = fnAdd();
main_modal_page_open('/htdocs/pages/switching/vlan_status_modal.lsp' + qStr, 'Add VLAN', '580', '290', { btnPost : "Apply", btnClose : "Cancel" } );
});
// Bind to the click event for all the matching 'b_form1_dt_edit' buttons to open a page as a modal dialog
$('[id*="b_form1_dt_edit"]').click( function() {
var qStr = fnEdit();
main_modal_page_open('/htdocs/pages/switching/vlan_status_edit_modal.lsp' + qStr, 'Edit VLAN Configuration', '520', '240', { btnPost : "Apply", btnClose : "Cancel" } );
});
// Bind to the submit event for 'b_form1_dt_remove' to open a modal confirm dialog
$('#form1').submit( function(e) {
var pattern = /dt_remove/gi;
if (jslib_b_pressed_g.match(pattern)) {
e.preventDefault();
main_confirm_dialog_open('dt_remove', 'Are you sure you want to remove the selected row(s)?'); }
});
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
iframe_auto_resize();
});
iframe_auto_resize();
$('form input[type="submit"]').click(function(e) {
var form_id = $(e.target).closest("form").attr("id");
var f_s = "b_"+form_id+"_submit";
var f_r = "b_"+form_id+"_refresh";
var f_click = $("#b_"+form_id+"_clicked").val();
if (((f_click == f_s) || (f_click == f_r)) && page_is_valid)
{
parent.progress_modal_open();
}
});
parent.progress_modal_handler(parent.ple.PAGE_LOADED);
focus_init("focus_top");
});
-->
</script>
</body>
</html>
View File
+152
View File
@@ -0,0 +1,152 @@
"""Unit tests for the OfficeConnect HTTP client — no real device required."""
from unittest.mock import MagicMock, patch
import pytest
from napalm.base.exceptions import ConnectionClosedException, ConnectionException
from napalm_hpe_officeconnect.client import OfficeConnectClient
def make_response(status_code=200, text="", json_data=None):
resp = MagicMock()
resp.status_code = status_code
resp.text = text
if json_data is None:
resp.json.side_effect = ValueError("no json")
else:
resp.json.return_value = json_data
return resp
@pytest.fixture
def client():
with patch("napalm_hpe_officeconnect.client.requests.Session") as session_cls:
c = OfficeConnectClient("192.0.2.20", "admin", "secret")
c._session = session_cls.return_value
yield c
# ===========================================================================
# base_url
# ===========================================================================
def test_base_url_defaults_to_http():
"""These switches ship without a certificate, so HTTP is the default."""
c = OfficeConnectClient("192.0.2.20", "admin", "secret")
assert c.base_url == "http://192.0.2.20"
def test_base_url_honours_https_opt_in():
c = OfficeConnectClient("192.0.2.20", "admin", "secret", scheme="https")
assert c.base_url == "https://192.0.2.20"
def test_base_url_includes_non_default_port():
c = OfficeConnectClient("192.0.2.20", "admin", "secret", port=8080)
assert c.base_url == "http://192.0.2.20:8080"
# ===========================================================================
# login
# ===========================================================================
def test_login_posts_credentials_and_succeeds(client):
client._session.get.return_value = make_response(text="login page")
client._session.post.return_value = make_response(
json_data={"redirect": "/htdocs/pages/main/main.lsp", "error": ""}
)
client.login()
# The RID cookie is handed out by the login page, so it must be fetched first.
client._session.get.assert_called_once()
assert client._session.get.call_args[0][0].endswith("/htdocs/login/login.lsp")
(url,) = client._session.post.call_args[0]
assert url.endswith("/htdocs/login/login.lua")
assert client._session.post.call_args[1]["data"] == {
"username": "admin",
"password": "secret",
}
assert client.is_authenticated is True
def test_login_raises_with_device_message_on_bad_credentials(client):
client._session.get.return_value = make_response(text="login page")
client._session.post.return_value = make_response(
json_data={"redirect": "", "error": "Invalid username or password"}
)
with pytest.raises(ConnectionException, match="Invalid username or password"):
client.login()
assert client.is_authenticated is False
def test_login_raises_when_response_is_not_json(client):
"""A firmware that redirects instead of answering must not look like success."""
client._session.get.return_value = make_response(text="login page")
client._session.post.return_value = make_response(status_code=303, text="")
with pytest.raises(ConnectionException):
client.login()
assert client.is_authenticated is False
# ===========================================================================
# fetch
# ===========================================================================
def test_fetch_returns_page_text(client):
client._authenticated = True
client._session.get.return_value = make_response(text="<html>data</html>")
assert client.fetch("/htdocs/pages/base/dashboard.lsp") == "<html>data</html>"
def test_fetch_raises_when_session_expired(client):
"""An expired session answers 303 to the login page rather than 401."""
client._authenticated = True
client._session.get.return_value = make_response(status_code=303, text="")
with pytest.raises(ConnectionClosedException):
client.fetch("/htdocs/pages/base/dashboard.lsp")
def test_fetch_requires_login_first(client):
with pytest.raises(ConnectionException):
client.fetch("/htdocs/pages/base/dashboard.lsp")
# ===========================================================================
# logout — must be reliable, the session table is small
# ===========================================================================
def test_logout_releases_the_session(client):
client._authenticated = True
client._session.get.return_value = make_response(status_code=303)
client.logout()
assert client._session.get.call_args[0][0].endswith("/htdocs/pages/main/logout.lsp")
assert client.is_authenticated is False
def test_logout_swallows_errors(client):
"""close() runs logout on the failure path too; it must never mask the
original exception, and an unreachable switch is not a new problem."""
client._authenticated = True
client._session.get.side_effect = OSError("network gone")
client.logout() # must not raise
assert client.is_authenticated is False
def test_logout_is_a_noop_when_not_logged_in(client):
client.logout()
client._session.get.assert_not_called()
+196
View File
@@ -0,0 +1,196 @@
"""Unit tests for OfficeConnectDriver — fixture-driven, no real device."""
import pathlib
from unittest.mock import patch
import pytest
from napalm_hpe_officeconnect.officeconnect import OfficeConnectDriver
FIXTURES = pathlib.Path(__file__).parent.parent / "fixtures"
PAGE_FOR_PATH = {
OfficeConnectDriver.DASHBOARD: "base_dashboard",
OfficeConnectDriver.PORT_SUMMARY: "base_port_summary",
OfficeConnectDriver.MAC_TABLE: "base_mac_address_table",
OfficeConnectDriver.VLAN_STATUS: "switching_vlan_status",
}
def fake_fetch(path: str) -> str:
"""Serve a captured page for the requested path."""
if path.startswith("/htdocs/pages/switching/vlan_per_port.lsp"):
vlan = path.rsplit("=", 1)[-1]
name = f"switching_vlan_per_port_{vlan if vlan == '10' else '1'}"
else:
name = PAGE_FOR_PATH[path]
return (FIXTURES / f"{name}.html").read_text(encoding="utf-8")
@pytest.fixture
def driver():
with patch("napalm_hpe_officeconnect.officeconnect.OfficeConnectClient") as client_cls:
client = client_cls.return_value
client.fetch.side_effect = fake_fetch
client.is_authenticated = True
d = OfficeConnectDriver("192.0.2.20", "admin", "secret")
d._client = client
yield d
# ===========================================================================
# Fingerprinting contract — consumed by netOrk discovery without a connection
# ===========================================================================
def test_driver_identity():
assert OfficeConnectDriver.DRIVER_NAME == "hpe_officeconnect"
assert OfficeConnectDriver.VENDOR == "HPE"
def test_snmp_object_id_is_specific_enough_to_not_collide_with_procurve():
"""The ProCurve driver claims 1.3.6.1.4.1.11 — the bare HPE arc. This
driver must claim the longer OfficeConnect arc or the two compete."""
assert OfficeConnectDriver.SNMP_OBJECT_ID_PREFIX == "1.3.6.1.4.1.11.2.3.7.11"
assert "1.3.6.1.4.1.11.2.3.7.11.170".startswith(OfficeConnectDriver.SNMP_OBJECT_ID_PREFIX)
def test_http_fingerprint_requires_officeconnect():
mandatory = [r for r in OfficeConnectDriver.HTTP_FINGERPRINT if r.mandatory]
assert [r.pattern for r in mandatory] == ["officeconnect"]
def test_snmp_fingerprint_matches_real_sysdescr():
"""sysDescr as returned by a J9982A over SNMPv2c."""
sys_descr = (
"hpe officeconnect switch 1820 8g poe+ (65w) j9982a, pt.02.19, "
"linux 3.6.5-58b5074c, u-boot 2012.10-00116-g3ab515c (jul 30 2014 - 10:52:01)"
)
matched = [r.pattern for r in OfficeConnectDriver.SNMP_FINGERPRINT if r.pattern in sys_descr]
assert "officeconnect" in matched
assert "1820" in matched
def test_snmp_fingerprint_has_no_mandatory_rule():
"""HTTP already carries the hard requirement. A mandatory SNMP rule would
disqualify the driver for any device answering SNMP but not HTTP."""
assert not any(r.mandatory for r in OfficeConnectDriver.SNMP_FINGERPRINT)
# ===========================================================================
# Connection lifecycle
# ===========================================================================
def test_open_logs_in(driver):
driver.open()
driver._client.login.assert_called_once()
def test_close_logs_out(driver):
driver.close()
driver._client.logout.assert_called_once()
def test_is_alive_reflects_session_state(driver):
assert driver.is_alive() == {"is_alive": True}
# ===========================================================================
# get_facts
# ===========================================================================
def test_get_facts(driver):
facts = driver.get_facts()
assert facts["vendor"] == "HPE"
assert facts["hostname"] == "testswitch"
assert facts["serial_number"] == "CN0FIXTURE0"
assert facts["os_version"] == "PT.02.19"
assert facts["model"] == "HPE OfficeConnect Switch 1820 8G PoE+ (65W) J9982A"
assert facts["uptime"] == 67480
assert facts["interface_list"][:3] == ["1", "2", "3"]
assert "TRK1" in facts["interface_list"]
# ===========================================================================
# get_interfaces
# ===========================================================================
def test_get_interfaces_returns_ports_and_trunks(driver):
interfaces = driver.get_interfaces()
assert len(interfaces) == 12
assert set(interfaces) >= {"1", "8", "TRK1", "TRK4"}
def test_get_interfaces_link_state(driver):
interfaces = driver.get_interfaces()
assert interfaces["3"]["is_up"] is True
assert interfaces["1"]["is_up"] is False
# Admin state is independent of link state on this platform.
assert interfaces["1"]["is_enabled"] is True
def test_get_interfaces_speed_is_mbit(driver):
interfaces = driver.get_interfaces()
assert interfaces["3"]["speed"] == 1000.0
assert interfaces["6"]["speed"] == 100.0 # "100 Mbps Full Duplex"
assert interfaces["1"]["speed"] == 0.0 # link down — no speed reported
def test_get_interfaces_mtu(driver):
assert driver.get_interfaces()["1"]["mtu"] == 1518
# ===========================================================================
# get_vlans
# ===========================================================================
def test_get_vlans_lists_every_vlan(driver):
vlans = driver.get_vlans()
assert set(vlans) == {"1", "10", "20", "30", "40", "50", "60"}
assert vlans["1"]["name"] == "default"
assert vlans["10"]["name"] == "VLAN0010"
def test_get_vlans_membership_excludes_non_members(driver):
"""Participation is Untagged / Tagged / Excluded — only the first two
make an interface a member."""
vlans = driver.get_vlans()
assert vlans["10"]["interfaces"] == ["2", "3", "4", "8"]
def test_get_vlans_detail_splits_tagged_and_untagged(driver):
detail = driver.get_vlans_detail()
assert detail["1"]["untagged"] == ["1", "5", "7", "TRK1", "TRK2", "TRK3", "TRK4"]
assert detail["1"]["tagged"] == ["8"]
# ===========================================================================
# get_mac_address_table
# ===========================================================================
def test_get_mac_address_table(driver):
table = driver.get_mac_address_table()
assert len(table) == 17
first = table[0]
assert first["mac"] == "00:11:22:33:44:01"
assert first["interface"] == "7"
assert first["vlan"] == 1
assert first["static"] is False
assert first["active"] is True
# ===========================================================================
# Deliberate gaps — documented, not silently faked
# ===========================================================================
def test_get_interfaces_counters_is_not_implemented(driver):
"""port_summary_stats.lsp ships an empty dataset on PT.02.19; returning
zeros would look like real counters. See README."""
with pytest.raises(NotImplementedError):
driver.get_interfaces_counters()
+134
View File
@@ -0,0 +1,134 @@
"""Unit tests for the OfficeConnect HTML/JS parsers.
Fixtures are real pages captured from an HPE OfficeConnect 1820 8G PoE+
(J9982A, firmware PT.02.19), scrubbed of serial number, MAC addresses,
IP addresses and hostname.
"""
import pathlib
import pytest
from napalm_hpe_officeconnect import parsers
FIXTURES = pathlib.Path(__file__).parent.parent / "fixtures"
def fixture(name: str) -> str:
return (FIXTURES / f"{name}.html").read_text(encoding="utf-8")
# ===========================================================================
# extract_data_set — the DataTables payload every list page ships
# ===========================================================================
def test_extract_data_set_returns_one_row_per_port():
"""port_summary carries 8 physical ports plus 4 trunk interfaces."""
rows = parsers.extract_data_set(fixture("base_port_summary"))
assert len(rows) == 12
assert all(isinstance(r, list) for r in rows)
def test_extract_data_set_preserves_cell_values():
rows = parsers.extract_data_set(fixture("base_port_summary"))
# Columns: [checkbox, interface, description, admin, phy type, status, ...]
assert rows[0][1] == "1"
assert rows[0][3] == "Enabled"
assert rows[2][5] == "Link Up"
assert rows[2][7] == "1000 Mbps"
def test_extract_data_set_handles_rows_without_markup():
"""mac_address_table rows are plain values, no embedded checkbox cell."""
rows = parsers.extract_data_set(fixture("base_mac_address_table"))
assert len(rows) == 17
assert rows[0] == ["1", "00:11:22:33:44:01", "7", "7", "Learned"]
def test_extract_data_set_handles_empty_cells():
"""Counter columns are empty strings on a port that never linked up."""
rows = parsers.extract_data_set(fixture("base_port_summary_stats"))
assert rows[0] == ["1", "", "", "", "", "", "", "", ""]
def test_extract_data_set_returns_empty_list_when_absent():
assert parsers.extract_data_set("<html><body>nothing here</body></html>") == []
# ===========================================================================
# extract_column_titles — used to assert the firmware layout hasn't shifted
# ===========================================================================
def test_extract_column_titles():
titles = parsers.extract_column_titles(fixture("switching_vlan_status"))
assert titles == ["VLAN ID", "Name", "Type"]
def test_extract_column_titles_skips_markup_only_header():
"""The leading checkbox column has an <input> as its title, not text."""
titles = parsers.extract_column_titles(fixture("base_mac_address_table"))
assert titles == ["VLAN ID", "MAC Address", "Interface", "Interface Index", "Status"]
# ===========================================================================
# strip_markup — the checkbox cell must collapse to an empty string
# ===========================================================================
@pytest.mark.parametrize(
"raw,expected",
[
('<input type="checkbox" value="1"><label></label>', ""),
("plain value", "plain value"),
("&nbsp;spaced&amp;out ", "spaced&out"),
("", ""),
],
)
def test_strip_markup(raw, expected):
assert parsers.strip_markup(raw) == expected
# ===========================================================================
# parse_uptime
# ===========================================================================
@pytest.mark.parametrize(
"raw,expected",
[
("0 days, 18 hours, 44 mins, 40 secs", 67480),
("3 days, 0 hours, 0 mins, 0 secs", 259200),
("0 days, 0 hours, 0 mins, 1 secs", 1),
],
)
def test_parse_uptime(raw, expected):
assert parsers.parse_uptime(raw) == expected
def test_parse_uptime_returns_negative_one_when_unparseable():
"""NAPALM's convention for 'uptime unknown' is -1, not 0."""
assert parsers.parse_uptime("nonsense") == -1
# ===========================================================================
# parse_facts — dashboard.lsp
# ===========================================================================
def test_parse_facts():
facts = parsers.parse_facts(fixture("base_dashboard"))
assert facts["hostname"] == "testswitch"
assert facts["serial_number"] == "CN0FIXTURE0"
assert facts["os_version"] == "PT.02.19"
assert facts["model"] == "HPE OfficeConnect Switch 1820 8G PoE+ (65W) J9982A"
assert facts["uptime"] == 67480
assert facts["sys_object_id"] == "1.3.6.1.4.1.11.2.3.7.11.170"
def test_parse_facts_tolerates_missing_fields():
facts = parsers.parse_facts("<html><body></body></html>")
assert facts["hostname"] == ""
assert facts["serial_number"] == ""
assert facts["uptime"] == -1