#!/usr/bin/env bash script_name="$(basename $(realpath $0))" working_dir="$(dirname $(realpath $0))" conf_file="${working_dir}/conf/${script_name%%.*}.conf" LOCK_DIR="/tmp/${script_name%%.*}.LOCK" log_file="${LOCK_DIR}/${script_name%%.*}.log" # ---------- # Base Function(s) # ---------- usage() { [[ -n "$1" ]] && error "$1" [[ $terminal ]] && echo -e " \033[1mUsage:\033[m $(basename $0) [-b] \033[1mDescription\033[m Script changes munin server ips (IPv4 and IPv6) in munin and in firewall configuration. All parameters can be given interactivly if not running in batch mode. \033[1mOptions\033[m -b script acts in batch mode. All required parameters must be given in configuration filer -h Prints this help. \033[1mFiles\033[m $conf_file: Configuration file \033[1mExample:\033[m Change munin server ip addresses. \033[1m$(basename $0)\033[m Same, but act in batch mode \033[1m$(basename $0) -b\033[m " clean_up 1 } clean_up() { # Perform program exit housekeeping rm -rf "$LOCK_DIR" blank_line exit $1 } echononl(){ if $terminal ; then echo X\\c > /tmp/shprompt$$ if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then echo -e -n " $*\\c" 1>&2 else echo -e -n " $*" 1>&2 fi rm /tmp/shprompt$$ fi } fatal(){ echo "" if $terminal ; then echo -e " [ \033[31m\033[1mFatal\033[m ]: $*" echo "" echo -e " \033[31m\033[1mScript was interupted\033[m!" else echo " [ Fatal ]: $*" echo "" echo " Script was terminated...." fi echo "" clean_up 1 } error (){ echo "" if $terminal ; then echo -e " [ \033[31m\033[1mError\033[m ]: $*" else echo "[ Error ]: $*" fi echo "" } warn (){ echo "" if $terminal ; then echo -e " [ \033[33m\033[1mWarning\033[m ]: $*" else echo "[ Warning ]: $*" fi echo "" } warn_only_terminal () { if $terminal ; then echo "" echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" echo "" fi } info (){ if $terminal ; then echo "" echo -e " [ \033[32m\033[1mInfo\033[m ] $*" echo "" fi } ok (){ if $terminal ; then echo "" echo -e " [ \033[32m\033[1mOk\033[m ] $*" echo "" fi } echo_done() { if $terminal ; then echo -e "\033[75G[ \033[32mdone\033[m ]" fi } echo_ok() { if $terminal ; then echo -e "\033[75G[ \033[32mok\033[m ]" fi } echo_warn() { if $terminal ; then echo -e "\033[75G[ \033[33mwarn\033[m ]" fi } echo_failed(){ if $terminal ; then echo -e "\033[75G[ \033[1;31mfailed\033[m ]" fi } echo_skipped() { if $terminal ; then echo -e "\033[75G[ \033[90m\033[1mskipped\033[m ]" fi } echo_wait(){ if $terminal ; then echo -en "\033[75G[ \033[5m\033[1m...\033[m ]" fi } trim() { local var="$*" var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters echo -n "$var" } blank_line() { if $terminal ; then echo "" fi } containsElement () { local e for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done return 1 } is_number() { return $(test ! -z "${1##*[!0-9]*}" > /dev/null 2>&1); # - also possible # - #[[ ! -z "${1##*[!0-9]*}" ]] && return 0 || return 1 #return $([[ ! -z "${1##*[!0-9]*}" ]]) } is_valid_ipv4() { local -a octets=( ${1//\./ } ) local RETURNVALUE=0 # return an error if the IP doesn't have exactly 4 octets [[ ${#octets[@]} -ne 4 ]] && return 1 for octet in ${octets[@]} do if [[ ${octet} =~ ^[0-9]{1,3}$ ]] then # shift number by 8 bits, anything larger than 255 will be > 0 ((RETURNVALUE += octet>>8 )) else # octet wasn't numeric, return error return 1 fi done return ${RETURNVALUE} } # - Test if given argument is a valid IPv6 Address # - #is_valid_ipv6() { # local _ipv6=$1 # # if [ "$1" != "${1#[0-9a-f]*:}" ] \ # && [ "$1" = "${1#*[^0-9a-f:]}" ] \ # && [ "${1#*[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]}" = "${1#*:*:*:*:*:*:*:*:*:}" ]; then # return 0 # else # return 1 # fi #} is_valid_ipv6() { local _ipv6="$1" _regex_ipv6='^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$' if [[ "$_ipv6" =~ ${_regex_ipv6} ]]; then return 0 else return 1 fi } # ---------- # Some checks .. # ---------- # - Running in a terminal? # - if [[ -t 1 ]] ; then terminal=true else terminal=false BATCH_MODE=true fi # ---------- # Default Values # ---------- BATCH_MODE=false DEFAULT_MUNIN_CONF_FILE='/etc/munin/munin-node.conf' DEFAULT_IPT_FIREWALL_MAIN_IPV4_FILE='/etc/ipt-firewall/main_ipv4.conf' DEFAULT_IPT_FIREWALL_MAIN_IPV6_FILE='/etc/ipt-firewall/main_ipv6.conf' # ---------- # Read Configuration # ---------- if [[ -f "$conf_file" ]]; then source "$conf_file" else warn_only_terminal "No configuration file '$conf_file' present.\n Loading default values.." fi # ---------- # Read commandline parameter # ---------- while getopts bh opt ; do case $opt in b) BATCH_MODE=true ;; h) usage ;; \?) usage ;; esac done if [[ -n "${IPv4_ADDRESS_OLD}" ]] ; then _IPv4_ADDRESS_OLD="${IPv4_ADDRESS_OLD}" fi if [[ -n "${IPv6_ADDRESS_OLD}" ]] ; then _IPv6_ADDRESS_OLD="${IPv6_ADDRESS_OLD}" fi if [[ -n "${IPv4_ADDRESS_NEW}" ]] ; then _IPv4_ADDRESS_NEW="${IPv4_ADDRESS_NEW}" fi if [[ -n "${IPv6_ADDRESS_NEW}" ]] ; then _IPv6_ADDRESS_NEW="${IPv6_ADDRESS_NEW}" fi if [[ -z "${MUNIN_CONF_FILE}" ]]; then MUNIN_CONF_FILE="${DEFAULT_MUNIN_CONF_FILE}" fi if [[ -z "${IPT_FIREWALL_MAIN_IPV4_FILE}" ]]; then IPT_FIREWALL_MAIN_IPV4_FILE="${DEFAULT_IPT_FIREWALL_MAIN_IPV4_FILE}" fi if [[ -z "${IPT_FIREWALL_MAIN_IPV6_FILE}" ]]; then IPT_FIREWALL_MAIN_IPV6_FILE="${DEFAULT_IPT_FIREWALL_MAIN_IPV6_FILE}" fi if ${BATCH_MODE} && ( [[ -z "${IPv4_ADDRESS_OLD}" ]] || [[ -z "${IPv4_ADDRESS_NEW}" ]] \ || [[ -z "${IPv6_ADDRESS_OLD}" ]] || [[ -z "${IPv6_ADDRESS_NEW}" ]] ) ; then [[ -z "${IPv4_ADDRESS_OLD}" ]] && fatal "Variable 'IPv4_ADDRESS_OLD' is empty and we are in batch mode!" [[ -z "${IPv4_ADDRESS_NEW}" ]] && fatal "Variable 'IPv4_ADDRESS_NEW' is empty and we are in batch mode!" [[ -z "${IPv6_ADDRESS_OLD}" ]] && fatal "Variable 'IPv6_ADDRESS_OLD' is empty and we are in batch mode!" [[ -z "${IPv6_ADDRESS_NEW}" ]] && fatal "Variable 'IPv6_ADDRESS_NEW' is empty and we are in batch mode!" fatal "Something wired went wrong.." fi if ! ${BATCH_MODE} && ${terminal}; then echo "" echo -e "\033[32m--\033[m" echo "" echo "Insert IPv4-Address which do you want to change (old address)." echo "" echo -e "Type \"\033[33mNone\033[m\" if no IPv4 address should be changed." echo "" IPv4_ADDRESS_OLD= _set_ipv4=true while [ "X$IPv4_ADDRESS_OLD" = "X" ]; do if [[ -z "${_IPv4_ADDRESS_OLD}" ]]; then echononl "Old IPv4-Address: " read IPv4_ADDRESS_OLD ## - To lower case IPv4_ADDRESS_OLD=${IPv4_ADDRESS_OLD,,} if [ "X$IPv4_ADDRESS_OLD" = "X" ]; then echo -e "\n\t\033[33m\033[1mAn entry is required!\033[m\n" IPv4_ADDRESS_OLD="" continue fi else echononl "Old IPv4-Address: [${_IPv4_ADDRESS_OLD}]: " read IPv4_ADDRESS_OLD ## - To lower case IPv4_ADDRESS_OLD=${IPv4_ADDRESS_OLD,,} if [[ -z "$(trim ${IPv4_ADDRESS_OLD})" ]]; then IPv4_ADDRESS_OLD=${_IPv4_ADDRESS_OLD} fi fi if [ "${IPv4_ADDRESS_OLD,,}" = "none" ];then _set_ipv4=false break fi if ! is_valid_ipv4 $IPv4_ADDRESS_OLD ; then echo -e "\n\t\033[33m\033[1m$IPv4_ADDRESS_OLD\033[m is NOT a valid IPv4 Address\n" IPv4_ADDRESS_OLD="" continue fi done if $_set_ipv4 ; then echo "" echo -e "\033[32m--\033[m" echo "" echo "Insert IPv4-Address of the new munin server." echo "" IPv4_ADDRESS_NEW= while [ "X$IPv4_ADDRESS_NEW" = "X" ]; do if [[ -z "${_IPv4_ADDRESS_NEW}" ]]; then echononl "New IPv4-Address: " read IPv4_ADDRESS_NEW ## - To lower case IPv4_ADDRESS_NEW=${IPv4_ADDRESS_NEW,,} if [ "X$IPv4_ADDRESS_NEW" = "X" ]; then echo -e "\n\t\033[33m\033[1mAn entry is required!\033[m\n" IPv4_ADDRESS_NEW="" continue fi else echononl "New IPv4-Address [${_IPv4_ADDRESS_NEW}]: " read IPv4_ADDRESS_NEW ## - To lower case IPv4_ADDRESS_NEW=${IPv4_ADDRESS_NEW,,} if [[ -z "$(trim ${IPv4_ADDRESS_NEW})" ]]; then IPv4_ADDRESS_NEW=${_IPv4_ADDRESS_NEW} fi fi if ! is_valid_ipv4 $IPv4_ADDRESS_NEW ; then echo -e "\n\t\033[33m\033[1m$IPv4_ADDRESS_NEW\033[m is NOT a valid IPv4 Address\n" IPv4_ADDRESS_NEW="" continue fi done fi echo "" echo -e "\033[32m--\033[m" echo "" echo "Insert IPv6-Address which do you want to change (old address)." echo "" echo -e "Type \"\033[33mnone\033[m\" if no IPv6 address should be changed." echo "" IPv6_ADDRESS_OLD= _set_ipv6=true while [ "X$IPv6_ADDRESS_OLD" = "X" ]; do if [[ -z "${_IPv6_ADDRESS_OLD}" ]]; then echononl "Old IPv6-Address: " read IPv6_ADDRESS_OLD ## - To lower case IPv6_ADDRESS_OLD=${IPv6_ADDRESS_OLD,,} if [ "X$IPv6_ADDRESS_OLD" = "X" ]; then echo -e "\n\t\033[33m\033[1mAn entry is required!\033[m\n" IPv6_ADDRESS_OLD="" continue fi else echononl "Old IPv6-Address: [${_IPv6_ADDRESS_OLD}]: " read IPv6_ADDRESS_OLD ## - To lower case IPv6_ADDRESS_OLD=${IPv6_ADDRESS_OLD,,} if [[ -z "$(trim ${IPv6_ADDRESS_OLD})" ]]; then IPv6_ADDRESS_OLD=${_IPv6_ADDRESS_OLD} fi fi if [ "${IPv6_ADDRESS_OLD,,}" = "none" ];then _set_IPv6=false break fi if ! is_valid_ipv6 $IPv6_ADDRESS_OLD ; then echo -e "\n\tXX\033[33m\033[1m$IPv6_ADDRESS_OLD\033[mXX is NOT a valid IPv6 Address\n" IPv6_ADDRESS_OLD="" continue fi done if $_set_ipv6 ; then echo "" echo -e "\033[32m--\033[m" echo "" echo "Insert IPv6-Address iof the new munin server" echo "" IPv6_ADDRESS_NEW= while [ "X$IPv6_ADDRESS_NEW" = "X" ]; do if [[ -z "${_IPv6_ADDRESS_NEW}" ]]; then echononl "New IPv6-Address: " read IPv6_ADDRESS_NEW ## - To lower case IPv6_ADDRESS_NEW=${IPv6_ADDRESS_NEW,,} if [ "X$IPv6_ADDRESS_NEW" = "X" ]; then echo -e "\n\t\033[33m\033[1mAn entry is required!\033[m\n" IPv6_ADDRESS_NEW="" continue fi else echononl "New IPv6-Address [${_IPv6_ADDRESS_NEW}]: " read IPv6_ADDRESS_NEW ## - To lower case IPv6_ADDRESS_NEW=${IPv6_ADDRESS_NEW,,} if [[ -z "$(trim ${IPv6_ADDRESS_NEW})" ]]; then IPv6_ADDRESS_NEW=${_IPv6_ADDRESS_NEW} fi fi if ! is_valid_ipv6 $IPv6_ADDRESS_NEW ; then echo -e "\n\t\033[33m\033[1m$IPv6_ADDRESS_NEW\033[m is NOT a valid IPv6 Address\n" IPv6_ADDRESS_NEW="" continue fi done fi fi if ${terminal} ; then clear echo "" echo "" echo -e "\033[14G\033[32mReplace IP-Address(es) for munin server\033[m" echo "" if $_set_ipv4 ; then echo " Old IPv4 Address...........................: $IPv4_ADDRESS_OLD" echo " New IPv4 Address...........................: $IPv4_ADDRESS_NEW" else echo -e " IPv4 Address(es)...........................: \033[33mNone\033[m" fi echo "" if $_set_ipv6 ; then echo " Old IPv6 Address...........................: $IPv6_ADDRESS_OLD" echo " New IPv6 Address...........................: $IPv6_ADDRESS_NEW" else echo -e " IPv6 Address(es)........................: \033[33mNone\033[m" fi echo "" echo -e " Munin Node configuration file..............: \033[33m${MUNIN_CONF_FILE}\033[m" echo -e " ipt firewall main IPv4 file................: \033[33m${IPT_FIREWALL_MAIN_IPV4_FILE}\033[m" echo -e " ipt firewall main IPv6 file................: \033[33m${IPT_FIREWALL_MAIN_IPV6_FILE}\033[m" if ! ${BATCH_MODE} ; then blank_line OK= while [ "$OK" != "yes" -o "$OK" != "no" ] ; do echononl "Parameters ok? [yes/no]: " read OK ## - To lower case OK=${OK,,} if [ "X$OK" = "X" ]; then echo -e "\n\t\033[33m\033[1mAn entry is required!\033[m\n" OK="" continue fi if [ "$OK" != "yes" -o "$OK" != "no" ] ; then break fi echo -e "\n\t\033[33m\033[1mWrong entry!\033[m\n" done [[ $OK = "yes" ]] || fatal Repeat execution with different parameters fi fi blank_line blank_line echononl " Replace ${IPv4_ADDRESS_OLD} in file '${MUNIN_CONF_FILE}'.." if [[ -f "${MUNIN_CONF_FILE}" ]] ; then if $(grep -q "${IPv4_ADDRESS_OLD}" "${MUNIN_CONF_FILE}" 2> /dev/null) ; then perl -i -n -p -e "s#${IPv4_ADDRESS_OLD}#${IPv4_ADDRESS_NEW}#g" "${MUNIN_CONF_FILE}" > /dev/null 2>&1 if [[ $? -gt 0 ]]; then echo_failed else echo_ok fi else echo_skipped fi else echo_skipped fi echononl " Replace ${IPv6_ADDRESS_OLD} in file '${MUNIN_CONF_FILE}'.." if [[ -f "${MUNIN_CONF_FILE}" ]] ; then if $(grep -q "${IPv6_ADDRESS_OLD}" "${MUNIN_CONF_FILE}" 2> /dev/null) ; then perl -i -n -p -e "s#${IPv6_ADDRESS_OLD}#${IPv6_ADDRESS_NEW}#g" "${MUNIN_CONF_FILE}" > /dev/null 2>&1 if [[ $? -gt 0 ]]; then echo_failed else echo_ok fi else echo_skipped fi else echo_skipped fi echononl " Replace ${IPv4_ADDRESS_OLD} in file '${IPT_FIREWALL_MAIN_IPV4_FILE}'.." if [[ -f "${IPT_FIREWALL_MAIN_IPV4_FILE}" ]] ; then if $(grep -q -E "munin_remote_ip=\"?${IPv4_ADDRESS_OLD}\"?" "${IPT_FIREWALL_MAIN_IPV4_FILE}" 2> /dev/null) ; then perl -i -n -p -e "s#munin_remote_ip=\"?${IPv4_ADDRESS_OLD}\"?#munin_remote_ip=\"${IPv4_ADDRESS_NEW}\"#g" "${IPT_FIREWALL_MAIN_IPV4_FILE}" > /dev/null 2>&1 if [[ $? -gt 0 ]]; then echo_failed else echo_ok fi else echo_skipped fi else echo_skipped fi echononl " Replace ${IPv6_ADDRESS_OLD} in file '${IPT_FIREWALL_MAIN_IPV6_FILE}'.." if [[ -f "${IPT_FIREWALL_MAIN_IPV6_FILE}" ]] ; then if $(grep -q -E "munin_remote_ip=\"?${IPv6_ADDRESS_OLD}\"?" "${IPT_FIREWALL_MAIN_IPV6_FILE}" 2> /dev/null) ; then perl -i -n -p -e "s#munin_remote_ip=\"?${IPv6_ADDRESS_OLD}\"?#munin_remote_ip=\"${IPv6_ADDRESS_NEW}\"#g" "${IPT_FIREWALL_MAIN_IPV6_FILE}" > /dev/null 2>&1 if [[ $? -gt 0 ]]; then echo_failed else echo_ok fi else echo_skipped fi else echo_skipped fi clean_up 0