diff --git a/include/nxsl_classes.h b/include/nxsl_classes.h index 67589bf..859996f 100644 --- a/include/nxsl_classes.h +++ b/include/nxsl_classes.h @@ -225,6 +225,8 @@ class LIBNXSL_EXPORTABLE NXSL_HashMap : public NXSL_HandleCountObject NXSL_Value *getKeys() const; NXSL_Value *getValues() const; + StringMap *toStringMap() const; + int size() const { return m_values->size(); } }; diff --git a/src/libnxsl/hashmap.cpp b/src/libnxsl/hashmap.cpp index ab7fa3d..94f0f66 100644 --- a/src/libnxsl/hashmap.cpp +++ b/src/libnxsl/hashmap.cpp @@ -85,3 +85,22 @@ NXSL_Value *NXSL_HashMap::getValues() const delete values; return new NXSL_Value(array); } + +/** + * Get hash map as string map + * Resulting string map is dynamically allocated and should be destroyed by caller + */ +StringMap *NXSL_HashMap::toStringMap() const +{ + StringMap *map = new StringMap(); + StructArray *values = m_values->toArray(); + for(int i = 0; i < values->size(); i++) + { + KeyValuePair *p = values->get(i); + const TCHAR *s = ((NXSL_Value *)p->value)->getValueAsCString(); + if (s != NULL) + map->set(p->key, s); + } + delete values; + return map; +} diff --git a/src/server/core/dctarget.cpp b/src/server/core/dctarget.cpp index 286b5f1..979cccb 100644 --- a/src/server/core/dctarget.cpp +++ b/src/server/core/dctarget.cpp @@ -745,6 +745,95 @@ UINT32 DataCollectionTarget::getListFromScript(const TCHAR *param, StringList ** } /** + * Get string map from library script + */ +UINT32 DataCollectionTarget::getStringMapFromScript(const TCHAR *param, StringMap **map) +{ + TCHAR name[256]; + nx_strncpy(name, param, 256); + Trim(name); + + ObjectArray args(16, 16, false); + + // Can be in form parameter(arg1, arg2, ... argN) + TCHAR *p = _tcschr(name, _T('(')); + if (p != NULL) + { + if (name[_tcslen(name) - 1] != _T(')')) + return DCE_NOT_SUPPORTED; + name[_tcslen(name) - 1] = 0; + + if (!ParseValueList(&p, args)) + { + // argument parsing error + args.clear(); + return DCE_NOT_SUPPORTED; + } + } + + UINT32 rc = DCE_NOT_SUPPORTED; + NXSL_VM *vm = g_pScriptLibrary->createVM(name, new NXSL_ServerEnv); + if (vm != NULL) + { + vm->setGlobalVariable(_T("$object"), createNXSLObject()); + if (getObjectClass() == OBJECT_NODE) + { + vm->setGlobalVariable(_T("$node"), new NXSL_Value(new NXSL_Object(&g_nxslNodeClass, this))); + } + vm->setGlobalVariable(_T("$isCluster"), new NXSL_Value((getObjectClass() == OBJECT_CLUSTER) ? 1 : 0)); + if (vm->run(&args)) + { + rc = DCE_SUCCESS; + NXSL_Value *value = vm->getResult(); + if (value->isHashMap()) + { + *map = value->getValueAsHashMap()->toStringMap(); + } + else if (value->isArray()) + { + *map = new StringMap(); + NXSL_Array *a = value->getValueAsArray(); + for(int i = 0; i < a->size(); i++) + { + NXSL_Value *v = a->getByPosition(i); + if (v->isString()) + { + (*map)->set(v->getValueAsCString(), v->getValueAsCString()); + } + } + } + else if (value->isString()) + { + *map = new StringMap(); + (*map)->set(value->getValueAsCString(), value->getValueAsCString()); + } + else if (value->isNull()) + { + rc = DCE_COMM_ERROR; + } + else + { + *map = new StringMap(); + } + } + else + { + DbgPrintf(4, _T("DataCollectionTarget(%s)->getListFromScript(%s): Script execution error: %s"), m_name, param, vm->getErrorText()); + PostEvent(EVENT_SCRIPT_ERROR, g_dwMgmtNode, "ssd", name, vm->getErrorText(), m_id); + rc = DCE_COMM_ERROR; + } + delete vm; + } + else + { + args.setOwner(true); + DbgPrintf(4, _T("DataCollectionTarget(%s)->getListFromScript(%s): script \"%s\" not found"), m_name, param, name); + } + DbgPrintf(7, _T("DataCollectionTarget(%s)->getListFromScript(%s): rc=%d"), m_name, param, rc); + return rc; +} + +/** * Get last (current) DCI values for summary table. */ void DataCollectionTarget::getDciValuesSummary(SummaryTable *tableDefinition, Table *tableData) diff --git a/src/server/core/node.cpp b/src/server/core/node.cpp index 107c96e..5b8c740 100644 --- a/src/server/core/node.cpp +++ b/src/server/core/node.cpp @@ -3521,7 +3521,7 @@ StringMap *Node::getInstanceList(DCItem *dci) node->getListFromAgent(dci->getInstanceDiscoveryData(), &instances); break; case IDM_SCRIPT: - node->getListFromScript(dci->getInstanceDiscoveryData(), &instances); + node->getStringMapFromScript(dci->getInstanceDiscoveryData(), &instanceMap); break; case IDM_SNMP_WALK_VALUES: node->getListFromSNMP(dci->getSnmpPort(), dci->getInstanceDiscoveryData(), &instances); diff --git a/src/server/include/nms_objects.h b/src/server/include/nms_objects.h index a35dc7c..2125f6b 100644 --- a/src/server/include/nms_objects.h +++ b/src/server/include/nms_objects.h @@ -1030,6 +1030,7 @@ class NXCORE_EXPORTABLE DataCollectionTarget : public Template virtual UINT32 getEffectiveSourceNode(DCObject *dco); UINT32 getListFromScript(const TCHAR *param, StringList **list); + UINT32 getStringMapFromScript(const TCHAR *param, StringMap **map); UINT32 getTableLastValues(UINT32 dciId, NXCPMessage *msg); UINT32 getThresholdSummary(NXCPMessage *msg, UINT32 baseId);