Filtering scripts в EPP
-
Добрый день!
Имеется скриптsubnets = []; for (p : $node.parents) if (classof(p) == "Subnet") subnets.append(p.alias); $event.addParameter("subnets", subnets.join(", ")); return true;Прицепляющий alias подсети к ивенту SYS_NODE_ADDED
В EPP созданы 2 правила на тот же ивент, отличающиеся действием и Filter скриптами
1-ый вроде как должен фильтровать ивенты, где в alias нет dc и tssub main() { subnet = tolower($event->subnets); // Быстрая проверка по ключевым словам if(contains(subnet, "dc") || contains(subnet, "ts")) { nxlog(4, "FILTER: Blocked DC subnet - " . $event->subnets); return false; } return true; }2-ой - где alias содержит dc и ts
sub main() { subnet = tolower($event->subnets); // Быстрая проверка по ключевым словам if(contains(subnet, "dc") || contains(subnet, "ts")) { return true; } nxlog(4, "FILTER: Blocked Users subnet - " . $event->subnets); return false; }Если в ивенте действительно ЕСТЬ dc или ts - приходит 1 ивент в нужный топик. Но если в alias нет dc\ts - алармы сыпятся в оба топика, что на 1-ый фильтр, что на второй
Вот пример такого ивента{ "id": 180591103, "rootId": 0, "code": 1, "name": "SYS_NODE_ADDED", "timestamp": 1769568582, "originTimestamp": 1769568582, "origin": 0, "source": 1051263, "zone": 0, "dci": 0, "severity": 0, "message": "Node added", "lastAlarmKey": "", "lastAlarmMessage": "", "tags": [ "NewObject" ], "parameters": [ { "name": "nodeOrigin", "value": "1" }, { "name": "subnets", "value": "KRS_Gaydashovka_UC" } ] }Что я сделал не так с этими фильтрами? ::)
-
contains это метод строки. Функции с таким именем нет. По идее в лог сервера должны сыпаться ошибки "Function not found" и создаваться ивенты SYS_SCRIPT_ERROR.
А надо так:
subnet.contains("dc")
-
А он давал такую ошибку, да. Но на линию 2, сейчас там
subnet = toLowerCase($event.subnets);Собственно в таком виде
sub main() { subnet_dc = toLowerCase($event.subnets); // Быстрая проверка по ключевым словам if(subnet_dc.contains("dc") || subnet_dc.contains("ts")) { return true; } return false; }Все равно не работает корректно - уведомления продолжают идти в оба топика. Ошибки видел на линию 2 Function not found
Если верить https://netxms.org/documentation/nxsl-latest/#class-event parameterNames существует в виде array - поиск по нему в таком виде вообще возможен? Или я изначально накосячилРеференсом было вот это
sub main() { packageName = toLowerCase($alarm.key); // Быстрая проверка по ключевым словам if(packageName.contains("7-zip") || packageName.contains("adobe reader")) { nxlog(4, "FILTER: Blocked package - " . $alarm->key); return false; } return true; }Как оказалось по логам - оно так же не работает, жалуясь Function or operation argument is not an object на линию
packageName = toLowerCase($alarm.key); -
А скрипт которые параметр subnets прикрепляет к событию - он откуда запускается?
Ну и там нет такого, что в filter script в этих правилах EPP могут попадать события, у которых нет этого параметра?
Eсли параметра нет, то при обращении к $event.subnets скрипт завалится с ошибкой Unknown object's attribute. Безопаснее использовать метод:
$event.getParameter("subnets")если параметра нет, он вернет null, но скрипт не завалится.
subnet_dc = $event.getParameter("subnets"); trace(0, "From EPP rule " .. typeof(subnet_dc) .. " " .. subnet_dc); // можно логить в серверный лог чтоб разобраться что происходит if (subnet_dc == null) return false; subnet_dc = subnet_dc.toLowerCase(); if (subnet_dc.contains("dc") || subnet_dc.contains("ts")) { return true; } return false;sub main() для EPP скриптов можно не писать, это актуально когда определяется функция, которую вызывают другие скрипты. И вместо sub теперь используется function.
-
Скрипт заводится из EPP по событию SYS_NODE_ADDED, опять же на форуме подсказали. С уведомлениями по подсетям я вроде разобрался, сейчас в таком виде
sub main() { subnet_dc = $event.subnets; // Быстрая проверка по ключевым словам if(($event.subnets like "*DC*") || ($event.subnets like "*TS*")) { return true; } return false; }sub main() { subnet = $event.subnets; // Быстрая проверка по ключевым словам if(($event.subnets like "*DC*") || ($event.subnets like "*TS*")) { return false; } return true; }Вроде как корректно фильтрует по нужным действиям
-
Я скриптом с #3 попытался отфильтровать EPP, которое кучу алармов генерирует при удалении\установке\изменении пакета приложений на ноде - дефолтная EPP 42. Так как бы не пробовал, но алармы проходят фильтр, хотя вроде как не должны
sub main() { packageName = $event.getParameter("name"); trace(0, "From EPP rule " .. typeof(packageName) .. " " .. packageName); //можно логить в серверный лог чтоб разобраться что происходит if (packageName == null) return false; packageName = packageName.toLowerCase(); if ((packageName.contains("7-zip")) || (packageName.contains("adobe reader")) || (packageName.contains("средства проверки правописания microsoft"))) { return false; } return true; }Пакетов там что-то около 60 указано, я сократил текст
Пример события{ "id": 181445587, "rootId": 0, "code": 87, "name": "SYS_PACKAGE_INSTALLED", "timestamp": 1769740202, "originTimestamp": 1769740202, "origin": 0, "source": 236657, "zone": 0, "dci": 0, "severity": 0, "message": "Package Intel(R) ME UninstallLegacy 1.0.1.0 installed", "lastAlarmKey": "", "lastAlarmMessage": "", "tags": null, "parameters": [ { "name": "name", "value": "Intel(R) ME UninstallLegacy" }, { "name": "version", "value": "1.0.1.0" } ] }В логах вроде как parameter корректно отбирается
2026.01.30 10:22:06.023 *I* [nxsl.trace ] From EPP rule string Агент администрирования Kaspersky Security Center 2026.01.30 10:22:06.023 *I* [nxsl.trace ] From EPP rule string LowerCase агент администрирования kaspersky security center 2026.01.30 10:22:09.734 *I* [nxsl.trace ] From EPP rule string Агент администрирования Kaspersky Security Center 2026.01.30 10:22:09.734 *I* [nxsl.trace ] From EPP rule string LowerCase агент администрирования kaspersky security center 2026.01.30 10:22:46.525 *I* [nxsl.trace ] From EPP rule string Агент администрирования Kaspersky Security Center 2026.01.30 10:22:58.159 *I* [nxsl.trace ] From EPP rule string Microsoft Edgehttps://netxms.org/documentation/nxsl-latest/ Тут актуальный док выложен по языку?
Вроде как скрипт подходит, в строчке нужная инфа есть, но сравнение выдает false.
Т.е. условный "2026-01 Обновление для системы безопасности" не содержит в себе "для системы безопасности"? -
Да, по ссылке актуальная документация.
Можно на любой ноде сделать Execute script, там packageName задать вручную, а не из ивента и посмотреть что будет, у меня вот это выдает false:sub main() { packageName = "2026-01 Обновление для системы безопасности"; if (packageName == null) return false; packageName = packageName.toLowerCase(); if ((packageName.contains("для системы безопасности")) || (packageName.contains("adobe reader")) || (packageName.contains("средства проверки правописания microsoft"))) { return false; } return true; }И, кстати, в Configuration есть такая штука как Mapping tables, там можно вести табличку с названиями ненужного софта, в колонке Key, Value можно не заполнять, из NXSL это будет доступно в виде массива через функцию GetMappingTableKeys()
-
Вот в таком виде фильтр отрабатывает вроде как корректно.
sub main() { packageName = $event.getParameter("name"); //trace(0, "From EPP rule " .. typeof(packageName) .. " " .. packageName); //можно логить в серверный лог чтоб разобраться что происходит if (packageName == null) return false; packageName = packageName.toLowerCase(); if ((packageName like "*7-zip*") || (packageName like "*adobe reader*") || (packageName like "*средства проверки правописания microsoft*")) { return false; } trace(0, "From EPP rule " .. typeof(packageName) .. " " .. packageName); //Лог, чтобы видеть разрешенные к алертам записи return true; } -
Замена contains на like проблему не решила — оба регистрозависимы. В текущем виде фильтр не сработает ни на одной записи с кириллицей, а ASCII-записи ("7-zip", "adobe reader") это маскируют.
Проверено на nxscript 6.2.0:
s = "Средства Проверки Microsoft Edge"; s like "*Средства Проверки*" // true - регистр совпадает s like "*средства проверки*" // false - регистр не совпадает s.contains("Средства Проверки") // true s ilike "*средства проверки*" // true - ilike регистронезависимРегистронезависимый оператор — ilike, а не like. Среди методов строки аналога contains без учёта регистра нет, equalsIgnoreCase сравнивает строку целиком.
Почему исходный вариант с contains выглядел нерабочим: по приложенному логу toLowerCase на вашем сервере отработал корректно — "агент администрирования kaspersky security center". Значит и contains работал, а пакеты из трейса (Kaspersky Security Center, Microsoft Edge) просто не входили в список из 60 записей, и правило отфильтровало их правильно. Исходный скрипт был в порядке.
Деталь, которая здесь важнее: toLowerCase, toUpperCase, ilike и equalsIgnoreCase для не-ASCII зависят от локали процесса. LC_CTYPE подхватывается только если он есть в окружении, а systemd-юнит его не задаёт — при запуске из пакета netxmsd может работать в локали C. Тогда toLowerCase молча оставляет кириллицу без изменений, а ilike и equalsIgnoreCase на кириллице возвращают false, без записи в лог. Тикет на это: https://github.com/netxms/netxms/issues/3483
Проверка:
println("Средства".toLowerCase()); // ожидается "средства"Если вывод пустой или регистр не изменился, локали нет — задаётся через LANG=C.UTF-8 в /etc/default/netxmsd.
Для списка из 60 наименований надёжнее не приводить регистр вручную: либо сравнивать через ilike при рабочей локали, либо сопоставлять точным регистром через contains — второй вариант от локали не зависит вообще. Вариант с Mapping tables, предложенный выше, здесь удобнее обоих: список правится в Configuration без редактирования скрипта, GetMappingTableKeys() отдаёт его массивом.
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login