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,217 @@
|
|
|
1
|
+
"""testprotocols — capability and device Protocols for telco resources under test."""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
|
|
5
|
+
from testprotocols.aftr_gateway import AftrGateway
|
|
6
|
+
from testprotocols.appliance_nat import ApplianceNat
|
|
7
|
+
from testprotocols.appliance_uplinks import ApplianceUplinks
|
|
8
|
+
from testprotocols.appliance_vlans import ApplianceVlans
|
|
9
|
+
from testprotocols.arp_client import ArpClient
|
|
10
|
+
from testprotocols.bgp import Bgp
|
|
11
|
+
from testprotocols.conntrack import Conntrack, ConntrackWhiteBox
|
|
12
|
+
from testprotocols.content_filtering import ContentFiltering
|
|
13
|
+
from testprotocols.device_lifecycle import DeviceLifecycle
|
|
14
|
+
from testprotocols.device_management import DeviceManagement
|
|
15
|
+
from testprotocols.devices.base import BaseDeviceProtocol
|
|
16
|
+
from testprotocols.devices.client import (
|
|
17
|
+
LanClientDevice,
|
|
18
|
+
QoeClientDevice,
|
|
19
|
+
WlanClientDevice,
|
|
20
|
+
)
|
|
21
|
+
from testprotocols.devices.cpe import CpeDevice
|
|
22
|
+
from testprotocols.devices.infra import (
|
|
23
|
+
AcsDevice,
|
|
24
|
+
ProvisionerDevice,
|
|
25
|
+
TftpDevice,
|
|
26
|
+
)
|
|
27
|
+
from testprotocols.devices.sdwan import SdwanApplianceDevice, SdwanRouterDevice
|
|
28
|
+
from testprotocols.devices.switch import L2Switch, L3Switch, L3SwitchRouted
|
|
29
|
+
from testprotocols.devices.traffic import (
|
|
30
|
+
IperfTrafficGeneratorDevice,
|
|
31
|
+
TrafficControllerDevice,
|
|
32
|
+
)
|
|
33
|
+
from testprotocols.devices.voice import (
|
|
34
|
+
SipPhoneDevice,
|
|
35
|
+
SipServerDevice,
|
|
36
|
+
)
|
|
37
|
+
from testprotocols.devices.wan import WanServerDevice
|
|
38
|
+
from testprotocols.dhcp_client import DhcpClient
|
|
39
|
+
from testprotocols.dhcp_server import DhcpServer
|
|
40
|
+
from testprotocols.discovery import Discovery
|
|
41
|
+
from testprotocols.dns_client import DnsClient
|
|
42
|
+
from testprotocols.file_transfer import FileTransfer
|
|
43
|
+
from testprotocols.firewall import Firewall, FirewallWhiteBox
|
|
44
|
+
from testprotocols.firewall_zones import FirewallZones
|
|
45
|
+
from testprotocols.first_hop_security import FirstHopSecurity
|
|
46
|
+
from testprotocols.gateway_redundancy import GatewayRedundancy
|
|
47
|
+
from testprotocols.http_client import HttpClient
|
|
48
|
+
from testprotocols.http_server import HttpServer
|
|
49
|
+
from testprotocols.hw_console import HwConsole
|
|
50
|
+
from testprotocols.infra_controller import InfraController
|
|
51
|
+
from testprotocols.interface_dhcp import InterfaceDhcp
|
|
52
|
+
from testprotocols.ip_interface import IpInterface
|
|
53
|
+
from testprotocols.ip_routing import IpRouting
|
|
54
|
+
from testprotocols.iperf_client import IperfClient
|
|
55
|
+
from testprotocols.iperf_generator import IperfGenerator
|
|
56
|
+
from testprotocols.iperf_server import IperfServer
|
|
57
|
+
from testprotocols.l3_firewall import L3Firewall
|
|
58
|
+
from testprotocols.l7_firewall import L7Firewall
|
|
59
|
+
from testprotocols.link_aggregation import LinkAggregation
|
|
60
|
+
from testprotocols.mac_table import MacTable
|
|
61
|
+
from testprotocols.multicast_client import MulticastClient
|
|
62
|
+
from testprotocols.nat import Nat
|
|
63
|
+
from testprotocols.netem_controller import NetemController
|
|
64
|
+
from testprotocols.nmap_scanner import NmapScanner
|
|
65
|
+
from testprotocols.ntp_client import NtpClient
|
|
66
|
+
from testprotocols.ntp_config import NtpConfig
|
|
67
|
+
from testprotocols.ospf import Ospf
|
|
68
|
+
from testprotocols.packet_filter import PacketFilter, PacketFilterWhiteBox
|
|
69
|
+
from testprotocols.pcap_capture import PcapCapture
|
|
70
|
+
from testprotocols.pdu_controller import PduController
|
|
71
|
+
from testprotocols.port_poe import PortPoe
|
|
72
|
+
from testprotocols.port_security import PortSecurity
|
|
73
|
+
from testprotocols.port_status import PortStatus
|
|
74
|
+
from testprotocols.qoe_browser import QoeBrowser
|
|
75
|
+
from testprotocols.radius_client import RadiusClient
|
|
76
|
+
from testprotocols.radius_server import RadiusServer
|
|
77
|
+
from testprotocols.routed_interfaces import RoutedInterfaces
|
|
78
|
+
from testprotocols.router import Router
|
|
79
|
+
from testprotocols.routing_read import RoutingRead
|
|
80
|
+
from testprotocols.sdwan_policy_manager import SdwanPolicyManager
|
|
81
|
+
from testprotocols.sip_phone import SipPhone
|
|
82
|
+
from testprotocols.sip_server import SipServer
|
|
83
|
+
from testprotocols.site_to_site_vpn import SiteToSiteVpn
|
|
84
|
+
from testprotocols.snmp_client import SnmpClient
|
|
85
|
+
from testprotocols.spanning_tree import SpanningTree
|
|
86
|
+
from testprotocols.static_routes import StaticRoutes
|
|
87
|
+
from testprotocols.storm_control import StormControl
|
|
88
|
+
from testprotocols.streaming_server import StreamingServer
|
|
89
|
+
from testprotocols.switch_acl import SwitchAcl
|
|
90
|
+
from testprotocols.switch_ports import SwitchPorts
|
|
91
|
+
from testprotocols.switch_qos import SwitchQos
|
|
92
|
+
from testprotocols.switch_vlans import SwitchVlans
|
|
93
|
+
from testprotocols.syslog_config import SyslogConfig
|
|
94
|
+
from testprotocols.tftp_server import TftpServer
|
|
95
|
+
from testprotocols.threat_prevention import ThreatPrevention
|
|
96
|
+
from testprotocols.tr069_client import Tr069Client
|
|
97
|
+
from testprotocols.tr069_server import Tr069Server
|
|
98
|
+
from testprotocols.traffic_shaping import TrafficShaping
|
|
99
|
+
from testprotocols.upnp_client import UpnpClient
|
|
100
|
+
from testprotocols.vlan_client import VlanClient
|
|
101
|
+
from testprotocols.wan_link_admin import WanLinkAdmin
|
|
102
|
+
from testprotocols.wifi_bss import WifiBss
|
|
103
|
+
from testprotocols.wifi_client import WifiClient
|
|
104
|
+
from testprotocols.wifi_mesh import WifiMesh, WifiMeshWhiteBox
|
|
105
|
+
from testprotocols.wifi_onboarding import WifiOnboarding
|
|
106
|
+
from testprotocols.wifi_radio import WifiRadio, WifiRadioWhiteBox
|
|
107
|
+
from testprotocols.wifi_rf import WifiRf
|
|
108
|
+
from testprotocols.wifi_stations import WifiStations
|
|
109
|
+
from testprotocols.wifi_transitions import WifiTransitions
|
|
110
|
+
|
|
111
|
+
__all__ = [
|
|
112
|
+
"AcsDevice",
|
|
113
|
+
"AftrGateway",
|
|
114
|
+
"ApplianceNat",
|
|
115
|
+
"ApplianceUplinks",
|
|
116
|
+
"ApplianceVlans",
|
|
117
|
+
"ArpClient",
|
|
118
|
+
"BaseDeviceProtocol",
|
|
119
|
+
"Bgp",
|
|
120
|
+
"Conntrack",
|
|
121
|
+
"ConntrackWhiteBox",
|
|
122
|
+
"ContentFiltering",
|
|
123
|
+
"CpeDevice",
|
|
124
|
+
"DeviceLifecycle",
|
|
125
|
+
"DeviceManagement",
|
|
126
|
+
"DhcpClient",
|
|
127
|
+
"DhcpServer",
|
|
128
|
+
"Discovery",
|
|
129
|
+
"DnsClient",
|
|
130
|
+
"FileTransfer",
|
|
131
|
+
"Firewall",
|
|
132
|
+
"FirewallWhiteBox",
|
|
133
|
+
"FirewallZones",
|
|
134
|
+
"FirstHopSecurity",
|
|
135
|
+
"GatewayRedundancy",
|
|
136
|
+
"HttpClient",
|
|
137
|
+
"HttpServer",
|
|
138
|
+
"HwConsole",
|
|
139
|
+
"InfraController",
|
|
140
|
+
"InterfaceDhcp",
|
|
141
|
+
"IpInterface",
|
|
142
|
+
"IpRouting",
|
|
143
|
+
"IperfClient",
|
|
144
|
+
"IperfGenerator",
|
|
145
|
+
"IperfServer",
|
|
146
|
+
"IperfTrafficGeneratorDevice",
|
|
147
|
+
"L2Switch",
|
|
148
|
+
"L3Firewall",
|
|
149
|
+
"L3Switch",
|
|
150
|
+
"L3SwitchRouted",
|
|
151
|
+
"L7Firewall",
|
|
152
|
+
"LanClientDevice",
|
|
153
|
+
"LinkAggregation",
|
|
154
|
+
"MacTable",
|
|
155
|
+
"MulticastClient",
|
|
156
|
+
"Nat",
|
|
157
|
+
"NetemController",
|
|
158
|
+
"NmapScanner",
|
|
159
|
+
"NtpClient",
|
|
160
|
+
"NtpConfig",
|
|
161
|
+
"Ospf",
|
|
162
|
+
"PacketFilter",
|
|
163
|
+
"PacketFilterWhiteBox",
|
|
164
|
+
"PcapCapture",
|
|
165
|
+
"PduController",
|
|
166
|
+
"PortPoe",
|
|
167
|
+
"PortSecurity",
|
|
168
|
+
"PortStatus",
|
|
169
|
+
"ProvisionerDevice",
|
|
170
|
+
"QoeBrowser",
|
|
171
|
+
"QoeClientDevice",
|
|
172
|
+
"RadiusClient",
|
|
173
|
+
"RadiusServer",
|
|
174
|
+
"RoutedInterfaces",
|
|
175
|
+
"Router",
|
|
176
|
+
"RoutingRead",
|
|
177
|
+
"SdwanApplianceDevice",
|
|
178
|
+
"SdwanPolicyManager",
|
|
179
|
+
"SdwanRouterDevice",
|
|
180
|
+
"SipPhone",
|
|
181
|
+
"SipPhoneDevice",
|
|
182
|
+
"SipServer",
|
|
183
|
+
"SipServerDevice",
|
|
184
|
+
"SiteToSiteVpn",
|
|
185
|
+
"SnmpClient",
|
|
186
|
+
"SpanningTree",
|
|
187
|
+
"StaticRoutes",
|
|
188
|
+
"StormControl",
|
|
189
|
+
"StreamingServer",
|
|
190
|
+
"SwitchAcl",
|
|
191
|
+
"SwitchPorts",
|
|
192
|
+
"SwitchQos",
|
|
193
|
+
"SwitchVlans",
|
|
194
|
+
"SyslogConfig",
|
|
195
|
+
"TftpDevice",
|
|
196
|
+
"TftpServer",
|
|
197
|
+
"ThreatPrevention",
|
|
198
|
+
"Tr069Client",
|
|
199
|
+
"Tr069Server",
|
|
200
|
+
"TrafficControllerDevice",
|
|
201
|
+
"TrafficShaping",
|
|
202
|
+
"UpnpClient",
|
|
203
|
+
"VlanClient",
|
|
204
|
+
"WanLinkAdmin",
|
|
205
|
+
"WanServerDevice",
|
|
206
|
+
"WifiBss",
|
|
207
|
+
"WifiClient",
|
|
208
|
+
"WifiMesh",
|
|
209
|
+
"WifiMeshWhiteBox",
|
|
210
|
+
"WifiOnboarding",
|
|
211
|
+
"WifiRadio",
|
|
212
|
+
"WifiRadioWhiteBox",
|
|
213
|
+
"WifiRf",
|
|
214
|
+
"WifiStations",
|
|
215
|
+
"WifiTransitions",
|
|
216
|
+
"WlanClientDevice",
|
|
217
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""AFTR / Gateway template.
|
|
2
|
+
|
|
3
|
+
Defines the abstract contract for Address Family Transition Router (AFTR)
|
|
4
|
+
gateway operations used in DS-Lite deployments.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Protocol, runtime_checkable
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class AftrGateway(Protocol):
|
|
14
|
+
"""Abstract contract for AFTR gateway operations."""
|
|
15
|
+
|
|
16
|
+
def configure_aftr(self) -> None:
|
|
17
|
+
"""Apply the AFTR configuration on the gateway."""
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
def restart_aftr_process(self) -> None:
|
|
21
|
+
"""Restart the AFTR process on the gateway."""
|
|
22
|
+
...
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""NAT template — managed SD-WAN appliance edition.
|
|
2
|
+
|
|
3
|
+
Defines the abstract contract for an appliance's NAT surfaces: 1:1 NAT, 1:Many
|
|
4
|
+
(PAT), and port-forwarding (DNAT). Each is an ordered list read and replaced as
|
|
5
|
+
a whole — the appliance-native shape, distinct from the host-tier ``nat.Nat``
|
|
6
|
+
(iptables SNAT/DNAT primitives, add/remove by name) used by the Linux digital
|
|
7
|
+
twin.
|
|
8
|
+
|
|
9
|
+
In scope: read/replace the 1:1, 1:Many, and port-forwarding rule lists.
|
|
10
|
+
|
|
11
|
+
Out of scope: low-level iptables NAT primitives (see ``nat``), firewall rules
|
|
12
|
+
(see ``l3_firewall`` / ``l7_firewall``).
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from typing import Protocol, runtime_checkable
|
|
18
|
+
|
|
19
|
+
from testprotocols.models.sdwan_appliance import (
|
|
20
|
+
OneToManyNatRule,
|
|
21
|
+
OneToOneNatRule,
|
|
22
|
+
PortForwardRule,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@runtime_checkable
|
|
27
|
+
class ApplianceNat(Protocol):
|
|
28
|
+
"""Abstract contract for an appliance's NAT rule sets."""
|
|
29
|
+
|
|
30
|
+
def set_one_to_one_rules(self, rules: list[OneToOneNatRule]) -> None:
|
|
31
|
+
"""Replace the 1:1 NAT mapping list with *rules*."""
|
|
32
|
+
...
|
|
33
|
+
|
|
34
|
+
def get_one_to_one_rules(self) -> list[OneToOneNatRule]:
|
|
35
|
+
"""Return the 1:1 NAT mappings."""
|
|
36
|
+
...
|
|
37
|
+
|
|
38
|
+
def set_one_to_many_rules(self, rules: list[OneToManyNatRule]) -> None:
|
|
39
|
+
"""Replace the 1:Many (PAT) mapping list with *rules*."""
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
def get_one_to_many_rules(self) -> list[OneToManyNatRule]:
|
|
43
|
+
"""Return the 1:Many (PAT) mappings."""
|
|
44
|
+
...
|
|
45
|
+
|
|
46
|
+
def set_port_forwarding_rules(self, rules: list[PortForwardRule]) -> None:
|
|
47
|
+
"""Replace the port-forwarding rule list with *rules*."""
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
def get_port_forwarding_rules(self) -> list[PortForwardRule]:
|
|
51
|
+
"""Return the port-forwarding rules."""
|
|
52
|
+
...
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""WAN uplink template — managed SD-WAN appliance.
|
|
2
|
+
|
|
3
|
+
Defines the abstract contract for observing an appliance's WAN uplinks: their
|
|
4
|
+
operational state and addressing. Read-only — uplink *configuration* (static vs
|
|
5
|
+
DHCP, PPPoE, etc.) is a separate concern not yet modelled (add on evidence).
|
|
6
|
+
|
|
7
|
+
This replaces, for a managed appliance, the Linux-host ``ip_interface`` surface
|
|
8
|
+
(per-interface ``ip addr``/``link``/``mtu``/``mac``) which a cloud-managed
|
|
9
|
+
appliance does not expose.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from typing import Protocol, runtime_checkable
|
|
15
|
+
|
|
16
|
+
from testprotocols.models.sdwan_appliance import UplinkStatus
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@runtime_checkable
|
|
20
|
+
class ApplianceUplinks(Protocol):
|
|
21
|
+
"""Abstract contract for observing an appliance's WAN uplinks."""
|
|
22
|
+
|
|
23
|
+
def get_uplinks(self) -> list[UplinkStatus]:
|
|
24
|
+
"""Return the status of every WAN uplink."""
|
|
25
|
+
...
|
|
26
|
+
|
|
27
|
+
def get_uplink(self, name: str) -> UplinkStatus:
|
|
28
|
+
"""Return the status of the named uplink (e.g. ``"wan1"``).
|
|
29
|
+
|
|
30
|
+
Raises KeyError if no uplink with that name exists.
|
|
31
|
+
"""
|
|
32
|
+
...
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""LAN VLAN + DHCP template — managed SD-WAN appliance.
|
|
2
|
+
|
|
3
|
+
Defines the abstract contract for a managed appliance's LAN side: per-VLAN
|
|
4
|
+
subnet/addressing and DHCP configuration, plus observed DHCP leases. This is the
|
|
5
|
+
appliance counterpart to a Linux host's interface + DHCP-server surfaces — an
|
|
6
|
+
appliance configures DHCP per VLAN, not via a host daemon.
|
|
7
|
+
|
|
8
|
+
In scope: list/get/set VLAN configuration (incl. per-VLAN DHCP), and read DHCP
|
|
9
|
+
leases.
|
|
10
|
+
|
|
11
|
+
Out of scope: WAN uplink status (see ``appliance_uplinks``), L3 firewall
|
|
12
|
+
(see ``l3_firewall``), and host-style per-interface config (see ``ip_interface``).
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from typing import Protocol, runtime_checkable
|
|
18
|
+
|
|
19
|
+
from testprotocols.models.sdwan_appliance import DhcpLease, VlanConfig
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@runtime_checkable
|
|
23
|
+
class ApplianceVlans(Protocol):
|
|
24
|
+
"""Abstract contract for an appliance's LAN VLANs and DHCP."""
|
|
25
|
+
|
|
26
|
+
def list_vlans(self) -> list[VlanConfig]:
|
|
27
|
+
"""Return every configured LAN VLAN."""
|
|
28
|
+
...
|
|
29
|
+
|
|
30
|
+
def get_vlan(self, vlan_id: int) -> VlanConfig:
|
|
31
|
+
"""Return the VLAN with *vlan_id*.
|
|
32
|
+
|
|
33
|
+
Raises KeyError if no VLAN with that id exists.
|
|
34
|
+
"""
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
def set_vlan(self, config: VlanConfig) -> None:
|
|
38
|
+
"""Create or replace the VLAN identified by ``config.vlan_id``."""
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
def get_dhcp_leases(self, vlan_id: int | None = None) -> list[DhcpLease]:
|
|
42
|
+
"""Return current DHCP leases, optionally filtered to one *vlan_id*.
|
|
43
|
+
|
|
44
|
+
Best-effort read: several management planes publish no true lease
|
|
45
|
+
table, so a driver may approximate from observed-client visibility
|
|
46
|
+
(no expiry / binding state) or raise unsupported-capability. Tests
|
|
47
|
+
should treat the result as observational evidence, not an exact
|
|
48
|
+
lease-table assertion.
|
|
49
|
+
"""
|
|
50
|
+
...
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""ARP / Client template.
|
|
2
|
+
|
|
3
|
+
Defines the abstract contract for ARP client operations including cache
|
|
4
|
+
management and table inspection.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Protocol, runtime_checkable
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class ArpClient(Protocol):
|
|
14
|
+
"""Abstract contract for ARP client operations."""
|
|
15
|
+
|
|
16
|
+
def flush_arp_cache(self) -> None:
|
|
17
|
+
"""Flush all entries from the ARP cache."""
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
def get_arp_table(self) -> str:
|
|
21
|
+
"""Return the current ARP table as a string."""
|
|
22
|
+
...
|
|
23
|
+
|
|
24
|
+
def delete_arp_table_entry(self, ip: str, intf: str) -> None:
|
|
25
|
+
"""Delete the ARP table entry for *ip* on interface *intf*."""
|
|
26
|
+
...
|
testprotocols/bgp.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""BGP template — WAN edge (twin and managed appliance).
|
|
2
|
+
|
|
3
|
+
Defines the abstract contract for a WAN edge's BGP: whole-replace
|
|
4
|
+
configuration (local AS + neighbors + advertised networks) plus operational
|
|
5
|
+
reads of neighbor session state and learned prefixes.
|
|
6
|
+
|
|
7
|
+
The config/read split is deliberate and per-method: configuration write and
|
|
8
|
+
read-back are universal across the reviewed management planes, while the
|
|
9
|
+
two *operational* reads are not — a product without a published BGP state
|
|
10
|
+
read raises unsupported-capability on those methods rather than
|
|
11
|
+
approximating.
|
|
12
|
+
|
|
13
|
+
In scope: BGP process configuration (whole-replace, idempotent), neighbor
|
|
14
|
+
session status, learned-prefix read.
|
|
15
|
+
|
|
16
|
+
Out of scope: RIB reads (see ``router``), static routes (see
|
|
17
|
+
``static_routes``), route maps / filters / per-neighbor policy (grow on
|
|
18
|
+
evidence), and other dynamic routing protocols (no driving test).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from typing import Protocol, runtime_checkable
|
|
24
|
+
|
|
25
|
+
from testprotocols.models.sdwan_appliance import BgpConfig, BgpPeerStatus
|
|
26
|
+
from testprotocols.models.wan_edge import RouteEntry
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@runtime_checkable
|
|
30
|
+
class Bgp(Protocol):
|
|
31
|
+
"""Abstract contract for a WAN edge's BGP configuration and state."""
|
|
32
|
+
|
|
33
|
+
def set_bgp_config(self, config: BgpConfig) -> None:
|
|
34
|
+
"""Replace the BGP configuration with *config* (idempotent)."""
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
def get_bgp_config(self) -> BgpConfig:
|
|
38
|
+
"""Return the current BGP configuration (config read-back)."""
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
def get_bgp_neighbors(self) -> list[BgpPeerStatus]:
|
|
42
|
+
"""Return the operational status of every configured neighbor.
|
|
43
|
+
|
|
44
|
+
Operational read — products without a published BGP state read
|
|
45
|
+
raise unsupported-capability rather than approximating.
|
|
46
|
+
"""
|
|
47
|
+
...
|
|
48
|
+
|
|
49
|
+
def get_learned_routes(self) -> list[RouteEntry]:
|
|
50
|
+
"""Return BGP-learned prefixes (operational read; same convention).
|
|
51
|
+
|
|
52
|
+
``gateway`` carries the peer next-hop; ``interface`` may be empty
|
|
53
|
+
when not reported.
|
|
54
|
+
"""
|
|
55
|
+
...
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""Firewall / Conntrack template.
|
|
2
|
+
|
|
3
|
+
Defines the abstract contract for inspecting and administering
|
|
4
|
+
connection-tracking state on a stateful device. Read-mostly; the only
|
|
5
|
+
write operations are explicit flushes (test-scenario reset), per-flow
|
|
6
|
+
drop, and table-size limit configuration.
|
|
7
|
+
|
|
8
|
+
In scope: aggregate stats, per-flow listing / lookup / drop, full-table
|
|
9
|
+
flush, table-size limit configuration.
|
|
10
|
+
|
|
11
|
+
Out of scope: rule installation (see ``packet_filter`` / ``firewall``
|
|
12
|
+
and ``nat``), helper-module loading (driver-internal concern), and
|
|
13
|
+
per-flow accounting deltas over time (operations layer can subtract
|
|
14
|
+
two snapshots).
|
|
15
|
+
|
|
16
|
+
Devices that do not track connections (e.g. stateless bridges) should
|
|
17
|
+
not compose this template.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
from typing import Protocol, runtime_checkable
|
|
23
|
+
|
|
24
|
+
from testprotocols.models.firewall import Connection, ConntrackStats
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@runtime_checkable
|
|
28
|
+
class Conntrack(Protocol):
|
|
29
|
+
"""Abstract contract for connection-tracking observability and admin."""
|
|
30
|
+
|
|
31
|
+
# --- Aggregate stats ---
|
|
32
|
+
|
|
33
|
+
def get_stats(self) -> ConntrackStats:
|
|
34
|
+
"""Return current conntrack table aggregate counters."""
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
# --- Per-flow inspection ---
|
|
38
|
+
|
|
39
|
+
def list_connections(
|
|
40
|
+
self,
|
|
41
|
+
*,
|
|
42
|
+
protocol: str | None = None,
|
|
43
|
+
src_ip: str | None = None,
|
|
44
|
+
dst_ip: str | None = None,
|
|
45
|
+
dst_port: int | None = None,
|
|
46
|
+
state: str | None = None,
|
|
47
|
+
) -> list[Connection]:
|
|
48
|
+
"""Return tracked flows, optionally filtered.
|
|
49
|
+
|
|
50
|
+
Filters compose with AND. *protocol*, when set, must be one of
|
|
51
|
+
``"tcp"``, ``"udp"``, ``"icmp"`` — raises ValueError otherwise.
|
|
52
|
+
Empty list when no flow matches.
|
|
53
|
+
"""
|
|
54
|
+
...
|
|
55
|
+
|
|
56
|
+
def count_connections(
|
|
57
|
+
self,
|
|
58
|
+
*,
|
|
59
|
+
protocol: str | None = None,
|
|
60
|
+
state: str | None = None,
|
|
61
|
+
) -> int:
|
|
62
|
+
"""Return the number of tracked flows matching the optional filters.
|
|
63
|
+
|
|
64
|
+
*protocol*, when set, must be one of ``"tcp"``, ``"udp"``,
|
|
65
|
+
``"icmp"`` — raises ValueError otherwise. Cheaper than
|
|
66
|
+
``len(list_connections(...))`` on drivers that can ask the
|
|
67
|
+
kernel directly.
|
|
68
|
+
"""
|
|
69
|
+
...
|
|
70
|
+
|
|
71
|
+
def get_connection(
|
|
72
|
+
self,
|
|
73
|
+
protocol: str,
|
|
74
|
+
src_ip: str,
|
|
75
|
+
dst_ip: str,
|
|
76
|
+
src_port: int | None,
|
|
77
|
+
dst_port: int | None,
|
|
78
|
+
) -> Connection:
|
|
79
|
+
"""Return the tracked flow exactly matching the supplied 5-tuple.
|
|
80
|
+
|
|
81
|
+
*src_port* / *dst_port* are ``None`` for ICMP.
|
|
82
|
+
|
|
83
|
+
Raises KeyError if no flow matches.
|
|
84
|
+
"""
|
|
85
|
+
...
|
|
86
|
+
|
|
87
|
+
# --- Per-flow administration ---
|
|
88
|
+
|
|
89
|
+
def drop_connection(
|
|
90
|
+
self,
|
|
91
|
+
protocol: str,
|
|
92
|
+
src_ip: str,
|
|
93
|
+
dst_ip: str,
|
|
94
|
+
src_port: int | None,
|
|
95
|
+
dst_port: int | None,
|
|
96
|
+
) -> None:
|
|
97
|
+
"""Drop the tracked flow exactly matching the supplied 5-tuple.
|
|
98
|
+
|
|
99
|
+
*src_port* / *dst_port* are ``None`` for ICMP.
|
|
100
|
+
|
|
101
|
+
Raises KeyError if no flow matches.
|
|
102
|
+
"""
|
|
103
|
+
...
|
|
104
|
+
|
|
105
|
+
def flush_connections(self) -> None:
|
|
106
|
+
"""Remove every tracked flow from the conntrack table."""
|
|
107
|
+
...
|
|
108
|
+
|
|
109
|
+
# --- Table size limit ---
|
|
110
|
+
|
|
111
|
+
def set_max_connections(self, max_connections: int) -> None:
|
|
112
|
+
"""Set the conntrack table size limit.
|
|
113
|
+
|
|
114
|
+
Raises ValueError if *max_connections* < 1.
|
|
115
|
+
Drivers that do not expose a configurable limit raise
|
|
116
|
+
NotImplementedError.
|
|
117
|
+
"""
|
|
118
|
+
...
|
|
119
|
+
|
|
120
|
+
def get_max_connections(self) -> int:
|
|
121
|
+
"""Return the current conntrack table size limit."""
|
|
122
|
+
...
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@runtime_checkable
|
|
126
|
+
class ConntrackWhiteBox(Conntrack, Protocol):
|
|
127
|
+
"""White-box extension of Conntrack for raw kernel-table introspection.
|
|
128
|
+
|
|
129
|
+
Linux drivers that can shell into the box satisfy this extension by
|
|
130
|
+
capturing ``conntrack -L`` (the netfilter conntrack utility) output.
|
|
131
|
+
Vendor-RTOS or locked-down devices typically satisfy only the base
|
|
132
|
+
``Conntrack`` Protocol; tests requiring raw connection-tuple
|
|
133
|
+
verification should pin against ``ConntrackWhiteBox`` and accept
|
|
134
|
+
the collection-skip on drivers that don't satisfy it (per the
|
|
135
|
+
``@white_box`` scenario tag rule).
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
def get_raw_conntrack_dump(self) -> str:
|
|
139
|
+
"""Return the raw ``conntrack -L`` output for the current namespace.
|
|
140
|
+
|
|
141
|
+
Format is the standard ``conntrack -L`` serialisation (one line per
|
|
142
|
+
flow, with proto / src / dst / sport / dport / state / mark fields).
|
|
143
|
+
Tests parse this to verify flow tuples landed at the kernel level
|
|
144
|
+
rather than only in the driver's intermediate state — useful for
|
|
145
|
+
debugging NAT-translation discrepancies and stuck-flow diagnostics.
|
|
146
|
+
"""
|
|
147
|
+
...
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Content-filtering template — URL / category blocking for a managed appliance.
|
|
2
|
+
|
|
3
|
+
Defines the abstract contract for an SD-WAN appliance's web content filter:
|
|
4
|
+
blocking by normalized content category and by explicit allow/block URL
|
|
5
|
+
patterns.
|
|
6
|
+
|
|
7
|
+
Categories are the normalized ``ContentCategory`` taxonomy owned by commons; the
|
|
8
|
+
driver maps each to its product's category id. URL patterns are free strings
|
|
9
|
+
(host / glob patterns), passed through to the appliance.
|
|
10
|
+
|
|
11
|
+
In scope: the blocked-category set and the allow / block URL-pattern lists.
|
|
12
|
+
|
|
13
|
+
Out of scope: application-aware (L7) rules (see ``l7_firewall``) and L3 5-tuple
|
|
14
|
+
filtering (see ``l3_firewall``).
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import Protocol, runtime_checkable
|
|
20
|
+
|
|
21
|
+
from testprotocols.models.sdwan_appliance import ContentCategory
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@runtime_checkable
|
|
25
|
+
class ContentFiltering(Protocol):
|
|
26
|
+
"""Abstract contract for an appliance's web content filter."""
|
|
27
|
+
|
|
28
|
+
def set_blocked_categories(self, categories: list[ContentCategory]) -> None:
|
|
29
|
+
"""Replace the set of blocked content categories with *categories*."""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
def get_blocked_categories(self) -> list[ContentCategory]:
|
|
33
|
+
"""Return the currently blocked content categories."""
|
|
34
|
+
...
|
|
35
|
+
|
|
36
|
+
def set_url_rules(self, allowed: list[str], blocked: list[str]) -> None:
|
|
37
|
+
"""Replace the explicit allow / block URL-pattern lists.
|
|
38
|
+
|
|
39
|
+
*allowed* takes precedence over both *blocked* and category blocks, per
|
|
40
|
+
the usual content-filter precedence; the driver maps that intent to its
|
|
41
|
+
product's allow/deny-list semantics.
|
|
42
|
+
"""
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
def get_url_rules(self) -> tuple[list[str], list[str]]:
|
|
46
|
+
"""Return ``(allowed, blocked)`` URL-pattern lists."""
|
|
47
|
+
...
|