#!/bin/bash

STATE_OK=0
STATE_CRITICAL=2
STATE_UNKNOWN=3

DEFAULT_CONFIG_FILE="/etc/default/etcd"
DEFAULT_CERT_FILE="/etc/step/certs/generic.user.full.pem"
DEFAULT_KEY_FILE="/etc/step/certs/generic.user.full.pem"

die() {
  echo "ERROR running $0: $1"
  exit 1
}

config_file="${config_file:-$DEFAULT_CONFIG_FILE}"
[[ -e "${config_file}" ]] || die "configuration file is missing: ${config_file}"
source ${config_file}

# Expect the following environment variables to be set
ETCD_PEER_CERT_FILE="${ETCD_PEER_CERT_FILE:-$DEFAULT_CERT_FILE}"
ETCD_PEER_KEY_FILE="${ETCD_PEER_KEY_FILE:-$DEFAULT_KEY_FILE}"
[[ -f "${ETCD_PEER_CERT_FILE}" ]] || die "ETCD_PEER_CERT_FILE (environment) is not set or does not exist"
[[ -f "${ETCD_PEER_KEY_FILE}" ]] || die "ETCD_PEER_KEY_FILE (environment) is not set or does not exist"
[[ -z "${ETCD_ADVERTISE_CLIENT_URLS-}" ]] && die "ETCD_ADVERTISE_CLIENT_URLS (environment) is not set"

if ! systemctl is-active --quiet etcd; then
  echo "CRITICAL - etcd service is not running"
  exit $STATE_CRITICAL
fi

TMP_FILE=$(mktemp /tmp/check_etcd.XXXXXX)
trap "rm -f $TMP_FILE" EXIT

etcdctl endpoint health \
  --cert "$ETCD_PEER_CERT_FILE" \
  --key "$ETCD_PEER_KEY_FILE" \
  --endpoints "$ETCD_ADVERTISE_CLIENT_URLS" \
  --write-out json \
  > "$TMP_FILE" 2>&1

JSON_OUTPUT=$(grep -Eo '\{.*\}|\[.*\]' "$TMP_FILE" | jq -s 'map(select(type == "object" or type == "array")) | .[]') || {
  echo "UNKNOWN - failed parsing etcdctl output:"
  cat "$TMP_FILE"
  exit $STATE_UNKNOWN
}

ETCD_HEALTH=$(echo "$JSON_OUTPUT" | jq -r '.[]? | .health?')

if [[ "$ETCD_HEALTH" = true ]]; then
  echo "OK - etcd node is healthy"
  exit $STATE_OK
else
  ERROR_DETAILS=$(echo "$JSON_OUTPUT" | jq -r '..? | .error?')
  echo -e "CRITICAL - etcd node is unhealthy:\n$ERROR_DETAILS"
  exit $STATE_CRITICAL
fi
