diff options
Diffstat (limited to 'lib/adei/adei.sh')
-rw-r--r-- | lib/adei/adei.sh | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/lib/adei/adei.sh b/lib/adei/adei.sh new file mode 100644 index 0000000..3a0aeb6 --- /dev/null +++ b/lib/adei/adei.sh @@ -0,0 +1,287 @@ +cd $(dirname $0) + +MAX_SOURCE_OFFSET=3600 +MAX_MASTER_OFFSET=300 +MAX_SLAVE_OFFSET=300 + +adei_default_timeout=${default_timeout:-120} + +. lib/adei/adei_version.sh +. lib/adei/adei_print.sh +. lib/adei/adei_error.sh +. lib/nagios/nagios.sh + +shopt -s nocasematch; + +# Auth with redirect (-L/--location-trusted) not working. Credentials are lost on hops. +function adei_query { + local resp + local timeout=${3:-$adei_default_timeout} + + local err=0 + if [ "$2" == "ecode" ]; then + url="$1&mysql=master" +# resp=$(curl --proxy "" -f -m "$timeout" "$url" 2>&1 | grep "returned error") + resp=$(curl --proxy "" --location-trusted -sf -m "$timeout" -w "%{http_code}" -o /dev/null "$url" 2>&1); + [ -z "$resp" -o "$resp" = "000" ] && resp="10" # error code 1 + elif [ "$2" == "emsg" ]; then + url="$1&mysql=master" + resp=$(curl --proxy "" --location-trusted -f -m "$timeout" "$url" 2>&1 | grep -o "curl.*") + [ -z "$resp" ] && resp="No response from" + else + if [ "$2" == "slave" ]; then + url="$1&mysql=slave" + else + url="$1&mysql=master" + fi + + + resp=$(curl --proxy "" --location-trusted -sf -m "$timeout" "$url"); err=$? + if [ $err -ne 0 ]; then + resp=$(adei_query "$1" "ecode" "$timeout") + err=$(($(($resp / 10)) + $(($resp % 10)))) + + resp=$(adei_query "$1" "emsg" "$timeout") + + [ -n "$debug" ] && echo "$(date) $timeout Failed $url" >> /tmp/adei.log + else + [ -n "$debug" ] && echo "$(date) $timeout OK $url" >> /tmp/adei.log + fi + fi + + echo -n $resp + return $err +} + +function adei_format_query { + local with_auth="${1:-1}" + local query="$2" + local timeout=${3:-$adei_default_timeout} + local source=${4:-"$adei_source"} + local url="${5:-$adei_url}" + + auth="" + [ $with_auth -gt 0 ] && auth="$adei_auth" + if [[ "$query" =~ \? ]]; then + echo "http://${auth}${url}/${query}${source}" + else + echo "http://${auth}${url}/${query}?xxxxx${source}" + fi +} + +function adei_simple_query { + local req=$(adei_format_query 1 "$@") + adei_query "$req" "master" "$timeout"; err=$? + return $err +} + +function adei_text_query { + local out # Local on the same string breaks error reporting + out="$(adei_simple_query "$@")"; local err=$? + + if [ $err -gt 0 -o -z "$out" ]; then +# echo "Error sending ADEI request: $(adei_format_query 0 "$@")" + [ $err -eq 0 ] && local err=1 + [ -n "$out" ] && echo -n "$out" + return $err + elif [[ "$out" =~ "Error:" ]]; then + echo -n "$out" + return 7 + else + echo -n "$out" + return 0 + fi +} + +function adei_xml_query { + local out # Local on the same string breaks error reporting + out="$(adei_simple_query "$@")"; local err=$? + + if [ $err -ne 0 -o -z "$out" ]; then +# echo "Error sending ADEI request: $(adei_format_query 0 '$@')" + [ $err -eq 0 ] && err=1 + [ -n "$out" ] && echo "$out" + return $err + fi + + local xml="$(echo "$out" | xmllint --format - 2>/dev/null)" + if [ $err -ne 0 -o -z "$out" ]; then + echo "$out" + if [[ "$out" =~ "Error:" ]]; then + return 7 + else + return 4 + fi + fi + + error=$(echo "$xml" | grep "<Error>") + if [ -n "$error" ]; then + echo $error | sed -e "s|</\?Error>||g" + return 7 + fi + + echo "$xml" + return $err +} + +function adei_value_query { + local out # Local on the same string breaks error reporting + out="$(adei_xml_query "$@")"; local err=$? + [ $err -ne 0 ] && { echo "$out"; return $err; } + + local values + values="$(echo "$out" | grep "Value")"; err=$? + [ $err -ne 0 ] && return 6 + + echo "$values" +} + + +function adei_get_databases { + local out + out="$(adei_xml_query "list.php?target=databases" "$@")" + [ $err -gt 0 ] && { echo -n "$out"; return $err; } + echo "$out" | grep "Value" | sed -e "s/^.*db_name=\"\([^\"]*\)\".*$/\\1/" | sed -e "s/ /::space::/" +} + +function adei_query_version { + local version # Local on the same string breaks error reporting + + version="$(adei_text_query "info.php?target=version&encoding=text" "$@")"; local err=$? + [ $err -gt 0 ] && { echo "$version"; return $err; } + + adei_version="$version" + + adei_revision=$(echo $adei_version | cut -d '-' -f 1) + if [ "$adei_revision" == "$adei_version" ]; then + adei_date="" + else + adei_date=$(echo $adei_version | cut -d '-' -f 2) + fi +} + +function adei_resolve_id { + fn="$1" + id="$2" + host="$3" + setup="$4" + + local var=$(cat "$fn" | grep "^$id" | awk '{ print $2 }') + [ -z "$var" -a -n "$host" ] && var=$(cat "$fn" | grep "^$host" | awk '{ print $2 }') + [ -z "$var" -a -n "$setup" ] && var=$(cat "$fn" | grep "^$setup" | awk '{ print $2 }') + + [ -n "$debug" ] && echo "$(date) resolved ($var) from $fn (id=$id, host=$host, setup=$setup) pwd ($(pwd))" >> /tmp/resolv.log + echo "$var" +} + +function adei_init_ { + local id="$1" && shift # Either URL or [setup]@[host] +# local url="$1" && shift + local server="$1" && shift + local database="$1" && [[ ! "$server" =~ \&|= ]] && shift + adei_args=( "$@" ) + + [ -z "$id" ] && { echo "ADEI ID is not specified" && exit 8 ; } + + + local url + local host + local setup + if [[ $id =~ http.*:// ]]; then # url + url="$id" + host="$(echo ${url#http*://} | cut -d '/' -f 1)" # parse port, maybe + + unset $setup + elif [[ $id =~ : ]]; then # [setup@]host + local seho + IFS='@' read -ra seho <<< "$id" && shift + host="${seho[1]:-${seho[0]}}" # parse port, for sure + setup="${seho[1]:+${seho[0]}}" + + unset $url + else # [setup]@[host] or both, no port + local seho + IFS='@' read -ra seho <<< "$id" && shift # techincally we can try to resolve to decide which is which + + host="${seho[1]:-${seho[0]}}" # This could be mixed up, but it is either not important, or correct, or misconfigured anyway + setup="${seho[1]:+${seho[0]}}" # Only error if only setup is provided. But we handle it in resolution code which agnostic and treats them as ids + + url=$(adei_resolve_id "setup/adei.txt" "$id" "$host" "$setup") + + if [ -n "$url" ]; then # Get URL, now we can determine host correctly and ignore the ids. + host="$(echo ${url#http*://} | cut -d '/' -f 1)" + unset $setup + else # only 'setup' is not allowed if URL is not configured, so it should be host (or error in configuration) + unset $url # so either we have both (correctly) or only host (correctly) + fi + fi + + local hopo + IFS=':' read -ra hopo <<< "$host" && shift + host="${hopo[0]}" # only non fqdn if also url not set + port=":${hopo[1]:-80}" + [ $port = ":80" ] && port="" + + local fqdn + if [ -z "$url" ]; then + url=$(adei_resolve_id "setup/adei.txt" "$id" "$host" "$setup") + if [ -n "$url" ]; then + fqdn="$(echo ${url#http*://} | cut -d '/' -f 1)" + + IFS=':' read -ra hopo <<< "$fqdn" && shift + host="${hopo[0]}" # again fqdn + port=":${hopo[1]:-80}" + [ $port = ":80" ] && port="" + else + fqdn=$(resolve_fqdn "$host") # this may be not fqdn + [ -n "$fqdn" ] && host="$fqdn" + url="${host}${port}/adei" + fi + fi + + # In some case we miss here "setup", but surely then the password is resolved host-based + adei_auth=$(adei_resolve_id "security/adei.txt" "$id" "$host" "$setup") + [ -n "$adei_auth" ] && adei_auth="$adei_auth@" + + # Now check port + adei_online=$(scripts/ping.pl "$host" "$port") + [ $adei_online -ne 1 ] && return 2 + + # Now build ADEI url + + adei_setup="$setup" + adei_host="$host" + adei_port="$port" + adei_url="${url#http*://}/services" + + + adei_query_version; local err=$? + [ $err -gt 0 ] && return $err + + + if [[ "$server" =~ \&|= ]]; then + adei_source="&$server" + else + adei_source="" + [ -n "$adei_setup" -a "$adei_setup" != "*" ] && adei_source+="&setup=$adei_setup" + [ -n "$server" -a "$server" != "-" ] && adei_source+="&db_server=$server" + + if [ "$database" == "#1" ]; then + databases="$(adei_get_databases)"; err=$? + [ $err -gt 0 ] && { echo "Failed to query ADEI databases: $databases"; return $err; } + [ -z "$databases" ] && { echo "No databases reported by ADEI"; return 6; } + database=$(echo "$databases" | head -n 1) + fi + + [ -n "$database" -a "$database" != "-" ] && adei_source+="&db_name=$database" + fi + + return 0 +} + +function adei_init { + adei_init_ "$@"; local code=$? + + adei_healthy=$(($code == 0)) + adei_process_error "$code" "" "*" "$(adei_print_status "$0" $adei_online $adei_healthy)" +} |