Olá pessoal!
Esta demanda surgiu pela necessidade constante de inserção de equipamentos de rede nas configurações do Nagios e como a equipe de Redes sempre enviava as informações no mesmo padrão, pensamos em gerar algo que lê-se esse arquivo e criasse tudo analisando cada cenário, ou seja, dependendo das informações passadas as dependências mudariam.
O script foi desenvolvido para automatizar a criação dos arquivos de configuração do Nagios (links, firewall e switchs). É feita a leitura de um arquivo csv e a partir daí o script valida as informações (por exemplo, se o IP possui um formato válido) e cria os arquivo de configuração, levando também em consideração alguns critérios de dependência (aqui utilizamos o recurso parents do Nagios) e condições de existência ou não de certos objetos.
Exemplo de csv:
LOCAL;SERVIDOR;LINK A LAN;LINK B LAN;LINK A WAN;LINK B WAN;FIREWALL INT;FIREWALL EXT;SWITCH 1;SWITCH 2;SWITCH 3;SWITCH 4;SWITCH 5;SWITCH 6;SWITCH 7;SWITCH 8
local0001;111.111.111.111;222.222.222.222;333.333.333.333;444.444.444.444;555.555.555.555;NÃO POSSUI;NÃO POSSUI;666.666.666.666;777.777.777.777;888.888.888.888;NÃO POSSUI;NÃO POSSUI;NÃO POSSUI;NÃO POSSUI;NÃO POSSUI
Para melhor entendimento do processo, desenhamos um fluxo:
Vou mostrar pedaços do script para explicar suas funções e ao final disponibilizarei o link para o meu repositório no GitHub onde o mesmo pode ser encontrado de forma completa.
Passo 1 – Fazer a leitura do arquivo e validá-lo.
LISTA="$1" DIR=/usr/local/nagios/etc/config #Local onde os arquivos do Nagios serão criados tr -cd "[:digit:][:punct:]\n" < /tmp/lista.txt > /tmp/lista_tratada.txt #Primeiro tratamento da lista para remoção de caracteres indesejados. sed -i -e 's/\.0\|\.00/./g' /tmp/lista_tratada.txt #Segundo tratamento, para ajuste do formato enviado para o padrão de IP. # Exemplo de csv #Local;SERVIDOR;LINK A LAN;LINK B LAN;LINK A WAN;LINK B WAN;FIREWALL INT;FIREWALL EXT;SWITCH 1;SWITCH 2;SWITCH 3;SWITCH 4;SWITCH 5;SWITCH 6;SWITCH 7;SWITCH 8 #Local0012;52.1.4.1;52.1.4.16;52.1.4.17;200.179.63.66;100.126.56.30;NÃO POSSUI;NÃO POSSUI;52.1.4.5;52.1.4.6;52.1.4.7;NÃO POSSUI;NÃO POSSUI;NÃO POSSUI;NÃO POSSUI;NÃO POSSUI
Passo 2 – Destrinchar o arquivo e chamar as devidas funções, passando como parâmetro esses dados que foram separados.
for LINHA in $(cat /tmp/lista_tratada.txt); do #Loop para tratar o arquivo LC=$(echo ${LINHA} |cut -d';' -f1) #Obtedo o primeiro campo antes do ; [ "${#LC}" -eq 3 ] && LC="0${LC}" #Ajustes de nomeclatura [ "${#LC}" -eq 2 ] && LC="00${LC}" [ "${#LC}" -eq 1 ] && LC="000${LC}" SERVIDOR=$(echo ${LINHA} |cut -d';' -f2) #Obtedo o segundo campo e os demais seguem o mesmo padrão LinkAWAN=$(echo ${LINHA} |cut -d';' -f5) valida_ip ${LinkAWAN} # Chama a função que valida os IPs LinkAWAN=`echo ${IP}` # O resultado da validação é passado a variável. LinkBWAN=$(echo ${LINHA} |cut -d';' -f6) valida_ip ${LinkBWAN} LinkBWAN=`echo ${IP}` FW=$(echo ${LINHA} |cut -d';' -f8) SW1=$(echo ${LINHA} |cut -d';' -f9) SW2=$(echo ${LINHA} |cut -d';' -f10) SW3=$(echo ${LINHA} |cut -d';' -f11) SW4=$(echo ${LINHA} |cut -d';' -f12) SW5=$(echo ${LINHA} |cut -d';' -f13) SW6=$(echo ${LINHA} |cut -d';' -f14) SW7=$(echo ${LINHA} |cut -d';' -f15) SW8=$(echo ${LINHA} |cut -d';' -f16) LinkAWAN > ${DIR}/link_do_Local/LinkA_Local${LC}.cfg # Aqui já temos o início da criação dos arquivos, pois a saída de resultado da função gera o arquivo que queremos. LinkBWAN > ${DIR}/link_do_Local/LinkB_Local${LC}.cfg . . .
Passo 3 – Aqui vou mostrar um pedacinho de algumas das funções que foram chamadas no laço anterior.
function valida_ip() { echo "${1}" | grep -E '([0-9]{1,3}\.)' validacao=$? if [ "${validacao}" != 0 ] then IP=`echo "${1}" | sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/;ta' | sed -e 's/\.0\|\.00/./g'` else IP=`echo "${1}"` fi }
Aqui temos as funções para a montagem dos arquivos, respeitando indentação e tal.
function LinkAWAN() { echo "define host{" echo " use linux-server" echo " hostgroups Link" echo " host_name LinkA_Local"${LC} echo " alias Local"${LC}"_LinkA" echo " address "${LinkAWAN} echo " }" echo " " echo "define service{" echo " use local-service" echo " host_name LinkA_Local"${LC} echo " service_description Ping" echo " check_command check_ping!100.0,20%!500.0,60%" echo " }" } function Firewall() { echo "define host{" echo " use linux-server" echo " hostgroups Firewall" echo " host_name FW_Local"${LC} echo " alias FW_Local"${LC} echo " address "${FW} echo " parents LinkA_Local"${LC}",LinkB_Local"${LC} echo " }" echo " " echo "define service{" echo " use local-service" echo " host_name FW_Local"${LC} echo " service_description Ping" echo " check_command check_ping!100.0,20%!500.0,60%" echo " }" echo " " } function Switch_fw() { echo "define host{" echo " use linux-server" echo " hostgroups Switch" echo " host_name "${switch}"_Local"${LC} echo " alias Local"${LC}"_"${switch} echo " address "${SW} echo " parents FW_Local"${LC} echo " }" echo " " echo "define service{" echo " use local-service" echo " host_name "${switch}"_Local"${LC} echo " service_description Ping" echo " check_command check_ping!100.0,20%!500.0,60%" echo " }" echo " " }
Passo 4 – E por fim, o bloco condicional que nos ajuda a criar as diferentes dependências, chamando as funções necessárias para cada estrutura. É aqui que crio arquivos com base no fluxo que mostrei anteriormente.
if [ -n "${FW}" ] # then Firewall > ${DIR}/firewall/FW_Local${LC}.cfg if [ -n "${SW1}" ] then switch="SW1" SW="${SW1}" Switch_fw > ${DIR}/switch/${switch}_Local${LC}.cfg . . . else if [ -n "${SW1}" ] then switch="SW1" SW="${SW1}" Switch_link > ${DIR}/switch/${switch}_Local${LC}.cfg fi . . .
Espero que tenham gostado, neste posta ao invés de mostrar o script todo como já fiz antes, preferi ir mostrando aos poucos e explicando cada função.
O script completo está aqui:
https://github.com/carolinux07/Shell-Script
Quero aproveitar pra fazer um agradecimento mais que especial para duas pessoas que me ajudaram na elaboração desse script.
Felipe Motta – https://www.linkedin.com/in/felipemottamendes/
Esse cara me ajudou d+ a aprimorar esse meu gosto por automatizar soluções e me mostrou o quanto é importante ter senso crítico e analisar a melhor maneira de sermos produtivos, não importando o quão pequena é a atividade, se a mesma é executada repetidamente então pode e dever ser automatizada. Além, é claro, de me mostrar o quão adaptável pode ser o Nagios num ambiente de monitoramento tão específico quanto era o que trabalhávamos. Cresci d+ profissionalmente por causa dele.
Agapito Rojas – https://www.linkedin.com/in/agapitorojas/
Tá aí um rapaz sagaz, tudo ele tem uma visão e solução diferente de nós “meros mortais” rsrs. Mas é sério, sempre irreverente e com grandes soluções, me ajudou muito a buscar comandos e parâmetros que me fizessem pensar “fora da caixinha”. Esse aí foi o responsável por me fazer querer estudar cada vez mais, tipo, estudar um comando qualquer se tornou pouco, tinha que destrinchar o comando e tirar o melhor dele. Tô até lendo RFC, pode isso?
Então é isso, esse post além de ser para compartilhar uma solução, também é para agradecer essa galera.
Vlw!
Documentação do recurso parents do Nagios:
https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/3/en/networkreachability.html