feat: initial napalm-yealink driver

Discovery-Fingerprinting für Yealink IP-Phones (T-series, W-series,
CP-series, VP-series) und Video-Endpoints.

- TYPE_LABEL = "Phone" (Override von AccessPointDriver)
- SNMP_OBJECT_ID_PREFIX = "1.3.6.1.4.1.37403" (Yealink Enterprise OID)
- HTTP_FINGERPRINT: "yealink" (mandatory, weight 10), Modell-Patterns
- get_facts(): liest phoneName + firmware aus dem noauth-API-Response
  (/api/v1/system/info liefert Gerätedaten auch ohne Authentication)
- Login via MD5-gehashtem Passwort auf /api/v1/session/login (HTTPS)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Manivong
2026-06-24 15:17:08 +02:00
co-authored by Claude Sonnet 4.6
commit 60525bd35e
15 changed files with 316 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
"""Fingerprint tests for YealinkDriver."""
from napalm_device_types import DeviceTypeDriver, FingerprintRule
from napalm_yealink import YealinkDriver
def test_yealink_is_device_type_driver():
assert issubclass(YealinkDriver, DeviceTypeDriver)
def test_type_label():
assert YealinkDriver.TYPE_LABEL == "Phone"
def test_vendor():
assert YealinkDriver.VENDOR == "Yealink"
def test_driver_name():
assert YealinkDriver.DRIVER_NAME == "yealink"
def test_snmp_oid_prefix():
assert YealinkDriver.SNMP_OBJECT_ID_PREFIX == "1.3.6.1.4.1.37403"
def test_http_fingerprint_mandatory_yealink():
mandatory = [r for r in YealinkDriver.HTTP_FINGERPRINT if r.mandatory]
assert any(r.pattern == "yealink" for r in mandatory)
def test_fingerprint_matches_t58_title():
"""'Yealink T58 Phone' im Titel → mandatory 'yealink' trifft zu."""
combined = "yealink t58 phone nginx "
mandatory = [r for r in YealinkDriver.HTTP_FINGERPRINT if r.mandatory]
assert all(r.pattern in combined for r in mandatory)
def test_fingerprint_does_not_match_cisco():
"""Cisco-Seite enthält kein 'yealink' → mandatory Pattern fehlt."""
combined = "cisco ip phone cp-8841 "
mandatory = [r for r in YealinkDriver.HTTP_FINGERPRINT if r.mandatory]
assert not all(r.pattern in combined for r in mandatory)