Consumindo a API do Zabbix com lld e item http
Em alguns momentos temos a necessidade de obter alguma métrica do Zabbix que não esta disponível em forma de itens nativos na ferramenta, é ai que entra a API do Zabbix e toda a sua flexibilidade, uma forma possível de consumir a API do Zabbix é utilizando uma estrutura de lld com item http.
Esse método possui limitações, não sendo possível encadear consultas utilizando respostas de consultas anteriores como parâmetros, sendo necessário ser possível obter toda a informação em uma única consulta.
Com a chegada dos itens do tipo javascript na versão 5.2 esse método caiu em desuso, porém não deixa de ser uma forma interessante e engenhosa que pode ser útil em alguns casos.
O Zabbix possui uma api JSON RPC que possui um único endpoint para interação, toda a configuração da requisição é passada para API através do payload, a partir da versão 5.4 o Zabbix passou a permitir a criação de tokens de API ZBXNEXT-6207, na atual versão LTS 5.0 ainda é necessário realizar autenticação para obter um token.
É ai que entra a utilização do LLD, a ideia é utilizá-lo para obter um token que será utilizado pelos seus protótipos de itens, obviamente com a limitação de poder realizar uma única request, pois ainda não é possível a criação de LLDs encadeados, futuramente talvez isso se torne possível ZBXNEXT-1527.
Para esse post vou utilizar o ambiente mantido pelo Isaque Profeta, que pode ser obtido em seu repositório github. Muito útil para subirmos um ambiente de testes rapidamente.
Criando a regra de descoberta
O primeiro passo então é criar uma regra LLD para obtenção do token de acesso, vamos utilizar um http item para isso, passando os parâmetros necessários via body em uma requisição POST.
Atentar para o Request Type ser do tipo POST e o body conforme abaixo.
{
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"user": "Admin",
"password": "zabbix"
},
"id": 1,
"auth": null
}
Essa requisição de autenticação a API retorna um objeto informando o token na chave result, como abaixo.
{
"jsonrpc": "2.0",
"result": "0424bd59b807674191e7d77572075f33",
"id": 1
}
Como estamos trabalhando com um LLD, esse retorno resultaria em um erro, pois todo LLD pressupõe a existência de um array, existe um loop intrínseco em um LLD que vai percorrer todos os elementos de um array e executar a criação de todos os seus protótipos para cada elemento encontrado. Em nosso cenário, estamos interessados apenas na obtenção do token, nesse caso vamos precisar pré processar esse objeto transformando ele em um array de apenas um objeto para “enganar” nosso LLD.
Na aba Preprocessing vamos utilizar uma etapa do tipo javascript, como na imagem abaixo.
O código utilizado no pre processamento é o abaixo.
var data = []
valor = JSON.parse(value)
data.push(valor)
return JSON.stringify(data)
O que estamos fazendo aqui é basicamente criando um array, fazendo um parse do JSON contido em value e transformando em um objeto javascript, posteriormente adicionamos esse objeto a um array e retornamos esse array em forma de string JSON novamente.
Sempre que estiver trabalhando com JSON, esses passos de realizar o parse e posteriormente o stringify serão comuns, é a forma utilizada em javascript de transformar um JSON, que nada mais é que uma string com uma formatação específica, em uma estrutura de dados interna da linguagem.
O resultado dessa etapa deverá ser basicamente um array com um único objeto dentro, onde na chave result desse objeto temos o token de autenticação que deverá ser utilizado nas próximas consultas. O próximo passo é capturar as chaves necessárias do JSON em Macros LLD. Vamos utilizar um JSONPath bem simples para isso que deverá ser configurado na aba LLD macros
Com isso terminamos a etapa do discovery e podemos partir para a configuração do protótipo de item que irá realizar uma consulta útil em nossa API.
Criando o protótipo de item
Para esse exemplo vou realizar uma consulta simples para obter a quantidade de hosts total no Zabbix, o payload necessário para essa consulta é o abaixo.
{
"jsonrpc": "2.0",
"method": "host.get",
"params": {
"countOutput":"True"
},
"auth": "{#TOKEN}",
"id": 1
}
Como o Zabbix é uma API de um único endpoint, as requisições são sempre POST para a mesma URL, mudando apenas o payload entre uma e outra. Vamos então criar o protótipo de item.
Atenção para a key, nesse cenários estamos utilizando a macro LLD {#ID} obtida na autenticação, dessa forma nosso item vai sempre continuar o mesmo, atualizando apenas o token quando a regra LLD rodar novamente.
No payload vamos utilizar a consulta propriamente dita passando a macro LLD que representa o token capturado na etapa de autenticação {#TOKEN}.
Como o retorno dessa consulta será um número, podemos configurar nosso item para Numeric (unsigned), porém antes precisamos pre processar essa resposta, pois o valor estará contido dentro de um JSON de resposta na chave result.
Com o pré processamento acima capturamos apenas o valor numérico retornado pela API contido na chave result.
O resultado é um item que captura a quantidade de hosts existentes no Zabbix.
Conclusão
Nesse post demonstrei como realizar consultas a API do Zabbix utilizando uma regra LLD e protótipos de itens, poderão ser criados quantos protótipos de itens forem necessários, todos eles vão utilzar o token armazenado na macro LLD {#TOKEN}, não esquecer de definir uma valor compartível com a expiração do token em seu ambiente para a execução da regra de descoberta.
Lembrando que uma das limitações desse método é estar condicionado a realizar apenas uma consulta a API, não sendo possível utilizar essa resposta como parâmetro para uma segunda consulta.