Filtering scripts в EPP

Started by Argonauts, January 28, 2026, 05:19:35 AM

Previous topic - Next topic

Argonauts

Добрый день!
Имеется скрипт
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 и ts
sub 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"
    }
  ]
}
Что я сделал не так с этими фильтрами? ::)

Filipp Sudanov

contains это метод строки. Функции с таким именем нет. По идее в лог сервера должны сыпаться ошибки "Function not found" и создаваться ивенты SYS_SCRIPT_ERROR.

А надо так:

subnet.contains("dc")

Argonauts

А он давал такую ошибку, да. Но на линию 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);

Filipp Sudanov

А скрипт которые параметр 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.


Argonauts

Скрипт заводится из 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;

}
Вроде как корректно фильтрует по нужным действиям

Argonauts

Я скриптом с #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 Edge

https://netxms.org/documentation/nxsl-latest/ Тут актуальный док выложен по языку?
Вроде как скрипт подходит, в строчке нужная инфа есть, но сравнение выдает false.
Т.е. условный "2026-01 Обновление для системы безопасности" не содержит в себе "для системы безопасности"?

Filipp Sudanov

Да, по ссылке актуальная документация.
Можно на любой ноде сделать 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()