Refactor Keenetic model to utilize centralized UTF-8 decoding utility
- Removed the internal `_decode_utf` method from the `Keenetic` class and replaced its usage with the new `decode_utf` utility function for decoding interface descriptions. - Added a new configuration file `config.conf` for Keenetic devices to facilitate testing. - Introduced an expected output JSON file `config.expected.json` to validate the parsing of Keenetic configurations against expected results.
This commit is contained in:
@@ -1,24 +1,13 @@
|
||||
from ipaddress import ip_interface
|
||||
from oxi.interfaces import register_parser
|
||||
from oxi.interfaces.base import BaseDevice
|
||||
from oxi.interfaces.utils import decode_utf
|
||||
|
||||
|
||||
@register_parser(["NDMS", "keenetic", "KeeneticOS"])
|
||||
class Keenetic(BaseDevice):
|
||||
template = "keenetic.ttp"
|
||||
|
||||
def _decode_utf(self, text: str):
|
||||
if "\\x" in text:
|
||||
desc = text.strip('"')
|
||||
decoded = (
|
||||
desc.encode("utf-8")
|
||||
.decode("unicode_escape")
|
||||
.encode("latin1")
|
||||
.decode("utf-8")
|
||||
)
|
||||
return decoded
|
||||
return text
|
||||
|
||||
def interfaces(self):
|
||||
interfaces: list[dict] = self.raw["interfaces"]
|
||||
for item in interfaces:
|
||||
@@ -29,7 +18,7 @@ class Keenetic(BaseDevice):
|
||||
item["mask"] = ipaddress.network.prefixlen
|
||||
item.pop("netmask", "Key not found")
|
||||
if item.get("description"):
|
||||
decoded = self._decode_utf(item.get("description", ""))
|
||||
decoded = decode_utf(item.get("description", ""))
|
||||
item["description"] = decoded
|
||||
return interfaces
|
||||
|
||||
@@ -37,13 +26,6 @@ class Keenetic(BaseDevice):
|
||||
vlans = self.raw["vlans"]
|
||||
for item in vlans:
|
||||
if item.get("description"):
|
||||
decoded = self._decode_utf(item.get("description", ""))
|
||||
decoded = decode_utf(item.get("description", ""))
|
||||
item["description"] = decoded
|
||||
return vlans
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open("./test2.txt") as file:
|
||||
data = file.read()
|
||||
mikr = Keenetic(data)
|
||||
print(mikr.parse().model_dump_json())
|
||||
|
||||
341
tests/fixtures/keenetic/config.conf
vendored
Normal file
341
tests/fixtures/keenetic/config.conf
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
!
|
||||
! release: 4.03.C.6.2-7
|
||||
! sandbox: stable
|
||||
! title: 4.3.6.2
|
||||
! arch: mips
|
||||
!
|
||||
! ndm:
|
||||
! exact: 0-a3057529fd
|
||||
! cdate: 29 Sep 2025
|
||||
!
|
||||
! bsp:
|
||||
! exact: 0-03b50470c4
|
||||
! cdate: 30 Sep 2025
|
||||
!
|
||||
! ndw:
|
||||
! features: dual_image,led_control,wifi_button,wifi5ghz,
|
||||
! vht2ghz,mimo2ghz,mimo5ghz,atf2ghz,atf5ghz,wifi6,wifi_ft,
|
||||
! wpa3,hwnat
|
||||
! components: base,cloudcontrol,corewireless,ddns,dhcpd,
|
||||
! dns-filter,dns-https,dns-tls,dot1x,easyconfig,igmp,ip6,
|
||||
! lang-en,lang-ru,miniupnpd,mws,nathelper-ftp,nathelper-
|
||||
! h323,nathelper-pptp,nathelper-rtsp,nathelper-sip,ndmp,
|
||||
! ndns,openvpn,pingcheck,ppe,pppoe,pptp,ssh,trafficcontrol,
|
||||
! wireguard
|
||||
!
|
||||
! ndw3:
|
||||
! version: 1.101.18.1
|
||||
!
|
||||
! ndw4:
|
||||
! version: 4.3.C.6.2
|
||||
!
|
||||
! manufacturer: Keenetic Ltd.
|
||||
! vendor: Keenetic
|
||||
! series: KN
|
||||
! model: Sprinter (KN-3710)
|
||||
! hw_version: 7777777
|
||||
! hw_type: router
|
||||
! hw_id: KN-3710
|
||||
! device: Sprinter
|
||||
! region: EA
|
||||
! description: Keenetic Sprinter (KN-3710)
|
||||
! $$$ Agent: http/rci
|
||||
! $$$ Last change: Fri, 3 Oct 2025 18:37:40 GMT
|
||||
! $$$ Model: Keenetic Sprinter
|
||||
! $$$ Username: admin
|
||||
! $$$ Version: 2.06.1
|
||||
system
|
||||
set net.ipv4.ip_forward 1
|
||||
set net.ipv4.neigh.default.gc_thresh1 256
|
||||
set net.ipv4.neigh.default.gc_thresh2 1024
|
||||
set net.ipv4.neigh.default.gc_thresh3 2048
|
||||
set net.ipv4.tcp_fin_timeout 30
|
||||
set net.ipv4.tcp_keepalive_time 120
|
||||
set net.ipv6.conf.all.forwarding 1
|
||||
set net.ipv6.neigh.default.gc_thresh1 256
|
||||
set net.ipv6.neigh.default.gc_thresh2 1024
|
||||
set net.ipv6.neigh.default.gc_thresh3 2048
|
||||
set net.netfilter.nf_conntrack_tcp_timeout_established 1200
|
||||
set vm.overcommit_memory 0
|
||||
set vm.vfs_cache_pressure 1000
|
||||
clock timezone Europe/Berlin
|
||||
domainname WORKGROUP
|
||||
hostname test_HW
|
||||
caption default
|
||||
description "Keenetic Sprinter (KN-3710)"
|
||||
ndss dump-report disable
|
||||
!
|
||||
dyndns profile _WEBADMIN
|
||||
!
|
||||
interface GigabitEthernet0
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/1
|
||||
rename 1
|
||||
switchport mode access
|
||||
switchport access vlan 1
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/2
|
||||
rename 2
|
||||
switchport mode access
|
||||
switchport access vlan 1
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/3
|
||||
rename 3
|
||||
switchport mode access
|
||||
switchport access vlan 1
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/Vlan1
|
||||
description "Home VLAN"
|
||||
ip dhcp client dns-routes
|
||||
ip name-servers
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/Vlan2
|
||||
rename ISP
|
||||
description "\xd0\x9f\xd0\xbe\xd0\xb4\xd0\xba\xd0\xbb\xd1\x8e\xd1\x87\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5 Ethernet"
|
||||
dyndns nobind
|
||||
mac address factory wan
|
||||
security-level public
|
||||
ip address dhcp
|
||||
ip dhcp client hostname test_HW
|
||||
ip dhcp client dns-routes
|
||||
ip mtu 1500
|
||||
ip access-group _WEBADMIN_ISP in
|
||||
ip global 57342
|
||||
ip no name-servers
|
||||
igmp upstream
|
||||
ipv6 address auto
|
||||
ipv6 prefix auto
|
||||
ipv6 no name-servers auto
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/0
|
||||
rename 0
|
||||
role inet for ISP
|
||||
switchport mode access
|
||||
switchport access vlan 2
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/Vlan3
|
||||
dyndns nobind
|
||||
ip dhcp client dns-routes
|
||||
ip name-servers
|
||||
up
|
||||
!
|
||||
interface WifiMaster0
|
||||
country-code RU
|
||||
compatibility BGN+AX
|
||||
rekey-interval 86400
|
||||
up
|
||||
!
|
||||
interface WifiMaster0/AccessPoint0
|
||||
mac access-list type none
|
||||
authentication wpa-psk ns3 7777ggggddddsss
|
||||
encryption enable
|
||||
encryption wpa2
|
||||
ip dhcp client dns-routes
|
||||
ssid test_HW_2.4G
|
||||
up
|
||||
!
|
||||
interface WifiMaster0/AccessPoint1
|
||||
mac access-list type none
|
||||
security-level private
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
down
|
||||
!
|
||||
interface WifiMaster0/AccessPoint2
|
||||
mac access-list type none
|
||||
security-level private
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
down
|
||||
!
|
||||
interface WifiMaster0/WifiStation0
|
||||
security-level public
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
standby enable
|
||||
standby timeout 600
|
||||
down
|
||||
!
|
||||
interface WifiMaster1
|
||||
country-code RU
|
||||
compatibility AN+AC+AX
|
||||
channel width 40-above/80
|
||||
rekey-interval 86400
|
||||
up
|
||||
!
|
||||
interface WifiMaster1/AccessPoint0
|
||||
mac access-list type none
|
||||
authentication wpa-psk ns3 7777ggggddddsss
|
||||
encryption enable
|
||||
encryption wpa2
|
||||
ip dhcp client dns-routes
|
||||
ssid test_HW_5G
|
||||
up
|
||||
!
|
||||
interface WifiMaster1/AccessPoint1
|
||||
mac access-list type none
|
||||
security-level private
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
down
|
||||
!
|
||||
interface WifiMaster1/AccessPoint2
|
||||
mac access-list type none
|
||||
security-level private
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
down
|
||||
!
|
||||
interface WifiMaster1/WifiStation0
|
||||
security-level public
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
standby enable
|
||||
standby timeout 600
|
||||
down
|
||||
!
|
||||
interface Bridge0
|
||||
rename Home
|
||||
description "Home network"
|
||||
dyndns nobind
|
||||
include GigabitEthernet0/Vlan1
|
||||
include WifiMaster0/AccessPoint0
|
||||
include WifiMaster1/AccessPoint0
|
||||
mac access-list type none
|
||||
security-level private
|
||||
ip address 17.36.1.1 255.255.255.0
|
||||
ip dhcp client dns-routes
|
||||
ip access-group _WEBADMIN_Home in
|
||||
ip name-servers
|
||||
band-steering
|
||||
up
|
||||
!
|
||||
interface Bridge1
|
||||
rename Guest
|
||||
description "Guest network"
|
||||
traffic-shape rate 5120
|
||||
dyndns nobind
|
||||
include GigabitEthernet0/Vlan3
|
||||
mac access-list type none
|
||||
peer-isolation
|
||||
security-level protected
|
||||
ip address 10.1.30.1 255.255.255.0
|
||||
ip dhcp client dns-routes
|
||||
ip name-servers
|
||||
down
|
||||
!
|
||||
interface Bridge2
|
||||
rename Test
|
||||
mac access-list type none
|
||||
security-level public
|
||||
ip dhcp client dns-routes
|
||||
up
|
||||
!
|
||||
interface OpenVPN0
|
||||
description test_HW-udp
|
||||
role misc
|
||||
security-level public
|
||||
ip dhcp client dns-routes
|
||||
ip tcp adjust-mss pmtu
|
||||
ip name-servers
|
||||
ipv6 name-servers auto
|
||||
openvpn accept-routes
|
||||
openvpn connect
|
||||
up
|
||||
!
|
||||
interface OpenVPN2
|
||||
description test_HW-tcp
|
||||
role misc
|
||||
dyndns nobind
|
||||
security-level public
|
||||
ip dhcp client dns-routes
|
||||
ip tcp adjust-mss pmtu
|
||||
openvpn accept-routes
|
||||
openvpn connect
|
||||
down
|
||||
!
|
||||
interface Wireguard0
|
||||
description test_HW
|
||||
dyndns nobind
|
||||
security-level public
|
||||
ip address 10.3.100.1 255.255.255.0
|
||||
ip mtu 1324
|
||||
ip tcp adjust-mss pmtu
|
||||
wireguard listen-port 65513
|
||||
wireguard peer 7777ggggddddsss= !test_HW
|
||||
allow-ips 0.0.0.0 0.0.0.0
|
||||
connect
|
||||
!
|
||||
up
|
||||
!
|
||||
interface Wireguard1
|
||||
description test_HW
|
||||
dyndns nobind
|
||||
security-level private
|
||||
ip address 10.1.100.1 255.255.255.0
|
||||
ip mtu 1324
|
||||
ip access-group _WEBADMIN_Wireguard1 in
|
||||
ip tcp adjust-mss pmtu
|
||||
wireguard listen-port 65511
|
||||
wireguard peer 7777ggggddddsss= !test_HW
|
||||
allow-ips 10.1.100.0 255.255.255.0
|
||||
allow-ips 17.36.3.0 255.255.255.0
|
||||
allow-ips 17.36.1.0 255.255.255.0
|
||||
allow-ips 0.0.0.0 0.0.0.0
|
||||
connect
|
||||
!
|
||||
up
|
||||
!
|
||||
interface Wireguard2
|
||||
description test_HW
|
||||
dyndns nobind
|
||||
security-level private
|
||||
ip address 10.2.100.1 255.255.255.0
|
||||
ip access-group _WEBADMIN_Wireguard2 in
|
||||
ip tcp adjust-mss pmtu
|
||||
wireguard listen-port 65512
|
||||
wireguard peer 7777ggggddddsss= !test_HW
|
||||
allow-ips 0.0.0.0 0.0.0.0
|
||||
connect
|
||||
!
|
||||
up
|
||||
!
|
||||
ip ssh
|
||||
port 22
|
||||
security-level public
|
||||
lockout-policy 5 15 3
|
||||
!
|
||||
ip hotspot
|
||||
policy Home permit
|
||||
host 7777ggggddddsss permit
|
||||
host 7777ggggddddsss priority 4
|
||||
!
|
||||
ipv6 subnet Default
|
||||
bind Home
|
||||
mode slaac
|
||||
prefix length 64
|
||||
number 0
|
||||
!
|
||||
ppe software
|
||||
ppe hardware
|
||||
upnp lan Home
|
||||
service dhcp
|
||||
service dns-proxy
|
||||
service http
|
||||
service telnet
|
||||
service ssh
|
||||
service ntp
|
||||
service upnp
|
||||
!
|
||||
easyconfig disable
|
||||
components
|
||||
auto-update disable
|
||||
auto-update channel stable
|
||||
!
|
||||
161
tests/fixtures/keenetic/config.expected.json
vendored
Normal file
161
tests/fixtures/keenetic/config.expected.json
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
{
|
||||
"system": {
|
||||
"model": "Sprinter (KN-3710)",
|
||||
"serial_number": "7777777",
|
||||
"version": "4.03.C.6.2-7"
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"interface": "GigabitEthernet0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "GigabitEthernet0/1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "GigabitEthernet0/2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "GigabitEthernet0/3",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "GigabitEthernet0/0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster0/AccessPoint0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster0/AccessPoint1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster0/AccessPoint2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster0/WifiStation0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster1/AccessPoint0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster1/AccessPoint1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster1/AccessPoint2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster1/WifiStation0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "Bridge0",
|
||||
"ip_address": "17.36.1.1",
|
||||
"mask": 24,
|
||||
"description": "Home network"
|
||||
},
|
||||
{
|
||||
"interface": "Bridge1",
|
||||
"ip_address": "10.1.30.1",
|
||||
"mask": 24,
|
||||
"description": "Guest network"
|
||||
},
|
||||
{
|
||||
"interface": "Bridge2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "OpenVPN0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "test_HW-udp"
|
||||
},
|
||||
{
|
||||
"interface": "OpenVPN2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "test_HW-tcp"
|
||||
},
|
||||
{
|
||||
"interface": "Wireguard0",
|
||||
"ip_address": "10.3.100.1",
|
||||
"mask": 24,
|
||||
"description": "test_HW"
|
||||
},
|
||||
{
|
||||
"interface": "Wireguard1",
|
||||
"ip_address": "10.1.100.1",
|
||||
"mask": 24,
|
||||
"description": "test_HW"
|
||||
},
|
||||
{
|
||||
"interface": "Wireguard2",
|
||||
"ip_address": "10.2.100.1",
|
||||
"mask": 24,
|
||||
"description": "test_HW"
|
||||
}
|
||||
],
|
||||
"vlans": [
|
||||
{
|
||||
"vlan_id": 1,
|
||||
"description": "Home VLAN"
|
||||
},
|
||||
{
|
||||
"vlan_id": 2,
|
||||
"description": "Подключение Ethernet"
|
||||
},
|
||||
{
|
||||
"vlan_id": 3,
|
||||
"description": "Home network"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user