testprotocols 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- testprotocols/__init__.py +217 -0
- testprotocols/aftr_gateway.py +22 -0
- testprotocols/appliance_nat.py +52 -0
- testprotocols/appliance_uplinks.py +32 -0
- testprotocols/appliance_vlans.py +50 -0
- testprotocols/arp_client.py +26 -0
- testprotocols/bgp.py +55 -0
- testprotocols/conntrack.py +147 -0
- testprotocols/content_filtering.py +47 -0
- testprotocols/device_lifecycle.py +49 -0
- testprotocols/device_management.py +50 -0
- testprotocols/devices/__init__.py +46 -0
- testprotocols/devices/base.py +40 -0
- testprotocols/devices/client.py +133 -0
- testprotocols/devices/cpe.py +66 -0
- testprotocols/devices/infra.py +62 -0
- testprotocols/devices/sdwan.py +97 -0
- testprotocols/devices/switch.py +115 -0
- testprotocols/devices/traffic.py +53 -0
- testprotocols/devices/voice.py +69 -0
- testprotocols/devices/wan.py +60 -0
- testprotocols/dhcp_client.py +30 -0
- testprotocols/dhcp_server.py +23 -0
- testprotocols/discovery.py +20 -0
- testprotocols/dns_client.py +23 -0
- testprotocols/file_transfer.py +22 -0
- testprotocols/firewall.py +121 -0
- testprotocols/firewall_zones.py +133 -0
- testprotocols/first_hop_security.py +52 -0
- testprotocols/gateway_redundancy.py +29 -0
- testprotocols/http_client.py +36 -0
- testprotocols/http_server.py +22 -0
- testprotocols/hw_console.py +48 -0
- testprotocols/infra_controller.py +28 -0
- testprotocols/interface_dhcp.py +30 -0
- testprotocols/ip_interface.py +62 -0
- testprotocols/ip_routing.py +57 -0
- testprotocols/iperf_client.py +47 -0
- testprotocols/iperf_generator.py +42 -0
- testprotocols/iperf_server.py +41 -0
- testprotocols/l3_firewall.py +74 -0
- testprotocols/l7_firewall.py +32 -0
- testprotocols/link_aggregation.py +24 -0
- testprotocols/mac_table.py +20 -0
- testprotocols/models/__init__.py +304 -0
- testprotocols/models/dhcp.py +28 -0
- testprotocols/models/firewall.py +197 -0
- testprotocols/models/impairment.py +18 -0
- testprotocols/models/l2_common.py +53 -0
- testprotocols/models/multicast.py +22 -0
- testprotocols/models/networking.py +50 -0
- testprotocols/models/packets.py +21 -0
- testprotocols/models/qoe.py +31 -0
- testprotocols/models/radius.py +63 -0
- testprotocols/models/sdwan_appliance.py +637 -0
- testprotocols/models/switch.py +297 -0
- testprotocols/models/switch_routing.py +122 -0
- testprotocols/models/tr069.py +35 -0
- testprotocols/models/traffic.py +29 -0
- testprotocols/models/wan_edge.py +116 -0
- testprotocols/models/wifi.py +183 -0
- testprotocols/multicast_client.py +20 -0
- testprotocols/nat.py +87 -0
- testprotocols/netem_controller.py +42 -0
- testprotocols/network_endpoint.py +32 -0
- testprotocols/network_probe.py +27 -0
- testprotocols/nmap_scanner.py +27 -0
- testprotocols/ntp_client.py +26 -0
- testprotocols/ntp_config.py +25 -0
- testprotocols/ospf.py +24 -0
- testprotocols/packet_filter.py +144 -0
- testprotocols/pcap_capture.py +39 -0
- testprotocols/pdu_controller.py +26 -0
- testprotocols/port_poe.py +25 -0
- testprotocols/port_security.py +25 -0
- testprotocols/port_status.py +23 -0
- testprotocols/py.typed +0 -0
- testprotocols/qoe_browser.py +62 -0
- testprotocols/radius_client.py +78 -0
- testprotocols/radius_server.py +130 -0
- testprotocols/routed_interfaces.py +29 -0
- testprotocols/router.py +53 -0
- testprotocols/routing_read.py +22 -0
- testprotocols/sdwan_policy_manager.py +64 -0
- testprotocols/sip_phone.py +230 -0
- testprotocols/sip_server.py +205 -0
- testprotocols/site_to_site_vpn.py +61 -0
- testprotocols/snmp_client.py +17 -0
- testprotocols/spanning_tree.py +37 -0
- testprotocols/static_routes.py +47 -0
- testprotocols/storm_control.py +24 -0
- testprotocols/streaming_server.py +32 -0
- testprotocols/switch_acl.py +29 -0
- testprotocols/switch_ports.py +28 -0
- testprotocols/switch_qos.py +33 -0
- testprotocols/switch_vlans.py +34 -0
- testprotocols/syslog_config.py +31 -0
- testprotocols/tftp_server.py +22 -0
- testprotocols/threat_prevention.py +60 -0
- testprotocols/tr069_client.py +47 -0
- testprotocols/tr069_server.py +151 -0
- testprotocols/traffic_shaping.py +54 -0
- testprotocols/upnp_client.py +37 -0
- testprotocols/vlan_client.py +22 -0
- testprotocols/wan_link_admin.py +34 -0
- testprotocols/wifi_bss.py +197 -0
- testprotocols/wifi_client.py +72 -0
- testprotocols/wifi_mesh.py +259 -0
- testprotocols/wifi_onboarding.py +105 -0
- testprotocols/wifi_radio.py +153 -0
- testprotocols/wifi_rf.py +78 -0
- testprotocols/wifi_stations.py +59 -0
- testprotocols/wifi_transitions.py +112 -0
- testprotocols-0.1.0.dist-info/METADATA +29 -0
- testprotocols-0.1.0.dist-info/RECORD +119 -0
- testprotocols-0.1.0.dist-info/WHEEL +5 -0
- testprotocols-0.1.0.dist-info/licenses/LICENSE +201 -0
- testprotocols-0.1.0.dist-info/licenses/NOTICE +11 -0
- testprotocols-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Device lifecycle template.
|
|
2
|
+
|
|
3
|
+
Defines the abstract contract for controlling a CPE device through its
|
|
4
|
+
boot lifecycle, including boot detection, factory reset, and finalization.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Protocol, runtime_checkable
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class DeviceLifecycle(Protocol):
|
|
14
|
+
"""Abstract contract for device lifecycle and boot management operations."""
|
|
15
|
+
|
|
16
|
+
def verify_cpe_is_booting(self) -> None:
|
|
17
|
+
"""Verify that the CPE device has entered the boot process."""
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
def wait_for_boot(self, timeout_s: int | None = None) -> None:
|
|
21
|
+
"""Block until the device has completed booting.
|
|
22
|
+
|
|
23
|
+
Implementations verify completion via a signal that
|
|
24
|
+
unambiguously postdates the most recent ``reset()`` — for
|
|
25
|
+
example, comparing an ACS-side ``last_boot_time`` against a
|
|
26
|
+
timestamp captured before the reset was issued. Raises
|
|
27
|
+
``TimeoutError`` if completion is not observed within
|
|
28
|
+
*timeout_s*; when *timeout_s* is ``None`` the implementation
|
|
29
|
+
applies its own default deadline.
|
|
30
|
+
"""
|
|
31
|
+
...
|
|
32
|
+
|
|
33
|
+
def factory_reset(self, method: str | None = None) -> bool:
|
|
34
|
+
"""Perform a factory reset using the given method. Return True on success."""
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
def reset(self, method: str | None = None) -> None:
|
|
38
|
+
"""Perform a reset (soft or hard) using the given method.
|
|
39
|
+
|
|
40
|
+
The implementation is expected to capture an internal baseline
|
|
41
|
+
(e.g. a wall-clock timestamp) so the matching ``wait_for_boot()``
|
|
42
|
+
call can confirm the device's post-reset boot is fresh, not a
|
|
43
|
+
stale signal from before the reset was issued.
|
|
44
|
+
"""
|
|
45
|
+
...
|
|
46
|
+
|
|
47
|
+
def finalize_boot(self) -> bool:
|
|
48
|
+
"""Finalize the boot sequence and return True if the device is ready."""
|
|
49
|
+
...
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Device management template.
|
|
2
|
+
|
|
3
|
+
Defines the abstract contract for querying runtime health and operational
|
|
4
|
+
state of a managed device, including uptime, memory, processes, and logs.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Any, Protocol, runtime_checkable
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class DeviceManagement(Protocol):
|
|
14
|
+
"""Abstract contract for device management and health monitoring operations."""
|
|
15
|
+
|
|
16
|
+
def get_seconds_uptime(self) -> float:
|
|
17
|
+
"""Return the device uptime in seconds."""
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
def is_online(self) -> bool:
|
|
21
|
+
"""Return True if the device is reachable and operational."""
|
|
22
|
+
...
|
|
23
|
+
|
|
24
|
+
def get_load_avg(self) -> float:
|
|
25
|
+
"""Return the current 1-minute load average of the device."""
|
|
26
|
+
...
|
|
27
|
+
|
|
28
|
+
def get_memory_utilization(self) -> dict[str, int]:
|
|
29
|
+
"""Return memory utilization in bytes, keyed by metric name."""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
def get_running_processes(self, ps_options: str = "-A") -> list[Any]:
|
|
33
|
+
"""Return the list of running processes using the given ps options."""
|
|
34
|
+
...
|
|
35
|
+
|
|
36
|
+
def get_board_logs(self, timeout: int = 300) -> str:
|
|
37
|
+
"""Return the board system log as a string, waiting up to *timeout* seconds."""
|
|
38
|
+
...
|
|
39
|
+
|
|
40
|
+
def read_event_logs(self) -> list[dict[str, Any]]:
|
|
41
|
+
"""Return structured event log entries from the device."""
|
|
42
|
+
...
|
|
43
|
+
|
|
44
|
+
def get_boottime_log(self) -> list[str]:
|
|
45
|
+
"""Return the boot-time log as a list of log lines."""
|
|
46
|
+
...
|
|
47
|
+
|
|
48
|
+
def get_file_content(self, fname: str, timeout: int = 30) -> str:
|
|
49
|
+
"""Return the content of the named file from the device filesystem."""
|
|
50
|
+
...
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Device archetype registry — maps inventory device_type strings to Protocols."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import importlib
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
_registry: dict[str, DeviceTypeSpec] = {}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class DeviceTypeSpec:
|
|
13
|
+
"""Registration record: inventory string -> @runtime_checkable Protocol class."""
|
|
14
|
+
|
|
15
|
+
name: str
|
|
16
|
+
protocol: type
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def register_device_type(name: str, protocol: type) -> DeviceTypeSpec:
|
|
20
|
+
"""Register *protocol* as the contract for inventory devices typed *name*.
|
|
21
|
+
|
|
22
|
+
Returns the spec; also stored in the module-level registry so
|
|
23
|
+
``get_device_type(name)`` can look it up by inventory string.
|
|
24
|
+
"""
|
|
25
|
+
spec = DeviceTypeSpec(name=name, protocol=protocol)
|
|
26
|
+
_registry[name] = spec
|
|
27
|
+
return spec
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_device_type(name: str) -> DeviceTypeSpec | None:
|
|
31
|
+
"""Return the spec for inventory *name*, or None if not registered."""
|
|
32
|
+
return _registry.get(name)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def all_device_types() -> dict[str, DeviceTypeSpec]:
|
|
36
|
+
"""Return a copy of the full registry."""
|
|
37
|
+
return dict(_registry)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# Auto-import all archetype modules to trigger registration as a side effect.
|
|
41
|
+
# ``importlib.import_module`` avoids the unused-import / out-of-order-import
|
|
42
|
+
# friction that direct ``from … import …`` statements would create here, and
|
|
43
|
+
# keeps the import section at the top of the file as PEP 8 prefers.
|
|
44
|
+
for _mod in ("client", "cpe", "infra", "sdwan", "switch", "traffic", "voice", "wan"):
|
|
45
|
+
importlib.import_module(f"testprotocols.devices.{_mod}")
|
|
46
|
+
del _mod
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Universal base Protocol shared by every device archetype."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Protocol, runtime_checkable
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@runtime_checkable
|
|
9
|
+
class BaseDeviceProtocol(Protocol):
|
|
10
|
+
"""Universal identity surface every test-device archetype carries.
|
|
11
|
+
|
|
12
|
+
Substrate- and framework-neutral: any concrete driver that exposes a
|
|
13
|
+
``device_name`` and a ``device_type`` satisfies this — palco's
|
|
14
|
+
``PalcoDevice`` (where both are ``@property``), a hypothetical
|
|
15
|
+
boardfarm ``BoardfarmDevice``, a pyATS ``Device`` wrapper, a
|
|
16
|
+
pure-Python simulator. Archetype Protocols in
|
|
17
|
+
``testprotocols.devices.*`` inherit from this so consumers
|
|
18
|
+
(operations, step defs) can read identity for log / assertion
|
|
19
|
+
messages without reaching into framework-specific base classes.
|
|
20
|
+
|
|
21
|
+
Deliberately scoped to the universal pair — name + type. Anything a
|
|
22
|
+
specific framework wants to expose (palco's ``config`` /
|
|
23
|
+
``get_interactive_consoles``, boardfarm's lifecycle hooks, etc.) is
|
|
24
|
+
the framework's own concern. Frameworks declare a connector Protocol
|
|
25
|
+
on their side that extends this base; testbed plugins compose
|
|
26
|
+
archetype + framework-connector into a combined Protocol where step
|
|
27
|
+
defs need both.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
# Read-only identity. Declared as properties (not settable variables) so that
|
|
31
|
+
# implementers exposing them as ``@property`` (VitroDevice, palco's
|
|
32
|
+
# PalcoDevice) statically satisfy the Protocol — a settable-variable member
|
|
33
|
+
# would reject a read-only property. A plain ``device_name: str`` attribute
|
|
34
|
+
# also satisfies a read-only-property member, so this is the more permissive,
|
|
35
|
+
# correct declaration for read-only identity.
|
|
36
|
+
@property
|
|
37
|
+
def device_name(self) -> str: ...
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def device_type(self) -> str: ...
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""Client device archetypes — wired LAN, wireless LAN, and QoE measurement endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Protocol, runtime_checkable
|
|
6
|
+
|
|
7
|
+
from testprotocols.arp_client import ArpClient
|
|
8
|
+
from testprotocols.devices import register_device_type
|
|
9
|
+
from testprotocols.devices.base import BaseDeviceProtocol
|
|
10
|
+
from testprotocols.dhcp_client import DhcpClient
|
|
11
|
+
from testprotocols.dns_client import DnsClient
|
|
12
|
+
from testprotocols.file_transfer import FileTransfer
|
|
13
|
+
from testprotocols.http_client import HttpClient
|
|
14
|
+
from testprotocols.http_server import HttpServer
|
|
15
|
+
from testprotocols.ip_interface import IpInterface
|
|
16
|
+
from testprotocols.ip_routing import IpRouting
|
|
17
|
+
from testprotocols.iperf_client import IperfClient
|
|
18
|
+
from testprotocols.iperf_server import IperfServer
|
|
19
|
+
from testprotocols.multicast_client import MulticastClient
|
|
20
|
+
from testprotocols.network_endpoint import NetworkEndpoint
|
|
21
|
+
from testprotocols.network_probe import NetworkProbe
|
|
22
|
+
from testprotocols.nmap_scanner import NmapScanner
|
|
23
|
+
from testprotocols.ntp_client import NtpClient
|
|
24
|
+
from testprotocols.packet_filter import PacketFilter
|
|
25
|
+
from testprotocols.pcap_capture import PcapCapture
|
|
26
|
+
from testprotocols.qoe_browser import QoeBrowser
|
|
27
|
+
from testprotocols.syslog_config import SyslogConfig
|
|
28
|
+
from testprotocols.upnp_client import UpnpClient
|
|
29
|
+
from testprotocols.vlan_client import VlanClient
|
|
30
|
+
from testprotocols.wifi_client import WifiClient
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@runtime_checkable
|
|
34
|
+
class LanClientDevice(BaseDeviceProtocol, Protocol):
|
|
35
|
+
"""Wired LAN client archetype — a host on the customer LAN segment.
|
|
36
|
+
|
|
37
|
+
Used as a traffic source/sink and protocol endpoint for testing CPE/router
|
|
38
|
+
behaviour from the subscriber side. Provides L3 (IP, routing, DHCP), the
|
|
39
|
+
common application-layer clients (HTTP/DNS/iperf/UPnP/multicast/NTP/file
|
|
40
|
+
transfer), packet capture, network scanning, host packet-filtering, and
|
|
41
|
+
L2 helpers (ARP, VLAN tagging).
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
ip_interface: IpInterface
|
|
45
|
+
ip_routing: IpRouting
|
|
46
|
+
dhcp_client: DhcpClient
|
|
47
|
+
http_client: HttpClient
|
|
48
|
+
http_server: HttpServer
|
|
49
|
+
dns_client: DnsClient
|
|
50
|
+
iperf_client: IperfClient
|
|
51
|
+
iperf_server: IperfServer
|
|
52
|
+
pcap: PcapCapture
|
|
53
|
+
upnp_client: UpnpClient
|
|
54
|
+
multicast_client: MulticastClient
|
|
55
|
+
ntp_client: NtpClient
|
|
56
|
+
nmap_scanner: NmapScanner
|
|
57
|
+
file_transfer: FileTransfer
|
|
58
|
+
packet_filter: PacketFilter
|
|
59
|
+
arp_client: ArpClient
|
|
60
|
+
vlan_client: VlanClient
|
|
61
|
+
network_probe: NetworkProbe
|
|
62
|
+
data_plane_endpoint: NetworkEndpoint
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@runtime_checkable
|
|
66
|
+
class WlanClientDevice(BaseDeviceProtocol, Protocol):
|
|
67
|
+
"""Wireless LAN client archetype — a Wi-Fi station for over-the-air testing.
|
|
68
|
+
|
|
69
|
+
Used to drive Wi-Fi association, roaming, and traffic scenarios against a
|
|
70
|
+
CPE / access point. Provides Wi-Fi client capabilities plus the L3 / app
|
|
71
|
+
surface needed to exercise data-plane behaviour once associated.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
wifi_client: WifiClient
|
|
75
|
+
ip_interface: IpInterface
|
|
76
|
+
ip_routing: IpRouting
|
|
77
|
+
dhcp_client: DhcpClient
|
|
78
|
+
http_client: HttpClient
|
|
79
|
+
iperf_client: IperfClient
|
|
80
|
+
iperf_server: IperfServer
|
|
81
|
+
pcap: PcapCapture
|
|
82
|
+
upnp_client: UpnpClient
|
|
83
|
+
multicast_client: MulticastClient
|
|
84
|
+
ntp_client: NtpClient
|
|
85
|
+
nmap_scanner: NmapScanner
|
|
86
|
+
file_transfer: FileTransfer
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@runtime_checkable
|
|
90
|
+
class QoeClientDevice(BaseDeviceProtocol, Protocol):
|
|
91
|
+
"""QoE (Quality of Experience) client archetype — browser-driven measurement endpoint.
|
|
92
|
+
|
|
93
|
+
Minimal client used to drive web-based QoE workloads (page load, video
|
|
94
|
+
streaming) against test servers and through CPE/SD-WAN under test.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
qoe_browser: QoeBrowser
|
|
98
|
+
ip_interface: IpInterface
|
|
99
|
+
dhcp_client: DhcpClient
|
|
100
|
+
syslog: SyslogConfig
|
|
101
|
+
"""Where this host forwards its syslog stream (management-plane telemetry).
|
|
102
|
+
|
|
103
|
+
Testbed-driven: the driver auto-applies the configured collector at
|
|
104
|
+
configure time; a testbed with no collector simply leaves it unset.
|
|
105
|
+
``QoeMeasurementClientDevice`` inherits this attribute.
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@runtime_checkable
|
|
110
|
+
class QoeMeasurementClientDevice(QoeClientDevice, Protocol):
|
|
111
|
+
"""QoE measurement client — a QoeClientDevice that is also a LAN-side
|
|
112
|
+
throughput source/sink, reachability prober, and capture point.
|
|
113
|
+
|
|
114
|
+
One host that drives browser QoE workloads AND acts as an iperf source/sink,
|
|
115
|
+
runs protocol-parameterised reachability probes (icmp / tcp / udp, with a
|
|
116
|
+
responder so the connectionless "blocked vs no-service" case is observable),
|
|
117
|
+
and captures traffic on the test segment. A strict superset of
|
|
118
|
+
``QoeClientDevice`` (qoe_browser + ip_interface + dhcp_client) — so any
|
|
119
|
+
consumer typed against ``QoeClientDevice`` also accepts this device — for
|
|
120
|
+
testbeds (e.g. a mobile LAN-side measurement VM) that fold all those roles
|
|
121
|
+
into one host rather than separate browser / iperf-generator devices.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
iperf_client: IperfClient
|
|
125
|
+
iperf_server: IperfServer
|
|
126
|
+
network_probe: NetworkProbe
|
|
127
|
+
pcap: PcapCapture
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
register_device_type("linux_lan_client", LanClientDevice)
|
|
131
|
+
register_device_type("linux_wlan_client", WlanClientDevice)
|
|
132
|
+
register_device_type("linux_qoe_client", QoeClientDevice)
|
|
133
|
+
register_device_type("linux_qoe_measurement_client", QoeMeasurementClientDevice)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""CPE (Customer Premises Equipment) device archetype."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Protocol, runtime_checkable
|
|
6
|
+
|
|
7
|
+
from testprotocols.conntrack import Conntrack
|
|
8
|
+
from testprotocols.device_lifecycle import DeviceLifecycle
|
|
9
|
+
from testprotocols.device_management import DeviceManagement
|
|
10
|
+
from testprotocols.devices import register_device_type
|
|
11
|
+
from testprotocols.devices.base import BaseDeviceProtocol
|
|
12
|
+
from testprotocols.firewall import Firewall
|
|
13
|
+
from testprotocols.firewall_zones import FirewallZones
|
|
14
|
+
from testprotocols.hw_console import HwConsole
|
|
15
|
+
from testprotocols.ip_interface import IpInterface
|
|
16
|
+
from testprotocols.ip_routing import IpRouting
|
|
17
|
+
from testprotocols.nat import Nat
|
|
18
|
+
from testprotocols.network_endpoint import NetworkEndpoint
|
|
19
|
+
from testprotocols.network_probe import NetworkProbe
|
|
20
|
+
from testprotocols.ntp_client import NtpClient
|
|
21
|
+
from testprotocols.tr069_client import Tr069Client
|
|
22
|
+
from testprotocols.wifi_bss import WifiBss
|
|
23
|
+
from testprotocols.wifi_onboarding import WifiOnboarding
|
|
24
|
+
from testprotocols.wifi_radio import WifiRadio
|
|
25
|
+
from testprotocols.wifi_rf import WifiRf
|
|
26
|
+
from testprotocols.wifi_stations import WifiStations
|
|
27
|
+
from testprotocols.wifi_transitions import WifiTransitions
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@runtime_checkable
|
|
31
|
+
class CpeDevice(BaseDeviceProtocol, Protocol):
|
|
32
|
+
"""CPE device archetype — black-box surface for residential / SMB gateways.
|
|
33
|
+
|
|
34
|
+
Aggregates the capability protocols any conforming CPE driver must provide:
|
|
35
|
+
TR-069 management, lifecycle, hardware console, the full Wi-Fi stack
|
|
36
|
+
(radio / BSS / stations / RF / transitions / onboarding), L3 (IP, routing,
|
|
37
|
+
NAT), the gateway-tier firewall (rule administration + port forwarding,
|
|
38
|
+
plus zone-based policy via firewall_zones), and NTP.
|
|
39
|
+
|
|
40
|
+
Plugin-local extensions (richer levels, additional capabilities) can
|
|
41
|
+
derive their own Protocol from this one.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
tr069_client: Tr069Client
|
|
45
|
+
device_management: DeviceManagement
|
|
46
|
+
device_lifecycle: DeviceLifecycle
|
|
47
|
+
hw_console: HwConsole
|
|
48
|
+
wifi_radio: WifiRadio
|
|
49
|
+
wifi_bss: WifiBss
|
|
50
|
+
wifi_stations: WifiStations
|
|
51
|
+
wifi_rf: WifiRf
|
|
52
|
+
wifi_transitions: WifiTransitions
|
|
53
|
+
wifi_onboarding: WifiOnboarding
|
|
54
|
+
ip_interface: IpInterface
|
|
55
|
+
ip_routing: IpRouting
|
|
56
|
+
firewall: Firewall
|
|
57
|
+
nat: Nat
|
|
58
|
+
conntrack: Conntrack
|
|
59
|
+
firewall_zones: FirewallZones
|
|
60
|
+
ntp_client: NtpClient
|
|
61
|
+
network_probe: NetworkProbe
|
|
62
|
+
wan_endpoint: NetworkEndpoint
|
|
63
|
+
lan_endpoint: NetworkEndpoint
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
register_device_type("linux_cpe", CpeDevice)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Infrastructure device archetypes — ACS, provisioner, TFTP server."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Protocol, runtime_checkable
|
|
6
|
+
|
|
7
|
+
from testprotocols.devices import register_device_type
|
|
8
|
+
from testprotocols.devices.base import BaseDeviceProtocol
|
|
9
|
+
from testprotocols.dhcp_server import DhcpServer
|
|
10
|
+
from testprotocols.file_transfer import FileTransfer
|
|
11
|
+
from testprotocols.packet_filter import PacketFilter
|
|
12
|
+
from testprotocols.pcap_capture import PcapCapture
|
|
13
|
+
from testprotocols.tftp_server import TftpServer
|
|
14
|
+
from testprotocols.tr069_server import Tr069Server
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@runtime_checkable
|
|
18
|
+
class AcsDevice(BaseDeviceProtocol, Protocol):
|
|
19
|
+
"""ACS (Auto-Configuration Server) archetype — TR-069 server-side counterpart to CPE.
|
|
20
|
+
|
|
21
|
+
Provides the TR-069 server protocol surface (CWMP plus ACS-side inventory
|
|
22
|
+
and per-CPE connection status). Includes packet capture / filter and file
|
|
23
|
+
transfer for diagnostic workflows. Drivers may implement the server
|
|
24
|
+
surface over any transport (CWMP NBI, REST, GUI scrape); the choice is a
|
|
25
|
+
driver-internal concern.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
tr069_server: Tr069Server
|
|
29
|
+
pcap: PcapCapture
|
|
30
|
+
file_transfer: FileTransfer
|
|
31
|
+
packet_filter: PacketFilter
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@runtime_checkable
|
|
35
|
+
class ProvisionerDevice(BaseDeviceProtocol, Protocol):
|
|
36
|
+
"""Provisioner archetype — DHCP-driven device provisioning service.
|
|
37
|
+
|
|
38
|
+
Hands out IP leases (with vendor-specific options) to CPEs and clients on
|
|
39
|
+
the test network. Includes packet capture / filter and file transfer for
|
|
40
|
+
inspecting provisioning exchanges.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
dhcp_server: DhcpServer
|
|
44
|
+
pcap: PcapCapture
|
|
45
|
+
file_transfer: FileTransfer
|
|
46
|
+
packet_filter: PacketFilter
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@runtime_checkable
|
|
50
|
+
class TftpDevice(BaseDeviceProtocol, Protocol):
|
|
51
|
+
"""TFTP server archetype — file source for firmware downloads / config fetches.
|
|
52
|
+
|
|
53
|
+
Minimal archetype used as a source for TR-069 ``Download`` operations and
|
|
54
|
+
similar boot-time fetch flows.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
tftp_server: TftpServer
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
register_device_type("linux_acs", AcsDevice)
|
|
61
|
+
register_device_type("linux_provisioner", ProvisionerDevice)
|
|
62
|
+
register_device_type("linux_tftp", TftpDevice)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""SD-WAN device archetypes."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Protocol, runtime_checkable
|
|
6
|
+
|
|
7
|
+
from testprotocols.appliance_nat import ApplianceNat
|
|
8
|
+
from testprotocols.appliance_uplinks import ApplianceUplinks
|
|
9
|
+
from testprotocols.appliance_vlans import ApplianceVlans
|
|
10
|
+
from testprotocols.bgp import Bgp
|
|
11
|
+
from testprotocols.content_filtering import ContentFiltering
|
|
12
|
+
from testprotocols.conntrack import Conntrack
|
|
13
|
+
from testprotocols.devices import register_device_type
|
|
14
|
+
from testprotocols.devices.base import BaseDeviceProtocol
|
|
15
|
+
from testprotocols.ip_interface import IpInterface
|
|
16
|
+
from testprotocols.l3_firewall import L3Firewall
|
|
17
|
+
from testprotocols.l7_firewall import L7Firewall
|
|
18
|
+
from testprotocols.nat import Nat
|
|
19
|
+
from testprotocols.pcap_capture import PcapCapture
|
|
20
|
+
from testprotocols.router import Router
|
|
21
|
+
from testprotocols.sdwan_policy_manager import SdwanPolicyManager
|
|
22
|
+
from testprotocols.site_to_site_vpn import SiteToSiteVpn
|
|
23
|
+
from testprotocols.static_routes import StaticRoutes
|
|
24
|
+
from testprotocols.syslog_config import SyslogConfig
|
|
25
|
+
from testprotocols.threat_prevention import ThreatPrevention
|
|
26
|
+
from testprotocols.traffic_shaping import TrafficShaping
|
|
27
|
+
from testprotocols.wan_link_admin import WanLinkAdmin
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@runtime_checkable
|
|
31
|
+
class SdwanRouterDevice(BaseDeviceProtocol, Protocol):
|
|
32
|
+
"""SD-WAN router archetype — branch / edge router with policy-based path selection.
|
|
33
|
+
|
|
34
|
+
Combines a generic routing read surface, WAN link administration (forced
|
|
35
|
+
link up/down — a host-substrate lever this Linux twin *can* exercise),
|
|
36
|
+
SD-WAN policy management (path / app steering), IP interface management,
|
|
37
|
+
packet capture, NAT, and connection tracking — the full set of L3 levers
|
|
38
|
+
a test needs to exercise SD-WAN behaviour end to end. Traffic impairment (netem) is on the
|
|
39
|
+
TrafficControllerDevice archetype — a separate device sitting between the
|
|
40
|
+
router and its WAN peers — not on the router itself; see
|
|
41
|
+
SPLITS.md for the rationale.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
routing: Router
|
|
45
|
+
wan_admin: WanLinkAdmin
|
|
46
|
+
static_routes: StaticRoutes
|
|
47
|
+
bgp: Bgp
|
|
48
|
+
sdwan_policy: SdwanPolicyManager
|
|
49
|
+
ip_interface: IpInterface
|
|
50
|
+
pcap: PcapCapture
|
|
51
|
+
nat: Nat
|
|
52
|
+
conntrack: Conntrack
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
register_device_type("linux_sdwan_router", SdwanRouterDevice)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@runtime_checkable
|
|
59
|
+
class SdwanApplianceDevice(BaseDeviceProtocol, Protocol):
|
|
60
|
+
"""Managed SD-WAN **appliance** archetype — vendor-neutral.
|
|
61
|
+
|
|
62
|
+
The capability surface a cloud-/controller-managed SD-WAN appliance exposes
|
|
63
|
+
through its management API — satisfiable by any vendor's driver. Distinct
|
|
64
|
+
from ``SdwanRouterDevice`` (the Linux digital twin, ``linux_sdwan_router``):
|
|
65
|
+
an appliance is driven by an API, not a shell, so the host substrate
|
|
66
|
+
capabilities — ``conntrack``, ``pcap``, ``ip_interface``, and the iptables
|
|
67
|
+
``nat`` — are deliberately **not** here; they remain on the twin. Packet
|
|
68
|
+
capture is the TrafficControllerDevice's job (see SPLITS.md), not the
|
|
69
|
+
appliance's.
|
|
70
|
+
|
|
71
|
+
Firewall is split by layer (``l3_firewall`` / ``l7_firewall``) and content
|
|
72
|
+
filtering is its own surface; NAT here is the appliance's 1:1 / 1:Many /
|
|
73
|
+
port-forwarding (``appliance_nat``), not the host iptables primitives.
|
|
74
|
+
Site-to-site VPN overlay participation — role, hubs, advertised subnets,
|
|
75
|
+
peer status — is the ``vpn`` surface; the overlay's firewall rules stay on
|
|
76
|
+
``l3_firewall``. Forced link-down (``wan_admin``) is likewise absent: an
|
|
77
|
+
API-managed appliance cannot admin-down its own uplink, so ``routing`` here
|
|
78
|
+
is the read-only surface and link administration stays on the twin.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
routing: Router
|
|
82
|
+
static_routes: StaticRoutes
|
|
83
|
+
bgp: Bgp
|
|
84
|
+
sdwan_policy: SdwanPolicyManager
|
|
85
|
+
vpn: SiteToSiteVpn
|
|
86
|
+
traffic_shaping: TrafficShaping
|
|
87
|
+
l3_firewall: L3Firewall
|
|
88
|
+
l7_firewall: L7Firewall
|
|
89
|
+
content_filtering: ContentFiltering
|
|
90
|
+
appliance_nat: ApplianceNat
|
|
91
|
+
security: ThreatPrevention
|
|
92
|
+
uplinks: ApplianceUplinks
|
|
93
|
+
lan: ApplianceVlans
|
|
94
|
+
syslog: SyslogConfig
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
register_device_type("sdwan_appliance", SdwanApplianceDevice)
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""Managed switch device archetypes — vendor-neutral.
|
|
2
|
+
|
|
3
|
+
``L2Switch`` is the managed access switch: the capability surface an
|
|
4
|
+
API/controller-managed switch exposes, satisfiable by any vendor's driver.
|
|
5
|
+
Host-substrate levers (conntrack, pcap, ip_interface, nat, packet_filter,
|
|
6
|
+
firewall_zones, wan_admin) are deliberately absent — a switch is not a Linux
|
|
7
|
+
host. See docs/architecture/l2-switch-protocol-design.md.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import Protocol, runtime_checkable
|
|
13
|
+
|
|
14
|
+
from testprotocols.bgp import Bgp
|
|
15
|
+
from testprotocols.devices import register_device_type
|
|
16
|
+
from testprotocols.devices.base import BaseDeviceProtocol
|
|
17
|
+
from testprotocols.discovery import Discovery
|
|
18
|
+
from testprotocols.first_hop_security import FirstHopSecurity
|
|
19
|
+
from testprotocols.gateway_redundancy import GatewayRedundancy
|
|
20
|
+
from testprotocols.interface_dhcp import InterfaceDhcp
|
|
21
|
+
from testprotocols.link_aggregation import LinkAggregation
|
|
22
|
+
from testprotocols.mac_table import MacTable
|
|
23
|
+
from testprotocols.ntp_config import NtpConfig
|
|
24
|
+
from testprotocols.ospf import Ospf
|
|
25
|
+
from testprotocols.port_poe import PortPoe
|
|
26
|
+
from testprotocols.port_security import PortSecurity
|
|
27
|
+
from testprotocols.port_status import PortStatus
|
|
28
|
+
from testprotocols.radius_client import RadiusClient
|
|
29
|
+
from testprotocols.routed_interfaces import RoutedInterfaces
|
|
30
|
+
from testprotocols.routing_read import RoutingRead
|
|
31
|
+
from testprotocols.spanning_tree import SpanningTree
|
|
32
|
+
from testprotocols.static_routes import StaticRoutes
|
|
33
|
+
from testprotocols.storm_control import StormControl
|
|
34
|
+
from testprotocols.switch_acl import SwitchAcl
|
|
35
|
+
from testprotocols.switch_ports import SwitchPorts
|
|
36
|
+
from testprotocols.switch_qos import SwitchQos
|
|
37
|
+
from testprotocols.switch_vlans import SwitchVlans
|
|
38
|
+
from testprotocols.syslog_config import SyslogConfig
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@runtime_checkable
|
|
42
|
+
class L2Switch(BaseDeviceProtocol, Protocol):
|
|
43
|
+
"""Managed access switch archetype — vendor-neutral.
|
|
44
|
+
|
|
45
|
+
Composes the shared L2 capability layer. ``radius`` and ``syslog`` are reused
|
|
46
|
+
as-is; ``first_hop_security`` and ``ntp`` are net-new baseline capabilities.
|
|
47
|
+
The sibling ``L3Switch`` (separate doc) composes this set plus an L3 layer as
|
|
48
|
+
a strict superset.
|
|
49
|
+
Host-substrate levers (conntrack, pcap, ip_interface, nat, packet_filter,
|
|
50
|
+
firewall_zones, wan_admin) are deliberately absent — a switch is API/controller-managed,
|
|
51
|
+
not a Linux host.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
switch_ports: SwitchPorts
|
|
55
|
+
switch_vlans: SwitchVlans
|
|
56
|
+
spanning_tree: SpanningTree
|
|
57
|
+
link_aggregation: LinkAggregation
|
|
58
|
+
port_poe: PortPoe
|
|
59
|
+
port_security: PortSecurity
|
|
60
|
+
radius: RadiusClient
|
|
61
|
+
first_hop_security: FirstHopSecurity
|
|
62
|
+
storm_control: StormControl
|
|
63
|
+
switch_acl: SwitchAcl
|
|
64
|
+
discovery: Discovery
|
|
65
|
+
mac_table: MacTable
|
|
66
|
+
port_status: PortStatus
|
|
67
|
+
switch_qos: SwitchQos
|
|
68
|
+
syslog: SyslogConfig
|
|
69
|
+
ntp: NtpConfig
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
register_device_type("managed_switch_l2", L2Switch)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@runtime_checkable
|
|
76
|
+
class L3Switch(L2Switch, Protocol):
|
|
77
|
+
"""Managed distribution switch — strict superset of L2Switch plus an L3 layer.
|
|
78
|
+
|
|
79
|
+
Inherits the full L2 capability layer via Protocol inheritance and adds
|
|
80
|
+
routed interfaces, static routes, RIB read, OSPF, per-interface DHCP, and
|
|
81
|
+
gateway redundancy. Scope is the default VRF (multi-VRF deferred, GAPS.md).
|
|
82
|
+
BGP is on the L3SwitchRouted tier (it fails the L3 majority bar).
|
|
83
|
+
Host-substrate levers (conntrack, pcap, ip_interface, nat, packet_filter,
|
|
84
|
+
firewall_zones, wan_admin) are deliberately absent — same exclusion as
|
|
85
|
+
``L2Switch``. The WAN-edge uplink-admin surface (``wan_admin`` / full
|
|
86
|
+
``Router`` write layer) is also excluded: an API-managed switch cannot
|
|
87
|
+
admin-down its own uplinks, so the RIB surface here is the read-only
|
|
88
|
+
``routing_read`` / ``RouteEntry`` view, not the router's write surface.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
routed_interfaces: RoutedInterfaces
|
|
92
|
+
static_routes: StaticRoutes
|
|
93
|
+
routing_read: RoutingRead
|
|
94
|
+
ospf: Ospf
|
|
95
|
+
interface_dhcp: InterfaceDhcp
|
|
96
|
+
gateway_redundancy: GatewayRedundancy
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
register_device_type("managed_switch_l3", L3Switch)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@runtime_checkable
|
|
103
|
+
class L3SwitchRouted(L3Switch, Protocol):
|
|
104
|
+
"""L3Switch plus BGP — the routed-distribution tier.
|
|
105
|
+
|
|
106
|
+
BGP is absent on the cloud design-target and fails the L3 majority bar, so it
|
|
107
|
+
is a separate tier rather than a mandatory L3Switch attribute. A driver for a
|
|
108
|
+
BGP-capable switch satisfies this; the registration isinstance-gate flags a
|
|
109
|
+
missing bgp at startup.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
bgp: Bgp
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
register_device_type("managed_switch_l3_routed", L3SwitchRouted)
|