#!/bin/sh

# Copyright (C) 2014-2019 Daniel Baumann <daniel.baumann@open-infrastructure.net>
#
# SPDX-License-Identifier: GPL-3.0+
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

set -e

PROGRAM="$(basename ${0})"

Parameters ()
{
	GETOPT_LONGOPTIONS="number:,release:,zone:,ipv4-address:,with-reverse,with-round-robin,master:,mds:,mgr:,mon:,osd:,rgw:,"
	GETOPT_OPTIONS="n:,r:,z:,f:,"

	PARAMETERS="$(getopt --longoptions ${GETOPT_LONGOPTIONS} --name=${PROGRAM} --options ${GETOPT_OPTIONS} --shell sh -- ${@})"

	if [ "${?}" != "0" ]
	then
		echo "'${PROGRAM}': getopt exit" >&2
		exit 1
	fi

	eval set -- "${PARAMETERS}"

	while true
	do
		case "${1}" in
			-n|--number)
				NUMBER="${2}"
				shift 2
				;;

			-r|--release)
				RELEASE="${2}"
				shift 2
				;;

			-z|--zone)
				ZONE="${2}"
				shift 2
				;;

			--ipv4-address)
				IPV4_ADDRESS="${2}"
				shift 2
				;;

			--with-reverse)
				WITH_REVERSE="true"
				shift 1
				;;

			--with-round-robin)
				WITH_ROUND_ROBIN="true"
				shift 1
				;;

			--master)
				MASTER="${2}"
				shift 2
				;;

			--mds)
				MDS="${2}"
				shift 2
				;;

			--mgr)
				MGR="${2}"
				shift 2
				;;

			--mon)
				MON="${2}"
				shift 2
				;;

			--osd)
				OSD="${2}"
				shift 2
				;;

			--rgw)
				RGW="${2}"
				shift 2
				;;

			--)
				shift 1
				break
				;;

			*)
				echo "'${PROGRAM}': getopt error" >&2
				exit 1
				;;
		esac
	done
}

Usage ()
{
	echo "Usage: ${PROGRAM} {create|check} [-n|--number NUMBER] [-r|--release RELEASE] [-z|--zone ZONE|none] [--ipv4-address IPV4_ADDRESS] [--with-reverse] [--with-round-robin] [--master MASTER_NUMBER] [--mds MDS_NUMBER] [--mgr MGR_NUMBER] [--mon MON_NUMBER] [--osd OSD_NUMBER] [--rgw RGW_NUMBER]" >&2
	exit 1
}

case "${1}" in
	check)
		ACTION="check"
		;;

	create)
		ACTION="create"
		;;

	*)
		Usage
		;;
esac

shift 1

Parameters "${@}"

NUMBER="${NUMBER:-3}"
RELEASE="${RELEASE:-mimic}"

case "${ZONE}" in
	"")
		ZONE=".ceph.example.net."
		;;

	none)
		ZONE=""
		;;

	*)
		ZONE=".${ZONE}"
		;;
esac

IPV4_ADDRESS="${IPV4_ADDRESS:-10.0.0.11}"

MASTER="${MASTER:-1}"
MDS="${MDS:-${NUMBER}}"
MGR="${MGR:-${NUMBER}}"
MON="${MON:-${NUMBER}}"
OSD="${OSD:-${NUMBER}}"
RGW="${RGW:-${NUMBER}}"

RED="$(tput setaf 1)$(tput bold)"
GREEN="$(tput setaf 2)$(tput bold)"
WHITE="$(tput setaf 7)$(tput bold)"
NORMAL="$(tput sgr0)"

STATUS_GOOD="${GREEN}✔${NORMAL}"
STATUS_BAD="${RED}✘${NORMAL}"
STATUS_UGLY="${WHITE}○${NORMAL}"

cat << EOF
; Ceph DNS: Forward Entries
EOF

# Run forward zone
for SERVICE in master mon mgr mds rgw osd
do
	NUMBERS="$(eval "echo \$$(echo "${SERVICE}" | tr [a-z] [A-Z])")"

	if [ -z "${NUMBERS}" ]
	then
		continue
	fi

	for NUMBER in $(seq 1 ${NUMBERS})
	do
		case "${SERVICE}" in
			master)
				CONTAINER="${SERVICE}"
				;;

			*)
				CONTAINER="${SERVICE}${NUMBER}"
				;;
		esac

		case "${CHECK}" in
			true)
				IP_ADDRESS="$(dig +short ${CONTAINER}.${RELEASE}${ZONE} | tail -n1)"

				if [ -n "${IP_ADDRESS}" ]
				then
					IP_ADDRESS="${IP_ADDRESS} ${STATUS_GOOD}"
				else
					IP_ADDRESS="${STATUS_BAD}"
				fi
				;;
		esac

		case "${SERVICE}" in
			master)

cat << EOF

${CONTAINER}${ZONE} IN A ${IP_ADDRESS}
dashboard${ZONE} IN CNAME master${ZONE}
${ZONE} IN A ${IP_ADDRESS}
EOF

				;;

			*)

cat << EOF

${CONTAINER}.${RELEASE}${ZONE} IN A ${IP_ADDRESS}
${CONTAINER}${ZONE} IN CNAME ${CONTAINER}.${RELEASE}${ZONE}
EOF


				if [ "${WITH_ROUND_ROBIN}" = "true" ]
				then

cat << EOF
${SERVICE}.${RELEASE}${ZONE} IN A ${IP_ADDRESS}
${SERVICE}${ZONE} IN A ${IP_ADDRESS}
EOF

				fi
				;;
		esac

		IP_ADDRESS="$((${IP_ADDRESS} + 1))"
	done
done

case "${WITH_REVERSE}" in
	true)

cat << EOF

; Ceph DNS: Reverse Entries

EOF

		# Run reverse zone
		for SERVICE in master mon mgr mds rgw osd
		do
			NUMBERS="$(eval "echo \$$(echo "${SERVICE}" | tr [a-z] [A-Z])")"

			if [ -z "${NUMBERS}" ]
			then
				continue
			fi

			for NUMBER in $(seq 1 ${NUMBERS})
			do
				case "${SERVICE}" in
					master)
						CONTAINER="master"
						;;

					*)
						CONTAINER="${SERVICE}${NUMBER}"
						;;
				esac

				case "${CHECK}" in
					true)
						IP_ADDRESS="$(dig +short ${CONTAINER}.${RELEASE}${ZONE} | tail -n1)"

						if [ -n "${IP_ADDRESS}" ]
						then
							HOST="$(dig +short -x ${IP_ADDRESS} | tail -n1)"
							if [ -n "${HOST}" ]
							then
								STATUS="${STATUS_GOOD}"
							else
								STATUS="${STATUS_BAD}"
							fi
						else
							STATUS="${STATUS_BAD}"
							IP_ADDRESS="Nil"
						fi
						;;
					*)
						IP_ADDRESS="FIXME"
					;;
				esac

cat << EOF
${IP_ADDRESS} IN PTR ${CONTAINER}.${RELEASE}${ZONE} ${STATUS}
EOF

			done
		done
		;;
esac
