#!/usr/bin/env bash

#
# This is a one-time script to upgrade db from MySQL 5.6 and Aurora ver.1 to
# MySQL 5.7 and Aurora 2.
#
# We should be able to restart this script if needed,
# it should be able to resume its work from where it was interrupted
#
# It creates a snapshot, restores it to a new cluster with encryption and MySQL 5.7/Aurora 2
# and creates master and two replicas
#

function msg() {
    echo "[$(date +'%F %T')] $1"
}

LEGACY_CLUSTER_NAME='prod-apollo-aurora-cluster'
ENCRYPTED_CLUSTER_NAME='prod-apollo-aurora-enc'
SNAPSHOT_IDENTIFIER='prod-apollo-aurora-cluster-before-encryption'
AWS_PROFILE='gdb-delphi-prod'

# step 1 - check if a snapshot exists
msg "check if a snapshot exists"
aws \
  --profile "${AWS_PROFILE}" \
  rds describe-db-cluster-snapshots \
    --db-cluster-snapshot-identifier "${SNAPSHOT_IDENTIFIER}"

# step 2 - if the snapshot doesn't exists create it
if [[ $? -ne 0 ]];
then
  msg "create a snapshot"
  aws --profile "${AWS_PROFILE}" \
    rds create-db-cluster-snapshot \
      --db-cluster-snapshot-identifier "${SNAPSHOT_IDENTIFIER}" \
      --db-cluster-identifier "${LEGACY_CLUSTER_NAME}" \
      --tags "Key=environment,Value=Production" \
             "Key=plat_env_project_service,Value=APL_PROD_DATA_AURA" \
             "Key=platform,Value=Apollo" \
             "Key=platform_with_env,Value=Apollo Production" \
             "Key=project,Value=Data" \
             "Key=service,Value=Aurora" || exit 1

  x=255
  until [[ $x -eq 0 ]];
  do
    msg "check if the snapshot is available"
    aws \
      --profile gdb-delphi-prod \
      rds describe-db-cluster-snapshots \
        --db-cluster-snapshot-identifier "${SNAPSHOT_IDENTIFIER}" | grep -q '"Status": "available"'
    x=$?
    sleep 5
  done
fi

# step 3 - check if a cluster exists
msg "check if a cluster exists"
aws \
  --profile "${AWS_PROFILE}" \
  rds describe-db-clusters \
    --db-cluster-identifier "${ENCRYPTED_CLUSTER_NAME}"

# step 3 - if the cluster doesn't exist create a new one
if [[ $? -ne 0 ]];
then
  msg "create a new cluster"
  aws \
    --profile "${AWS_PROFILE}" \
    rds restore-db-cluster-from-snapshot \
      --db-cluster-identifier "${ENCRYPTED_CLUSTER_NAME}" \
      --snapshot-identifier "arn:aws:rds:us-east-1:323555055331:cluster-snapshot:${SNAPSHOT_IDENTIFIER}" \
      --engine aurora-mysql \
      --engine-version '5.7.mysql_aurora.2.10.2' \
      --db-subnet-group-name prod-apollo-dbsubnetgroup \
      --vpc-security-group-ids 'sg-0a9175404c4199f14' 'sg-0544d2fd45f72b249' \
      --engine-mode provisioned \
      --db-cluster-parameter-group-name prod-apollo-main-5-7 \
      --database-name sonyDB \
      --copy-tags-to-snapshot \
      --deletion-protection \
      --enable-cloudwatch-logs-exports "audit" "error" "general" "slowquery" \
      --kms-key-id arn:aws:kms:us-east-1:323555055331:key/0b0c5f3d-d5c0-44a3-bd18-796b98ed8cbd \
      --tags "Key=environment,Value=Production" \
             "Key=plat_env_project_service,Value=APL_PROD_DATA_AURA" \
             "Key=platform,Value=Apollo" \
             "Key=platform_with_env,Value=Apollo Production" \
             "Key=project,Value=Data" \
             "Key=service,Value=Aurora" || exit 1

  x=255
  until [[ $x -eq 0 ]];
  do
    msg "check if the cluster is available"
    aws \
      --profile "${AWS_PROFILE}" \
      rds describe-db-clusters \
        --db-cluster-identifier "${ENCRYPTED_CLUSTER_NAME}" | grep -q 'Status": "available"'
    x=$?
    sleep 15
  done
fi

# step 4 - attach a role to the cluster
msg "attach a role to the cluster"
aws \
  --profile "${AWS_PROFILE}" \
  rds add-role-to-db-cluster \
    --db-cluster-identifier "${ENCRYPTED_CLUSTER_NAME}" \
    --role-arn arn:aws:iam::323555055331:role/prod-apollo-aurora_s3 || msg "already attached."

# step 5 - check if an instance exists
msg "check if an instance exists"
aws \
  --profile "${AWS_PROFILE}" \
  rds describe-db-instances \
    --db-instance-identifier "${ENCRYPTED_CLUSTER_NAME}-master"

# step 6 - if the instance doesn't exist create a new one
if [[ $? -ne 0 ]];
then
  msg "create a master instance"
  aws \
    --profile "${AWS_PROFILE}" \
    rds create-db-instance \
      --db-instance-identifier "${ENCRYPTED_CLUSTER_NAME}-master" \
      --db-instance-class db.r5.2xlarge \
      --engine aurora-mysql \
      --db-parameter-group-name prod-apollo-main-5-7 \
      --db-cluster-identifier "${ENCRYPTED_CLUSTER_NAME}" \
      --availability-zone us-east-1c \
      --no-publicly-accessible \
      --no-auto-minor-version-upgrade \
      --preferred-maintenance-window sun:09:00-sun:11:00 \
      --tags "Key=environment,Value=Production" \
             "Key=plat_env_project_service,Value=APL_PROD_DATA_AURA" \
             "Key=platform,Value=Apollo" \
             "Key=platform_with_env,Value=Apollo Production" \
             "Key=project,Value=Data" \
             "Key=service,Value=Aurora" || exit 1

  x=255
  until [[ $x -eq 0 ]];
  do
    msg "check if the master instance is available"
    aws \
      --profile "${AWS_PROFILE}" \
      rds describe-db-instances \
        --db-instance-identifier "${ENCRYPTED_CLUSTER_NAME}-master" | grep -q 'Status": "available"'
    x=$?
    sleep 15
  done
fi

# step 7 - check if a reader instance exists
msg "check if a reader instance exists"
aws \
  --profile "${AWS_PROFILE}" \
  rds describe-db-instances \
    --db-instance-identifier "${ENCRYPTED_CLUSTER_NAME}-reader"

# step 8 - if the reader instance doesn't exist create a new one
if [[ $? -ne 0 ]];
then
  msg "create a reader instance"
  aws \
    --profile "${AWS_PROFILE}" \
    rds create-db-instance \
      --db-instance-identifier "${ENCRYPTED_CLUSTER_NAME}-reader" \
      --db-instance-class db.r5.2xlarge \
      --engine aurora-mysql \
      --db-parameter-group-name prod-apollo-main-5-7 \
      --db-cluster-identifier "${ENCRYPTED_CLUSTER_NAME}" \
      --availability-zone us-east-1b \
      --no-publicly-accessible \
      --no-auto-minor-version-upgrade \
      --preferred-maintenance-window sun:09:00-sun:11:00 \
      --tags "Key=environment,Value=Production" \
             "Key=plat_env_project_service,Value=APL_PROD_DATA_AURA" \
             "Key=platform,Value=Apollo" \
             "Key=platform_with_env,Value=Apollo Production" \
             "Key=project,Value=Data" \
             "Key=service,Value=Aurora" || exit 1

  x=255
  until [[ $x -eq 0 ]];
  do
    msg "check if the reader instance is available"
    aws \
      --profile "${AWS_PROFILE}" \
      rds describe-db-instances \
        --db-instance-identifier "${ENCRYPTED_CLUSTER_NAME}-reader" | grep -q 'Status": "available"'
    x=$?
    sleep 15
  done
fi

# step 7 - check if the 2nd reader instance exists
msg "check if the 2nd reader instance exists"
aws \
  --profile "${AWS_PROFILE}" \
  rds describe-db-instances \
    --db-instance-identifier "${ENCRYPTED_CLUSTER_NAME}-reader2"

# step 8 - if the reader instance doesn't exist create a new one
if [[ $? -ne 0 ]];
then
  msg "create the 2nd reader instance"
  aws \
    --profile "${AWS_PROFILE}" \
    rds create-db-instance \
      --db-instance-identifier "${ENCRYPTED_CLUSTER_NAME}-reader2" \
      --db-instance-class db.r5.2xlarge \
      --engine aurora-mysql \
      --db-parameter-group-name prod-apollo-main-5-7 \
      --db-cluster-identifier "${ENCRYPTED_CLUSTER_NAME}" \
      --availability-zone us-east-1a \
      --no-publicly-accessible \
      --no-auto-minor-version-upgrade \
      --preferred-maintenance-window sun:09:00-sun:11:00 \
      --tags "Key=environment,Value=Production" \
             "Key=plat_env_project_service,Value=APL_PROD_DATA_AURA" \
             "Key=platform,Value=Apollo" \
             "Key=platform_with_env,Value=Apollo Production" \
             "Key=project,Value=Data" \
             "Key=service,Value=Aurora" || exit 1

  x=255
  until [[ $x -eq 0 ]];
  do
    msg "check if the 2nd reader instance is available"
    aws \
      --profile "${AWS_PROFILE}" \
      rds describe-db-instances \
        --db-instance-identifier "${ENCRYPTED_CLUSTER_NAME}-reader2" | grep -q 'Status": "available"'
    x=$?
    sleep 15
  done
fi

msg "done."
