#!/bin/bash
# This script will assist to setup Percona XtraDB cluster ProxySQL monitoring script.
#####################################################################################

HOSTGROUP_ID="${1:-0}"
ERR_FILE="${2:-/dev/null}"
CHECK_STATUS=0

if [ -f /etc/proxysql-admin.cnf ]; then
  source /etc/proxysql-admin.cnf
else
  echo "Assert! proxysql-admin configuration file :/etc/proxysql-admin.cnf does not exists, Terminating!" >> $ERR_FILE
  exit 1
fi
PROXYSQL_DSN="-u$PROXYSQL_USERNAME -p$PROXYSQL_PASSWORD -h$PROXYSQL_HOSTNAME -P$PROXYSQL_PORT --protocol=tcp"

check_cmd(){
  MPID=$1
  ERROR_MSG=$2
  if [ ${MPID} -ne 0 ]; then 
    echo "Assert! $ERROR_MSG. Terminating!" >> $ERR_FILE
    exit 1
  fi
}

proxysql_exec() {
  query=$1
  result=$(
    printf "[client]\nuser=${PROXYSQL_USERNAME}\npassword=${PROXYSQL_PASSWORD}\nhost=${PROXYSQL_HOSTNAME}\nport=${PROXYSQL_PORT}\n" | \
      mysql --defaults-file=/dev/stdin --protocol=tcp -e "${query}" 2>/dev/null
  )
}

# Update Percona XtraDB Cluster nodes in ProxySQL database
update_cluster(){
  current_hosts=(`mysql $PROXYSQL_DSN -Bse"SELECT hostname,port FROM mysql_servers where hostgroup_id=$HOSTGROUP_ID" 2>/dev/null | sed 's|\t|:|g' | tr '\n' ' '`)
  wsrep_address=(`mysql  $MYSQL_DSN -Bse "SHOW STATUS LIKE 'wsrep_incoming_addresses'" 2>/dev/null | awk '{print $2}' | sed 's|,| |g'`)
  if [ ${#wsrep_address[@]} -eq 0 ]; then
    echo "Alert! wsrep_incoming_addresses is empty. Terminating!" >> $ERR_FILE
    exit 1
  fi

  for i in "${wsrep_address[@]}"; do
    if [[ ! " ${current_hosts[@]} " =~ " ${i} " ]]; then
      ws_ip=$(echo $i | cut -d':' -f1)
      ws_port=$(echo $i | cut -d':' -f2)
      echo "Cluster node (${i}) does not exists in ProxySQL database!" >> $ERR_FILE
      proxysql_exec "INSERT INTO mysql_servers (hostname,hostgroup_id,port,weight) VALUES ('$ws_ip',10,$ws_port,1000);"
      check_cmd $? "Cannot add Percona XtraDB Cluster node $ws_ip:$ws_port to ProxySQL database, Please check proxysql credentials"
      proxysql_exec "LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;"
      echo "Added ${i} node into ProxySQL database." >> $ERR_FILE
    else
      CHECK_STATUS=1
    fi
  done

  for i in "${current_hosts[@]}"; do
    if [[ ! " ${wsrep_address[@]} " =~ " ${i} " ]]; then
      ws_ip=$(echo $i | cut -d':' -f1)
      ws_port=$(echo $i | cut -d':' -f2)
      echo "Node ${i} does not exists in cluster membership!" >> $ERR_FILE
      proxysql_exec "DELETE FROM mysql_servers WHERE hostname='$ws_ip' and port=$ws_port;"
      check_cmd $? "Cannot remove Percona XtraDB Cluster node $ws_ip:$ws_port from ProxySQL database, Please check proxysql credentials"
      proxysql_exec "LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;"
      echo "Removed ${i} node from ProxySQL database." >> $ERR_FILE 
    else
      CHECK_STATUS=1 
    fi
  done
  proxysql_exec "UPDATE SCHEDULER SET arg3=${#wsrep_address[@]} WHERE id=10;LOAD SCHEDULER TO RUNTIME;SAVE SCHEDULER TO DISK;"
}

CLUSTER_USERNAME=$(mysql $PROXYSQL_DSN -Bse"SELECT variable_value FROM global_variables WHERE variable_name='mysql-monitor_username'" 2>/dev/null)
check_cmd $? "Could not retrieve cluster login info from ProxySQL. Please check cluster login credentials"

CLUSTER_PASSWORD=$(mysql $PROXYSQL_DSN -Bse"SELECT variable_value FROM global_variables WHERE variable_name='mysql-monitor_password'" 2>/dev/null) 
check_cmd $? "Could not retrieve cluster login info from ProxySQL. Please check cluster login credentials"

CLUSTER_HOST_INFO=`mysql $PROXYSQL_DSN -Bse"SELECT hostname,port FROM mysql_servers WHERE status='ONLINE' and hostgroup_id=$HOSTGROUP_ID limit 1" 2>/dev/null`
check_cmd $? "Could not retrieve cluster node info from ProxySQL. Please check cluster login credentials"

CLUSTER_HOSTNAME=$(echo $CLUSTER_HOST_INFO | awk '{print $1}')
CLUSTER_PORT=$(echo $CLUSTER_HOST_INFO | awk '{print $2}')
MYSQL_DSN="-u$CLUSTER_USERNAME -p$CLUSTER_PASSWORD -h $CLUSTER_HOSTNAME -P $CLUSTER_PORT --protocol=tcp"

if [[ -z $CLUSTER_HOST_INFO ]]; then
  echo "Percona XtraDB Cluster nodes are not configured with hostgroup $HOSTGROUP_ID. Please pass correct info" >> $ERR_FILE
else
  update_cluster
fi

if [ $CHECK_STATUS -eq 1 ]; then
  echo "Percona XtraDB Cluster membership looks good" >> $ERR_FILE
fi
exit 0

