Imported from meklis/switcher-core (
AGENTS.md). Install upstream withnpx skills add meklis/switcher-core. Copyright stays with the author.
AGENTS.md
Описание проекта
switcher-core это PHP-библиотека для работы с сетевым оборудованием через единый интерфейс. Основная идея репозитория: определять модель устройства по SNMP, подмешивать YAML-конфигурации OID/модулей и вызывать нужный модуль без отдельного враппера под каждого вендора.
Проект ориентирован на коммутаторы, OLT и роутеры. Поддерживаются входы через SNMP v2c, telnet, ssh и RouterOS API. Библиотека используется как embeddable core, а не как самостоятельный сервис.
Подтвержденные параметры проекта
- Язык и формат: PHP library, автозагрузка
PSR-4через namespaceSwitcherCore\\. - Минимальная версия PHP по
composer.json:>=7.2.0. - Ключевые runtime-зависимости:
meklis/snmp-wrapper,meklis/console-client,meklis/routeros-api,php-di/php-di,monolog/monolog,phpseclib/phpseclib,ext-yaml,ext-json. - Dev-зависимости:
phpunit/phpunit,symfony/console. - Базовая команда тестов:
composer tests. - В репозитории сейчас есть 40 файлов моделей в
configs/models, 31 vendor/module namespace вsrc/Modules, 4 trap-конфига и 1 тестовый файл.
Архитектура
- Точка сборки ядра:
src/Switcher/CoreConnector.php. - Основной runtime-объект:
src/Switcher/Core.php. - Описание устройства и connection-параметров:
src/Switcher/Device.php. - Встроенный путь к конфигам возвращает
SwitcherCore\\Modules\\Helper::getBuildInConfig(). - Конфигурация модели/модулей/OID читается из
configs/черезsrc/Config/*Collector.php. - Реальные реализации модулей лежат в
src/Modules/<Vendor>/. - Общий реестр модулей и их аргументов:
configs/modules.yml. - Device detection завязан на
sys.Descr,sys.ObjId,sys.IfacesCount.
Карта каталогов
src/Switcher/: ядро, коннекторы, console wrappers, cache objects.src/Config/: чтение YAML и сборщики моделей, OID, trap и модулей.src/Modules/: модульные реализации по вендорам и типам устройств.configs/models/: YAML-описания поддерживаемых моделей и mapping модулей.configs/oids/: OID-базы по вендорам и платформам.configs/traps/: trap-конфиги.docs/: список устройств, модулей и примеры ответов.src/Dev/иbin/console: локальная dev-консоль для вызова модулей и просмотра поддержки.tests/: сейчас покрытие минимальное и в основном проверяет консистентность OID-конфигов.
Как работать с этим репозиторием
- Сначала проверять YAML-конфиги и mapping модели, потом уже PHP-классы модулей: значительная часть поведения задается не кодом, а
configs/models/*.ymlиconfigs/modules.yml. - Для новых устройств обычно нужно:
- добавить или поправить OID-файлы в
configs/oids/; - описать модель в
configs/models/; - привязать существующие модули или добавить новые классы в
src/Modules/...; - проверить, что detection и аргументы модуля совпадают с конфигом.
- добавить или поправить OID-файлы в
- Для локальной ручной проверки использовать
bin/console, особенно командыmodules,call,devices-by-module. - Не полагаться на широкое тестовое покрытие: автоматические тесты здесь не гарантируют корректность runtime-поведения на реальном оборудовании.
Правила при разработке/доработке модулей
- Приоритет — SNMP. Консоль (telnet/ssh) тоже полноценный вариант, а не запасной — например, когда нужна информация по конкретной ONU, а через SNMP её получить нельзя.
- Новые модули и правки существующих равнять по структуре класса и именованию на уже существующие модули, написанные до 2026 года — не изобретать свой стиль.
- Комментарии в коде — на русском, короткие, не обязательны на каждую строку. PHPDoc и commit-сообщения — по-прежнему на английском.
- После любого изменения — обязательно протестировать, а не остановиться на
php -l: прогнать реальный вызов черезbin/consoleилиwca(см. примеры ниже) и показать результат.
Конвенция полей в ответах модулей (getPretty)
Правила согласованы с пользователем на примере pon_onts_blacklist (GPON FD16xxV3\OntBlacklist vs EPON CData\OntBlacklist) и применимы ко всем модулям, у которых один и тот же action реализован по-разному на разных платформах/вендорах.
- Поле без подчеркивания в начале — значит оно общее (одинаковое по смыслу и имени) для всех платформенных реализаций данного action. Пример:
index,interfaces,enabledвpon_onts_blacklist— присутствуют что у GPON, что у EPON. - Поле с
_в начале — значит оно специфично только для одной платформы/вендора и не входит в общий контракт action'а. Пример:_mask,_hit_countтолько у GPON (SN-based blacklist с маской);_frame_slot,_portтолько у EPON (blacklist привязан к PON-порту). - Если разные платформы отдают семантически одно и то же значение под разными именами (например GPON —
serial, EPON —mac), нужно:- завести общее поле без подчеркивания с нейтральным именем (в данном случае
ident), которое содержит это значение независимо от платформы; - продублировать исходное платформенное имя с подчеркиванием (
_serialу GPON,_macу EPON) для обратной совместимости и для тех, кому нужно точно знать тип идентификатора.
- завести общее поле без подчеркивания с нейтральным именем (в данном случае
- Эта конвенция — про имена полей в
getPretty()/getPrettyFiltered(), а не про интерфейсные объекты (interface/interfaces), у которых уже есть своя устоявшаяся конвенция:id,name,type,parent— общие,_port,_slot,_onu,_snmp_id,_technology,_typeи т.п. — технические/платформенные. - При добавлении новой платформенной реализации существующего action-а проверять уже имеющиеся реализации этого же action у других вендоров и приводить имена полей к этой же схеме, а не изобретать новые.
Практические замечания для будущих проходов
- В коде много vendor-specific логики и исторического стиля PHP; перед рефакторингом нужно отдельно проверять обратную совместимость.
CoreConnectorумеет кешировать собранные collector-объекты через serialize/unserialize; изменения конфигов могут требовать пересборки этого кеша.bin/consoleчитает параметры подключения изbin/connection.conf.yml.- Для тестирования модулей на реальном железе можно использовать
wildcoreDMS, если он установлен в окружении. wildcoreDMSможет быть установлен локально или на удаленном сервере; во втором случае команды нужно выполнять черезsshна этот сервер.- В документации и внутренних заметках не хранить реальные IP-адреса оборудования; использовать плейсхолдеры вроде
DEVICE_IPиREMOTE_HOST. - Базовые примеры вызова модуля через
wildcoreDMS:wca switcher-core:call DEVICE_IP pon_onts_statusssh REMOTE_HOST 'wca switcher-core:call DEVICE_IP pon_onts_status'ssh REMOTE_HOST 'docker exec -i wca wca switcher-core:call DEVICE_IP pon_onts_status'
- Для SNMP-проверки через
wcaиспользовать командуtest:snmpwalk, а неtest:snmp:wca test:snmpwalk DEVICE_IP if.Descrwca test:snmpwalk DEVICE_IP ont.opStatusssh REMOTE_HOST 'docker exec -i wca wca test:snmpwalk DEVICE_IP ont.opStatus'
- Для детализированного вывода при диагностике добавлять
-v --telnetили короткую форму-v -t. - При запуске
wcaиз automation/PTY-less окружения учитывать, что команда может требовать TTY; типичный симптом:the input device is not a TTY. - Проверенный локальный пример:
wca switcher-core:call DEVICE_IP pon_onts_status -v --telnet
- Проверенный успешный пример:
wca switcher-core:call DEVICE_IP system -v --telnet
- Проверенный успешный пример после фикса декодирования ONU index:
wca switcher-core:call DEVICE_IP pon_onts_status -v --telnet
- Проверенные SNMP-примеры для этого устройства:
wca test:snmpwalk DEVICE_IP if.Descrwca test:snmpwalk DEVICE_IP ont.opStatuswca test:snmpwalk DEVICE_IP ont.serialNum
- Что дает подробный режим на практике:
- печатает стартовый блок с IP, именем модуля и аргументами;
- при ошибке показывает текст исключения и stack trace;
- печатает секцию
Telnet output, даже если telnet-буфер пустой.
- На успешном вызове
systemдля одного из проверенных C-Data FD17xx устройств команда вернула JSON c общей информацией об устройстве, включаяmeta.key = c_data_fd1700s_fw3, версию ПОV3.3.48, версию железаV1.0и список доступных модулей. - Исторически на вызове
pon_onts_statusдля одного из проверенных FD17xx устройств была ошибкаUnable to decode ONU index; после фикса FD17xx модуль отрабатывает успешно, а этот кейс полезен как пример диагностики SNMP index-related проблем. - В рабочем дереве могут встречаться служебные и временные файлы вроде
logs,mock,.phpunit.result.cache,.save; не удалять их автоматически без прямого запроса. - Не трогать
vendor/, если задача не требует обновления зависимостей. - Если меняется сигнатура или поведение модуля, нужно сверять код с
configs/modules.yml, иначе dev-console и внешние клиенты будут расходиться с реальностью.