From 634cfee7744510949cd403a1e03b9adca64e3740 Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Wed, 22 Apr 2020 11:59:41 +0200 Subject: [PATCH] Writing of ospf and bgp roles --- evolixisation.yml | 3 + roles/bgp/README.md | 14 ++ roles/bgp/defaults/main.yml | 3 + roles/bgp/tasks/main.yml | 35 +++++ roles/bgp/templates/bgpd-check-peers.sh.j2 | 117 ++++++++++++++++ roles/ospf/README.md | 14 ++ roles/ospf/defaults/main.yml | 3 + roles/ospf/tasks/main.yml | 22 +++ roles/ospf/templates/ospf6d-check-peers.sh.j2 | 126 +++++++++++++++++ roles/ospf/templates/ospfd-check-peers.sh.j2 | 127 ++++++++++++++++++ 10 files changed, 464 insertions(+) create mode 100644 roles/bgp/README.md create mode 100644 roles/bgp/defaults/main.yml create mode 100644 roles/bgp/tasks/main.yml create mode 100755 roles/bgp/templates/bgpd-check-peers.sh.j2 create mode 100644 roles/ospf/README.md create mode 100644 roles/ospf/defaults/main.yml create mode 100644 roles/ospf/tasks/main.yml create mode 100755 roles/ospf/templates/ospf6d-check-peers.sh.j2 create mode 100755 roles/ospf/templates/ospfd-check-peers.sh.j2 diff --git a/evolixisation.yml b/evolixisation.yml index df88a4c..0f0f242 100644 --- a/evolixisation.yml +++ b/evolixisation.yml @@ -16,6 +16,7 @@ vars_files: - vars/main.yml # - vars/secrets.yml +# - vars/openbsd-secret.yml roles: - etc-git @@ -26,6 +27,8 @@ - nagios-nrpe - post-install #- openvpn + #- ospf + #- bgp post_tasks: - include: "tasks/commit_etc_git.yml" diff --git a/roles/bgp/README.md b/roles/bgp/README.md new file mode 100644 index 0000000..51aad44 --- /dev/null +++ b/roles/bgp/README.md @@ -0,0 +1,14 @@ +# BGP + +Deployment of BGP check script with its cron, and a best route log cron. + +## Tasks + +Everything is in the `tasks/main.yml` file. + +## Available variables + +The full list of variables (with default values) can be found in `defaults/main.yml`. + +* `bgp_mailto` : email address the output of the script will be sent to when a change is detected +* `bgp_exclude_grep_command` : facultative grep -v command for some peers not to be checked diff --git a/roles/bgp/defaults/main.yml b/roles/bgp/defaults/main.yml new file mode 100644 index 0000000..8279e96 --- /dev/null +++ b/roles/bgp/defaults/main.yml @@ -0,0 +1,3 @@ +--- +bgp_mailto: "foobar@example.com" +bgp_exclude_grep_command: "" diff --git a/roles/bgp/tasks/main.yml b/roles/bgp/tasks/main.yml new file mode 100644 index 0000000..2196dc6 --- /dev/null +++ b/roles/bgp/tasks/main.yml @@ -0,0 +1,35 @@ +--- +- name: Deploy bgp check script + template: + src: bgpd-check-peers.sh.j2 + dest: /usr/share/scripts/bgpd-check-peers.sh + when: group_names | select('search','bgp') | list | count > 0 + tags: + - bgp + +- name: Cron job for bgp check script is installed + cron: + name: bgp check + job: "/bin/sh /usr/share/scripts/bgpd-check-peers.sh" + when: group_names | select('search','bgp') | list | count > 0 + tags: + - bgp + +- name: Create bgp log directory + file: + path: /var/log/bgp + state: directory + when: group_names | select('search','bgp') | list | count > 0 + tags: + - bgp + +- name: weekly best routes cron job is installed + cron: + name: bgp best routes + minute: 0 + hour: 4 + weekday: 0 + job: "/usr/sbin/bgpctl show rib selected > /var/log/bgp/rib-selected-$(date +%F)" + when: group_names | select('search','bgp') | list | count > 0 + tags: + - bgp diff --git a/roles/bgp/templates/bgpd-check-peers.sh.j2 b/roles/bgp/templates/bgpd-check-peers.sh.j2 new file mode 100755 index 0000000..250ed54 --- /dev/null +++ b/roles/bgp/templates/bgpd-check-peers.sh.j2 @@ -0,0 +1,117 @@ +#!/bin/ksh + +# Script writen by Daniel Jakots + +# First we go through the list of neighbor and we write all the peer and +# their status in "${_TMPDIR}"/bgp-status. + +# Then we monitor if this file has changed between now and the previous run. + +# If it did, we send a mail with the states of the different sessions. + +set -u + +PATH=$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:. + +_MAILTO="{{ bgp_mailto }}" +_TMPDIR=/tmp/check-bgp +_PIDFILE="${_TMPDIR}"/bgpd-check-peers.pid + + +if [ -e /etc/realname ]; then + _REALNAME=$(cat /etc/realname) + _HOSTNAME=$(hostname -s) +else + _HOSTNAME=$(hostname) +fi + +mkdir -p "${_TMPDIR}" + +# Don't try to run if it's already running +if [ -e "${_PIDFILE}" ]; then + echo "$(date)" >> "${_TMPDIR}"/log + exit 1 +else + echo $$ >> "${_PIDFILE}" +fi + +# Create an history +if [[ -f "${_TMPDIR}"/bgp-status ]] ; then + mv "${_TMPDIR}"/bgp-status "${_TMPDIR}"/bgp-status.old +else + touch "${_TMPDIR}"/bgp-status + touch "${_TMPDIR}"/bgp-status.old +fi + +# List peers and loops on them to list them and their BGP state +bgpctl show neighbor | grep Description {{ bgp_exclude_grep_command }} | sed s,\ Description:\ ,,g > "${_TMPDIR}"/peers-list + +while read _PEER +do + _STATUS=$(/usr/sbin/bgpctl show neighbor "${_PEER}" | grep state | awk '{print $4}' |tr -d ',') + echo -n "${_PEER}" >> "${_TMPDIR}"/bgp-status + echo -n " " >> "${_TMPDIR}"/bgp-status + # we note only if it's established or not + if ! [[ "${_STATUS}" = "Established" ]] ; then + _STATUS="NotEstablished" + fi + echo "${_STATUS}" >> "${_TMPDIR}"/bgp-status + +done <"${_TMPDIR}"/peers-list + +# Check for difference with previous run +different=$(diff -q "${_TMPDIR}"/bgp-status.old "${_TMPDIR}"/bgp-status) + +if ! [[ -n "${different}" ]] ; then + rm -f "${_PIDFILE}" + exit 0 +fi + +# It changed so we're going to send a mail + +_TMPMAILDIR="${_TMPDIR}"/mail +mkdir -p "${_TMPMAILDIR}" + +# go through sessions and list them depending on their BGP state +echo "*** Session(s) OK ***\n" >> "${_TMPMAILDIR}"/bodyok +while read _LINE +do + # _LINE is session + status + _STATUS=$(echo "${_LINE##* }") + _SESSION=$(echo "${_LINE}" | awk '{$NF=""}1') + if [[ "${_STATUS}" = "Established" ]] ; then + bgpctl show | grep "${_SESSION}" >> "${_TMPMAILDIR}"/bodyok + else + bgpctl show | grep "${_SESSION}" >> "${_TMPMAILDIR}"/bodynok + fi +done <"${_TMPDIR}"/bgp-status + +# create the mail body + +echo "Dear NOC,\n\nThe state of one or more BGP session(s) has changed:\n" > "${_TMPMAILDIR}"/header +cat "${_TMPMAILDIR}"/header "${_TMPMAILDIR}"/bodyok > "${_TMPMAILDIR}"/body + +_STATE="OK" +if [[ -f "${_TMPMAILDIR}"/bodynok ]] ; then + _STATE="NOT OK" + echo "\n*** Session(s) on error ***\n" >> "${_TMPMAILDIR}"/body + cat "${_TMPMAILDIR}"/bodynok >> "${_TMPMAILDIR}"/body +fi + +# show a diff +echo "" >> "${_TMPMAILDIR}"/body +echo "Diff is " >> "${_TMPMAILDIR}"/body +diff -U0 "${_TMPDIR}"/bgp-status.old "${_TMPDIR}"/bgp-status >> "${_TMPMAILDIR}"/body + +# Send the mail whether we have a realname or not +if [ -n "${_REALNAME}" ]; then + cat "${_TMPMAILDIR}"/body | mail -s "[BGP] ${_REALNAME} (${_HOSTNAME}) - State change - ${_STATE}" "${_MAILTO}" +else + cat "${_TMPMAILDIR}"/body | mail -s "[BGP] ${_HOSTNAME} - State change" "${_MAILTO}" +fi + +# cleaning +if [[ -d "${_TMPMAILDIR}" ]] ; then + rm -rf "${_TMPMAILDIR}" +fi +rm -f "${_PIDFILE}" diff --git a/roles/ospf/README.md b/roles/ospf/README.md new file mode 100644 index 0000000..f0e929c --- /dev/null +++ b/roles/ospf/README.md @@ -0,0 +1,14 @@ +# OSPF + +Deployment of OSPF check scripts with their cron. + +## Tasks + +Everything is in the `tasks/main.yml` file. + +## Available variables + +The full list of variables (with default values) can be found in `defaults/main.yml`. + +* `ospf_mailto` : email address the output of the scripts will be sent to when a change is detected +* `ospf_sed_command` : facultative sed command to modify the ospfctl output and add a name to IPs diff --git a/roles/ospf/defaults/main.yml b/roles/ospf/defaults/main.yml new file mode 100644 index 0000000..098bef5 --- /dev/null +++ b/roles/ospf/defaults/main.yml @@ -0,0 +1,3 @@ +--- +ospf_mailto: "foobar@example.com" +ospf_sed_command: "" diff --git a/roles/ospf/tasks/main.yml b/roles/ospf/tasks/main.yml new file mode 100644 index 0000000..aa04759 --- /dev/null +++ b/roles/ospf/tasks/main.yml @@ -0,0 +1,22 @@ +--- +- name: Deploy ospf check scripts + template: + src: "{{ item }}.j2" + dest: /usr/share/scripts/{{ item }} + with_items: + - "ospfd-check-peers.sh" + - "ospf6d-check-peers.sh" + when: group_names | select('search','ospf') | list | count > 0 + tags: + - ospf + +- name: Cron job for ospf check scripts is installed + cron: + name: "{{ item }} check" + job: "/bin/sh /usr/share/scripts/{{ item }}-check-peers.sh" + with_items: + - ospfd + - ospf6d + when: group_names | select('search','ospf') | list | count > 0 + tags: + - ospf diff --git a/roles/ospf/templates/ospf6d-check-peers.sh.j2 b/roles/ospf/templates/ospf6d-check-peers.sh.j2 new file mode 100755 index 0000000..2c1d294 --- /dev/null +++ b/roles/ospf/templates/ospf6d-check-peers.sh.j2 @@ -0,0 +1,126 @@ +#!/bin/ksh + +# Script writen by Daniel Jakots for BGP, adapted by Jeremy Dubois for OSPF + +# First we go through the list of neighbor and we write all the peer and +# their status in "${_TMPDIR}"/ospf6-status. + +# Then we monitor if this file has changed between now and the previous run. + +# If it did, we send a mail with the states of the different sessions. + +set -u + +PATH=$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:. + +_MAILTO="{{ ospf_mailto }}" +_TMPDIR=/tmp/check-ospf6 +_PIDFILE="${_TMPDIR}"/ospf6d-check-peers.pid + + +if [ -e /etc/realname ]; then + _REALNAME=$(cat /etc/realname) + _HOSTNAME=$(hostname -s) +else + _HOSTNAME=$(hostname) +fi + +mkdir -p "${_TMPDIR}" + +# Don't try to run if it's already running +if [ -e "${_PIDFILE}" ]; then + echo "$(date)" >> "${_TMPDIR}"/log + exit 1 +else + echo $$ >> "${_PIDFILE}" +fi + +# Create an history +if [[ -f "${_TMPDIR}"/ospf6-status ]] ; then + mv "${_TMPDIR}"/ospf6-status "${_TMPDIR}"/ospf6-status.old +else + touch "${_TMPDIR}"/ospf6-status + touch "${_TMPDIR}"/ospf6-status.old +fi + +# List peers and loops on them to list them and their OSPF6 state +ospf6ctl show neighbor | grep -v "^$" | grep -v "Uptime" | awk {'print $1'} > "${_TMPDIR}"/peers-list + +while read _PEER +do + _STATUS=$(/usr/sbin/ospf6ctl show neighbor | grep "${_PEER} " | awk {'print $3'}) + echo -n "${_PEER}" >> "${_TMPDIR}"/ospf6-status + echo -n " " >> "${_TMPDIR}"/ospf6-status + if ([[ "${_STATUS}" = "FULL/BCKUP" ]] || [[ "${_STATUS}" = "FULL/DR" ]] || [[ "${_STATUS}" = "2-WAY/OTHER" ]] || [[ "${_STATUS}" = "FULL/OTHER" ]]) ; then + _STATUS="UP" + else + _STATUS="DOWN" + fi + echo "${_STATUS}" >> "${_TMPDIR}"/ospf6-status + +done <"${_TMPDIR}"/peers-list + +# Check for difference with previous run +different=$(diff -q "${_TMPDIR}"/ospf6-status.old "${_TMPDIR}"/ospf6-status) + +if ! [[ -n "${different}" ]] ; then + rm -f "${_PIDFILE}" + exit 0 +fi + +# It changed so we're going to send a mail + +_TMPMAILDIR="${_TMPDIR}"/mail +mkdir -p "${_TMPMAILDIR}" + +# go through sessions and list them depending on their OSPF6 state +echo "*** Session(s) OK ***\n" >> "${_TMPMAILDIR}"/bodyok +while read _LINE +do + # _LINE is session + status + _STATUS=$(echo "${_LINE}" | awk {'print $2'}) + _SESSION=$(echo "${_LINE}" | awk {'print $1'}) + if [[ "${_STATUS}" = "UP" ]] ; then + ospf6ctl show neighbor | grep "${_SESSION} " {{ ospf_sed_command }} >> "${_TMPMAILDIR}"/bodyok + else + ospf6ctl show neighbor | grep "${_SESSION} " {{ ospf_sed_command }} >> "${_TMPMAILDIR}"/bodynok + fi +done <"${_TMPDIR}"/ospf6-status + +# create the mail body + +echo "Dear NOC,\n\nThe state of one or more OSPF6 session(s) has changed:\n" > "${_TMPMAILDIR}"/header +cat "${_TMPMAILDIR}"/header "${_TMPMAILDIR}"/bodyok > "${_TMPMAILDIR}"/body + +_STATE="OK" +if [[ -f "${_TMPMAILDIR}"/bodynok ]] ; then + _STATE="NOT OK" + echo "\n*** Session(s) on error ***\n" >> "${_TMPMAILDIR}"/body + cat "${_TMPMAILDIR}"/bodynok >> "${_TMPMAILDIR}"/body +fi + +# Add some infos +echo "\n\n*** Known OSPF routes ***\n" >> "${_TMPMAILDIR}"/body +ospf6ctl show fib ospf >> "${_TMPMAILDIR}"/body + +echo "\n\n*** Network used memory ***\n" >> "${_TMPMAILDIR}"/body +netstat -m >> "${_TMPMAILDIR}"/body + +echo "\n\n*** Server load ***\n" >> "${_TMPMAILDIR}"/body +w >> "${_TMPMAILDIR}"/body + +echo "\n\n*** Processes ***\n" >> "${_TMPMAILDIR}"/body +top >> "${_TMPMAILDIR}"/body + +# Send the mail whether we have a realname or not +if [ -n "${_REALNAME}" ]; then + cat "${_TMPMAILDIR}"/body | mail -s "[OSPF6] ${_REALNAME} (${_HOSTNAME}) - State change - ${_STATE}" "${_MAILTO}" +else + cat "${_TMPMAILDIR}"/body | mail -s "[OSPF6] ${_HOSTNAME} - State change - ${_STATE}" "${_MAILTO}" +fi + +# cleaning +if [[ -d "${_TMPMAILDIR}" ]] ; then + rm -rf "${_TMPMAILDIR}" +fi +rm -f "${_PIDFILE}" diff --git a/roles/ospf/templates/ospfd-check-peers.sh.j2 b/roles/ospf/templates/ospfd-check-peers.sh.j2 new file mode 100755 index 0000000..ede2eec --- /dev/null +++ b/roles/ospf/templates/ospfd-check-peers.sh.j2 @@ -0,0 +1,127 @@ +#!/bin/ksh + +# Script writen by Daniel Jakots for BGP, adapted by Jeremy Dubois for OSPF + +# First we go through the list of neighbor and we write all the peer and +# their status in "${_TMPDIR}"/ospf-status. + +# Then we monitor if this file has changed between now and the previous run. + +# If it did, we send a mail with the states of the different sessions. + +set -u + +PATH=$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:. + +_MAILTO="{{ ospf_mailto }}" +_TMPDIR=/tmp/check-ospf +_PIDFILE="${_TMPDIR}"/ospfd-check-peers.pid + + +if [ -e /etc/realname ]; then + _REALNAME=$(cat /etc/realname) + _HOSTNAME=$(hostname -s) +else + _HOSTNAME=$(hostname) +fi + +mkdir -p "${_TMPDIR}" + +# Don't try to run if it's already running +if [ -e "${_PIDFILE}" ]; then + echo "$(date)" >> "${_TMPDIR}"/log + exit 1 +else + echo $$ >> "${_PIDFILE}" +fi + +# Create an history +if [[ -f "${_TMPDIR}"/ospf-status ]] ; then + mv "${_TMPDIR}"/ospf-status "${_TMPDIR}"/ospf-status.old +else + touch "${_TMPDIR}"/ospf-status + touch "${_TMPDIR}"/ospf-status.old +fi + +# List peers and loops on them to list them and their OSPF state +ospfctl show neighbor | grep -v "^$" | grep -v "Uptime" | awk {'print $1'} > "${_TMPDIR}"/peers-list + +while read _PEER +do + _STATUS=$(/usr/sbin/ospfctl show neighbor | grep "${_PEER} " | awk {'print $3'}) + echo -n "${_PEER}" >> "${_TMPDIR}"/ospf-status + echo -n " " >> "${_TMPDIR}"/ospf-status + if ([[ "${_STATUS}" = "FULL/BCKUP" ]] || [[ "${_STATUS}" = "FULL/DR" ]] || [[ "${_STATUS}" = "2-WAY/OTHER" ]] || [[ "${_STATUS}" = "FULL/OTHER" ]]) ; then + _STATUS="UP" + else + _STATUS="DOWN" + fi + echo "${_STATUS}" >> "${_TMPDIR}"/ospf-status + +done <"${_TMPDIR}"/peers-list + +# Check for difference with previous run +different=$(diff -q "${_TMPDIR}"/ospf-status.old "${_TMPDIR}"/ospf-status) + +if ! [[ -n "${different}" ]] ; then + rm -f "${_PIDFILE}" + exit 0 +fi + +# It changed so we're going to send a mail + +_TMPMAILDIR="${_TMPDIR}"/mail +mkdir -p "${_TMPMAILDIR}" + +# go through sessions and list them depending on their OSPF state +echo "*** Session(s) OK ***\n" >> "${_TMPMAILDIR}"/bodyok +while read _LINE +do + # _LINE is session + status + _STATUS=$(echo "${_LINE}" | awk {'print $2'}) + _SESSION=$(echo "${_LINE}" | awk {'print $1'}) + if [[ "${_STATUS}" = "UP" ]] ; then + ospfctl show neighbor | grep "${_SESSION} " {{ ospf_sed_command }} >> "${_TMPMAILDIR}"/bodyok + else + ospfctl show neighbor | grep "${_SESSION} " {{ ospf_sed_command }} >> "${_TMPMAILDIR}"/bodynok + fi +done <"${_TMPDIR}"/ospf-status + +# create the mail body + +echo "Dear NOC,\n\nThe state of one or more OSPF session(s) has changed:\n" > "${_TMPMAILDIR}"/header +cat "${_TMPMAILDIR}"/header "${_TMPMAILDIR}"/bodyok > "${_TMPMAILDIR}"/body + +_STATE="OK" +if [[ -f "${_TMPMAILDIR}"/bodynok ]] ; then + _STATE="NOT OK" + echo "\n*** Session(s) on error ***\n" >> "${_TMPMAILDIR}"/body + cat "${_TMPMAILDIR}"/bodynok >> "${_TMPMAILDIR}"/body +fi + +# Add some infos +echo "\n\n*** Known OSPF routes ***\n" >> "${_TMPMAILDIR}"/body +ospfctl show fib ospf >> "${_TMPMAILDIR}"/body + +echo "\n\n*** Network used memory ***\n" >> "${_TMPMAILDIR}"/body +netstat -m >> "${_TMPMAILDIR}"/body + +echo "\n\n*** Server load ***\n" >> "${_TMPMAILDIR}"/body +w >> "${_TMPMAILDIR}"/body + +echo "\n\n*** Processes ***\n" >> "${_TMPMAILDIR}"/body +top >> "${_TMPMAILDIR}"/body + + +# Send the mail whether we have a realname or not +if [ -n "${_REALNAME}" ]; then + cat "${_TMPMAILDIR}"/body | mail -s "[OSPF] ${_REALNAME} (${_HOSTNAME}) - State change - ${_STATE}" "${_MAILTO}" +else + cat "${_TMPMAILDIR}"/body | mail -s "[OSPF] ${_HOSTNAME} - State change - ${_STATE}" "${_MAILTO}" +fi + +# cleaning +if [[ -d "${_TMPMAILDIR}" ]] ; then + rm -rf "${_TMPMAILDIR}" +fi +rm -f "${_PIDFILE}"