Дополнительные объекты JavaScript

Обзор

Этот раздел описывает дополнения Zabbix к языку JavaScript, который реализован при помощи Duktape, и поддерживаемые глобальные функции JavaScript.

Не используйте необъявленные присваивания в предварительной обработке JavaScript. Используйте var для объявления локальных переменных.

Встроенные объекты

Zabbix

Объект Zabbix даёт возможность взаимодействия с внутренним функционалом Zabbix.

Метод Описание
log(уровень_журнала, сообщение) Записывает <сообщение> в журнал Zabbix с использованием уровня журнала <уровень_журнала> (смотрите параметр DebugLevel в файле конфигурации).

Пример:

Zabbix.log(3, "this is a log entry written with 'Warning' log level")

Вы можете использовать следующие псевдонимы:

Псевдоним Псевдоним к
console.log(объект) Zabbix.log(4, JSON.stringify(объект))
console.warn(объект) Zabbix.log(3, JSON.stringify(объект))
console.error(объект) Zabbix.log(2, JSON.stringify(объект))

Суммарный размер всех записываемых в журнал сообщений ограничен величиной 8 мегабайт на выполняемый скрипт.

Метод Описание
sleep(задержка) Задержка выполнения JavaScript на задержка миллисекунд.

Пример (задержка выполнения на 15 секунд):

Zabbix.sleep(15000)

HttpRequest

Этот объект инкапсулирует дескриптор cURL и позволяет выполнять простые HTTP-запросы. Ошибки вызываются как исключения.

Инициализация нескольких объектов HttpRequest ограничена 10 объектами за одно выполнение скрипта.

Method Description
addHeader(value) Добавляет поле HTTP-заголовка. Это поле используется для всех последующих запросов, пока не будет очищено с помощью метода clearHeader().
Общая длина полей заголовка, которые можно добавить в один объект HttpRequest, ограничена 128 Кбайт (включая специальные символы и имена заголовков).
clearHeader() Очищает HTTP-заголовок. Если поля заголовка не заданы, HttpRequest установит Content-Type в application/json, если отправляемые данные имеют формат JSON; в противном случае будет установлен text/plain.
connect(url) Отправляет HTTP-запрос CONNECT по указанному URL и возвращает ответ.
customRequest(method, url, data) Позволяет указать любой HTTP-метод в первом параметре. Отправляет запрос указанного метода по URL с необязательной полезной нагрузкой data и возвращает ответ.
delete(url, data) Отправляет HTTP-запрос DELETE по URL с необязательной полезной нагрузкой data и возвращает ответ.
getHeaders(<asArray>) Возвращает объект полученных полей HTTP-заголовков.
Параметру asArray можно задать значение "true" (например, getHeaders(true)), "false" или оставить его неопределённым. Если задано значение "true", значения полученных полей HTTP-заголовков возвращаются в виде массивов; этот вариант следует использовать для получения значений нескольких заголовков с одинаковым именем.
Если параметр не задан или имеет значение "false", значения полученных полей HTTP-заголовков возвращаются в виде строк.
get(url, data) Отправляет HTTP-запрос GET по URL с необязательной полезной нагрузкой data и возвращает ответ.
head(url) Отправляет HTTP-запрос HEAD по URL и возвращает ответ.
options(url) Отправляет HTTP-запрос OPTIONS по URL и возвращает ответ.
patch(url, data) Отправляет HTTP-запрос PATCH по URL с необязательной полезной нагрузкой data и возвращает ответ.
put(url, data) Отправляет HTTP-запрос PUT по URL с необязательной полезной нагрузкой data и возвращает ответ.
post(url, data) Отправляет HTTP-запрос POST по URL с необязательной полезной нагрузкой data и возвращает ответ.
getStatus() Возвращает код состояния последнего HTTP-запроса.
setProxy(proxy) Устанавливает HTTP-прокси в значение "proxy". Если этот параметр пуст, прокси не используется.
setHttpAuth(bitmask, username, password) Устанавливает разрешённые методы HTTP-аутентификации (HTTPAUTH_BASIC, HTTPAUTH_DIGEST, HTTPAUTH_NEGOTIATE, HTTPAUTH_NTLM, HTTPAUTH_NONE) в параметре 'bitmask'.
Флаг HTTPAUTH_NONE позволяет отключить HTTP-аутентификацию.
Примеры:
request.setHttpAuth(HTTPAUTH_NTLM | HTTPAUTH_BASIC, username, password)
request.setHttpAuth(HTTPAUTH_NONE)
trace(url, data) Отправляет HTTP-запрос TRACE по URL с необязательной полезной нагрузкой data и возвращает ответ.

Пример:

try {
    Zabbix.log(4, 'jira webhook script value='+value);

    var result = {
        'tags': {
            'endpoint': 'jira'
        }
    },
    params = JSON.parse(value),
    req = new HttpRequest(),
    fields = {},
    resp;

    req.addHeader('Content-Type: application/json');
    req.addHeader('Authorization: Basic '+params.authentication);

    fields.summary = params.summary;
    fields.description = params.description;
    fields.project = {"key": params.project_key};
    fields.issuetype = {"id": params.issue_id};
    resp = req.post('https://jira.example.com/rest/api/2/issue/',
        JSON.stringify({"fields": fields})
    );

    if (req.getStatus() != 201) {
        throw 'Response code: '+req.getStatus();
    }

    resp = JSON.parse(resp);
    result.tags.issue_id = resp.id;
    result.tags.issue_key = resp.key;
} catch (error) {
    Zabbix.log(4, 'jira issue creation failed json : '+JSON.stringify({"fields": fields}));
    Zabbix.log(4, 'jira issue creation failed : '+error);

    result = {};
}

return JSON.stringify(result);

XML

Объект XML позволяет обрабатывать XML данные в элементах данных и в предварительной обработке низкоуровневых обнаружений, а также в вебхуках.

Чтобы использовать объект XML, сервер/прокси должны быть скомпилированы с поддержкой libxml2.

Метод Описание
XML.query(данные, выражение) Получение содержимого узла с использованием XPath. Возвращает null, если узел не найден.
выражение — выражение XPath;
данные — данные XML в виде строки.
XML.toJson(данные) Преобразование данных в XML формате в JSON.
XML.fromJson(данные) Преобразование данных в JSON формате в XML.

Пример:

Входящие данные:

<menu>
    <food type = "breakfast">
        <name>Chocolate</name>
        <price>$5.95</price>
        <description></description>
        <calories>650</calories>
    </food>
</menu>

Вывод:

{
    "menu": {
        "food": {
            "@type": "breakfast",
            "name": "Chocolate",
            "price": "$5.95",
            "description": null,
            "calories": "650"
        }
    }
}
Правила сериализации

Преобразование XML в JSON обрабатывается в соответствии со следующими правилами (для преобразования JSON в XML применяются обратные правила):

1. Атрибуты XML преобразуются в ключи, имеющие в своих именах префикс '@'.

Пример:

Входящие данные:

<xml foo="FOO">
  <bar>
    <baz>BAZ</baz>
  </bar>
</xml>

Вывод:

{
  "xml": {
    "@foo": "FOO",
    "bar": {
      "baz": "BAZ"
    }
  }
}

2. Элементы, которые закрываются в самих себе (<foo/>), будут преобразованы как имеющие значение «null».

Пример:

Входящие данные:

<xml>
  <foo/>
</xml>

Вывод:

{
  "xml": {
    "foo": null
  }
}

3. Пустые атрибуты (со значением "") будут преобразованы как имеющие значение пустой строки ('').

Пример:

Входящие данные:

<xml>
  <foo bar="" />
</xml>

Вывод:

{
  "xml": {
    "foo": {
      "@bar": ""
    }
  }
}

4. Несколько дочерних узлов с идентичными именами элементов будут преобразованы в один ключ, который имеет массив значений в качестве своего значения.

Пример:

Входящие данные:

<xml>
  <foo>BAR</foo>
  <foo>BAZ</foo>
  <foo>QUX</foo>
</xml>

Вывод:

{
  "xml": {
    "foo": ["BAR", "BAZ", "QUX"]
  }
}

5. Если текстовый элемент не имеет атрибутов и дочерних элементов, он будет преобразован в строку.

Пример:

Входящие данные:

<xml>
    <foo>BAZ</foo>
</xml>

Вывод:

{
  "xml": {
    "foo": "BAZ"
   }
}

6. Если текстовый элемент не имеет дочерних элементов, но имеет атрибуты, то текстовое содержимое будет преобразовано в элемент с ключом «#text» и содержимым в виде значения; атрибуты будут преобразованы в соответствии с правилом сериализации 1.

Пример:

Входящие данные:

<xml>
  <foo bar="BAR">
    BAZ
  </foo>
</xml>

Вывод:

{
  "xml": {
    "foo": {
      "@bar": "BAR",
      "#text": "BAZ"
    }
  }
}

Глобальные функции JavaScript

В Duktape реализованы дополнительные глобальные функции JavaScript:

  • btoa(data) - кодирует данные в строку base64.
  • atob(base64_string) - декодирует строку base64 в буфер Uint8Array.
try {
    b64 = btoa("test string");
    buffer = atob(b64);

    // Обратите внимание, что логика декодирования зависит от формата данных буфера.
    decoded = String.fromCharCode.apply(this, [].slice.call(buffer));
} 
catch (error) {
    return {'error.name' : error.name, 'error.message' : error.message};
}
  • md5(data) - вычисляет MD5-хэш данных.
  • sha256(data) - вычисляет SHA256-хэш данных.
  • hmac('<hash type>',key,data) - возвращает HMAC-хэш в виде строки в шестнадцатеричном формате; в качестве hash type поддерживаются md5 и sha256; параметры key и data поддерживают двоичные данные.

    Примеры:

    • hmac('md5',key,data)
    • hmac('sha256',key,data)
  • sign(hash,key,data) - возвращает вычисленную подпись (RSA-подпись с SHA-256) в виде строки, где:
    hash - допускается только sha256, в противном случае будет выдана ошибка.
    key - закрытый ключ. Он должен соответствовать стандарту PKCS#1 или PKCS#8. Ключ может быть предоставлен в разных формах:

    • с пробелами вместо символов новой строки
    • с экранированными или неэкранированными \n вместо символов новой строки
    • без каких-либо символов новой строки, в виде строки в одну строку
    • в виде строки в формате JSON

    Ключ также может быть загружен из пользовательского макроса/секретного макроса/vault.

    data - данные, которые будут подписаны. Это может быть строка (также поддерживаются двоичные данные) или буфер (Uint8Array/ArrayBuffer).

    Пример:

    • sign('sha256',key,data)

    Для вычисления подписей используется OpenSSL или GnuTLS. Если Zabbix был собран без какой-либо из этих криптографических библиотек, будет выдана ошибка ('missing OpenSSL or GnuTLS library').