Ложное срабатывание на SYS_PACKAGE_UPDATE

Started by IFriendly, January 30, 2018, 11:50:51 AM

Previous topic - Next topic

IFriendly

Добрый день!

Обнаружил ложное срабатывание при опросе конфигурации через агента (2.2.2, Linux Centos 7)
Решил проблему NXSL-фильтром на обработчике событий.

Но ситуация в принципе не корректная.

Причина в следующем.

Опрос ПО и установленных пакетов идет через агента по System.InstalledProducts событию и в хендлере H_InstalledProducts()
...
      command = "/bin/rpm -qa --queryformat '@@@ #%{NAME}:%{ARCH}|%{VERSION}|%{VENDOR}|%{INSTALLTIME}|%{URL}|%{SUMMARY}\\n'";
...

Интересующая часть результата опроса:
....
@@@ #gpg-pubkey:(none)|f4a80eb5|(none)|1512394964|(none)|gpg(CentOS-7 Key (CentOS 7 Official Signing Key) <[email protected]>)
@@@ #gpg-pubkey:(none)|352c64e5|(none)|1512410575|(none)|gpg(Fedora EPEL (7) <[email protected]>)
@@@ #gpg-pubkey:(none)|442df0f8|(none)|1512403038|(none)|gpg(PostgreSQL RPM Building Project <[email protected]>)
.....

Обработка полученного результата идет на сервере в Node::updateSoftwarePackages()
...
SoftwarePackage *pkg = SoftwarePackage::createFromTableRow(table, i);
packages->add(pkg);
...
packages->sort(PackageNameComparator);

Компаратор производит сравнение по имени пакета, но имена из примера выше одинаковые.

static int PackageNameComparator(const SoftwarePackage *p1, const SoftwarePackage *p2)
{
   return _tcscmp((*p1)->getName(), (*p2)->getName());
}

В таких случаях хорошо бы сравнивать еще и по описанию, но метода для доступа к приватному полю в классе SoftwarePackage нет:

class SoftwarePackage{
...
public:
   ~SoftwarePackage();

   void fillMessage(NXCPMessage *msg, UINT32 baseId) const;
   const TCHAR *getName() const { return m_name; }
   const TCHAR *getVersion() const { return m_version; }

   static SoftwarePackage createFromTableRow(const Table table, int row);
};

Ложное срабатывание происходит при поиске:
         SoftwarePackage *p = m_softwarePackages->get(i);
         SoftwarePackage np = (SoftwarePackage )packages->find(p, PackageNameComparator);

т.к. будет найден первый из имеющихся опрошенных пакетов при поиске по одинаковому ключу.

Решение:
1. Добавить методы в класс SoftwarePackage для доступа к описанию пакета.
2. В случае одинаковых имен пакетов в компараторе провести сравнение по описанию.

Также можно расширить запрос rpm на один столбец: %{Packager} и сравнивать не по описанию, а по %{Packager}-у, при этом необходимо будет расширить таблицу с сохраненными параметрами пакетов (аналогично и для deb-пакетов).