#!/bin/bash
#
# OpenLDAP check status script
#
# - setup
# @code
# yum install openldap-clients
# chmod 755 ldap-status.sh
# @endcode
#
# $Revision:$
# $Date:$

# define
OPT_SERVERS=
OPT_BIND_PASSWORD=
OPT_BIND_DN=
OPT_BASE_DN=
OPT_LOG_DIR= # /tmp

#PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
readonly DEBUG=0
export LANG=C
readonly CUR_DIR=$(cd $(dirname $0);pwd) # current directory
readonly PID=$$
readonly CMDNAME=`basename $0`
readonly CMDBASENAME=`basename $0 .sh`
LOG_FILE= # "$CUR_DIR/${CMDBASENAME}.log"

# ESC  http://ascii-table.com/ansi-escape-sequences.php
# BASH http://archive.linux.or.jp/JF/JFdocs/Bash-Prompt-HOWTO-5.html
readonly ESC="\e["
readonly ESCEND=m
readonly ESC_CLEAR=${ESC}${ESCEND}
# ESC Foreground colors
readonly ESC_BLACK="30"
readonly ESC_RED="31"
readonly ESC_GREEN="32"
readonly ESC_YELLOW="33"
readonly ESC_BLUE="34"
readonly ESC_MAGENTA="35"
readonly ESC_CYAN="36"
readonly ESC_WHITE="37"
readonly ESC_DARK_GRAY="30;1"
readonly ESC_LIGHT_RED="31;1"
readonly ESC_LIGHT_GREEN="32;1"
readonly ESC_LIGHT_YELLOW="33;1"
readonly ESC_LIGHT_BLUE="34;1"
readonly ESC_LIGHT_MAGENTA="35;1"
readonly ESC_LIGHT_CYAN="36;1"

# /define

# function
echo_prestr() {
	echo -e `date '+%Y-%m-%d %H:%M:%S'`"\t${PID}"
}

echo_blank() {
	echo "" | tee -a ${LOG_FILE}
}

echo_info() {
	local prestr=`echo_prestr`"\tINFO"
	echo -en "${ESC}${ESC_LIGHT_GREEN}${ESCEND}"
	echo -e "${prestr}\t${1}" | tee -a ${LOG_FILE}
	echo -en "${ESC_CLEAR}"
	return 0
}

echo_warn() {
	local prestr=`echo_prestr`"\tWARN"
	{
		echo -en "${ESC}${ESC_YELLOW}${ESCEND}"
		echo -e "${prestr}\t${1}" | tee -a ${LOG_FILE}
		echo -en "${ESC_CLEAR}"
	} 1>&2
}

echo_error() {
	local prestr=`echo_prestr`"\tERROR"
	{
		echo -en "${ESC}${ESC_MAGENTA}${ESCEND}"
		echo -e "${prestr}\t${1}" | tee -a ${LOG_FILE}
		echo -en "${ESC_CLEAR}"
	} 1>&2

	return 1
}

# result 0:OK, 1:NG
function replication_status() {

	if [ -z "$OPT_BASE_DN" ]; then
		echo_error "--base-dn is required"
		exit 1
	fi

	if [ -z "$OPT_BIND_DN" ]; then
		echo_error "--bind-dn is required"
		exit 1
	fi

	if [ -z "$OPT_BIND_PASSWORD" ]; then
		echo_error "--bind-password is required"
		exit 1
	fi

	# get contextCSN
	IFS=','
	local server
	local md5
	local md5list=()
	for server in ${OPT_SERVERS[@]};do
		md5=$(ldapsearch -x -H "${server}" \
	  -D "${OPT_BIND_DN}" \
	  -w "${OPT_BIND_PASSWORD}" \
	  -s base -b "${OPT_BASE_DN}" contextCSN 2>/dev/null | grep -P "^contextCSN:" | sort | md5sum)
		if [ "$?" != "0" ]; then
			echo "1"
			exit 0
		fi

		md5list+=("$md5")
	done
	
	# verification
	local tmp
	for md5 in ${md5list[@]};do
		if [ -z "$tmp" ]; then
			tmp=$md5
		fi
		
		if [ "$tmp" != "$md5" ]; then
			echo "1"
			exit 0
		fi
	done
	
	echo "0"
	exit 0
}

function main() {

	if [ -z "$OPT_OPERATION" ]; then
		echo_error "OPERATION is required"
		exit 1
	fi

	if [ -z "$OPT_SERVERS" ]; then
		echo_error "--servers is required"
		exit 1
	fi

	case $OPT_OPERATION in
		"replication-status" )
			replication_status
			;;
		* )
			echo_error "[${OPT_OPERATION}] is not supported"
			usage_exit
			;;
	esac
}

usage_exit() {
	cat 1>&2 << EOS
Usage: $CMDNAME [options] operation

Operations:
  replication-status         result 0:OK, 1:NG

Common options:
  --servers                  LDAP Servers
                             ex: ldap://server01/,ldap://server02/,...
  --base-dn                  base dn for search
                             ex: dc=my-domain,dc=com
  --bind-dn                  bind DN
                             ex: "cn=Manager,dc=my-domain,dc=com"
  --bind-password            bind password (for simple authentication)
  --log-dir                  ex: /tmp
  --help                     help
EOS
	exit 1
}

# /function

# check command args.
if [ $# -lt 1 ]; then
    usage_exit
fi

OPT=`getopt -q -o "" -l "help,log-dir:,bind-password:,bind-dn:,base-dn:,servers:" -- "$@"`
if [ $? != 0 ]; then
	usage_exit
fi
 
eval set -- "$OPT"
while [ -n "$1" ]; do
	case $1 in
		--servers) OPT_SERVERS=$2; shift 2;;
		--bind-password) OPT_BIND_PASSWORD=$2; shift 2;;
		--bind-dn) OPT_BIND_DN=$2; shift 2;;
		--base-dn) OPT_BASE_DN=$2; shift 2;;
		--log-dir) 
			OPT_LOG_DIR=$2
			shift 2
			if [ -d "$OPT_LOG_DIR" ]; then
				LOG_FILE=$OPT_LOG_DIR/${CMDBASENAME}.log
			else
				echo_error "directory not found. [$OPT_LOG_DIR]"
				exit 1
			fi
			;;
		--help) usage_exit;;
		--) shift; break;;
		*) echo_error "Unknown option($1) used."; exit 1;;
	esac
done

OPT_OPERATION=$1

main

# vim: ts=4:sw=4

