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






