#!/bin/bash

# Author's: Mark Bogner,
#           Thaddeus M. Diede
#           Modified by NDB

# Updated 2016-09-15 - Updated to clean up after itself
# Updated 2016-11-04 - Renamed from "dailyawsdbbackup" to dailyaws-nsdb-backup"
# Updated 2017-01-18 - Major revision, removed -b flag (separation of concerns)
# Updated 2020-01-07 - Added FTP upload for use by certain customers, plus some script cleanup and better logging

# This shell script is for producing Novastar backup files and placing them on AWS S3
# It performs the following tasks:
#   1. Copies yesterday's backup to backup.old
#   2. Generates a new nsdb backup
#   3. Copy .bak to client's aws s3 bucket/dir
#   4. If friday, make a .FRI copy
#   4. If first-of-month (FOM) make a .FOM copy
#   5. Secure copy today, today.old, FRI, FOM to backup node.
#   6. Preserve copies of today, .old, .FRI, .FOM in /usr/ns/bak on local system

# The backup strategy is keep each backup for the last week plus the first of the month.
# This task is achieved via the use of Amazon Web Services Command Line Interface (AWS-CLI)
# AWS-CLI communicates on TCP Port 443. 
# It is likely that this port will not be open by default on NovaStar systems.


#------------------------------------------------------------------------------

# Configuration
PGNAME="awsbackup-nsdb-daily"
PGDESC="NSDB offsite backup to AWS-S3"
LOGFILE="/usr/ns/log/${PGNAME}.log"
BAKDIR="/usr/ns/bak"


# Functions

cleanup() {
  SIGNAL=$?
  # Clean up temp files
  # Show exit code
  echo "Exit code: ${1:-$SIGNAL}"
}


# Function to do the actual file uploads to S3 and object tagging.  Set variables prior to calling function.
upload_file_s3()
{
  mv -v "$NSDBFILE" "${NSDBFILE}${FILE_EXT}"
  echo "Created NSDB $BACKUP_TYPE_TAG Backup File: ${NSDBFILE}${FILE_EXT}"
  echo "NDSB AWS-S3 $BACKUP_TYPE_TAG Backup Destination: s3://${S3BUCKET}/${S3DIR}/${DATECODE}-${NSDBFILE}${FILE_EXT}"
  echo "Starting $BACKUP_TYPE_TAG backup aws-cli transfer..."
  aws s3 cp "${NSDBFILE}${FILE_EXT}" "s3://${S3BUCKET}/${S3DIR}/${DATECODE}-${NSDBFILE}${FILE_EXT}" --profile "$AWSCLIPROFILE"
  echo "Tagging backup as $BACKUP_TYPE_TAG"
  aws s3api put-object-tagging --bucket $S3BUCKET --tagging "TagSet=[{Key=backup_type,Value=${BACKUP_TYPE_TAG}}]" --key "${S3DIR}/${DATECODE}-${NSDBFILE}${FILE_EXT}"
}



# Main Program

# Trap signals
trap cleanup HUP INT QUIT ABRT TERM

# Send all output to log and screen
exec &> >(tee -a "$LOGFILE")

echo 
echo "***********************************************************"
echo "$(nstime) Starting $PGNAME..."

# Add path to aws-cli for cron to find it.
export PATH="$PATH:/usr/local/bin"

echo "Loading Configuration file..."
# Load custom client config file settings
if [ ! -f /usr/ns/cus/awsbackup.config  ]; then
  echo "ERROR: Configuration not found!"
  exit 1
fi

source /usr/ns/cus/awsbackup.config

# Assign date variables and build the date code
DAYOFWEEK="$(date '+%u')"
DAYOFMONTH="$(date '+%d')"
DATECODE="$(date +%Y%m%d)"

# Generate S3 destination directory & nsdb archive filename
S3DIR="$CUSTCODE/NovaStar/DBBackups"
NSDBFILE="$CUSTCODE-$HOSTNAME-$NODECODE-nsdb.bak"
# Default extra file extension is none for daily backups (set to FOM for monthly and FRI for weekly)
FILE_EXT=''

echo "S3 Bucket: $S3BUCKET"
echo "Customer Code: $CUSTCODE"
echo "Node Code: $NODECODE"
echo "Host Name: $HOSTNAME"
echo "AWS-CLI Profile: $AWSCLIPROFILE"
echo "Date Code: $DATECODE"
echo "Backup filename: $NSDBFILE"

# Create backup dir if it doesn't exist
if [ ! -d "$BAKDIR" ]; then
  mkdir -pv "$BAKDIR"
fi
cd "$BAKDIR"

# Generate local backup file in $BAKDIR
# (date code is not present so that local files don't accumulate).
echo "Backing up database.  This may take a while..."
#nsdbbackup "$NSDBFILE"
# Only dump the public schema, omitting replication data in the _novastar_slony schema.
pg_dump -v -Fc -h localhost -U novastar novastar -n public -f "$NSDBFILE"

# Upload the file to FTP Server, using datecode for remote filename.
if [ "${FTP_SERVER:=none}" == "none" ] ; then
  echo "Skipping FTP upload per configuration."
else
  echo "Uploading file $DATECODE$NSDBFILE to $FTP_SERVER via FTP..."
  ftp -ni "$FTP_SERVER" << __EOF__
user $FTP_USERNAME $FTP_PASSWORD
cd $FTP_DIR
put $NSDBFILE $DATECODE-$NSDBFILE
quit
__EOF__

fi

# If it's the first of the month append FOM to the backup.
# Else if it's a Friday, append .FRI to the backup
# Else make a regular daily backup.
if [ "$DAYOFMONTH" = 01 ];
then
  # Extra file extension for monthly backups.  Add the dot here so that when this variable is empty string, there is no extra extension and no extra dot at the end...
  FILE_EXT='.FOM'
  # Tag montly backups appropriately so that AWS lifecycle policies will deal with them as defined.
  # Montly backups are moved to Glacier storage after they are 6 months old.
  BACKUP_TYPE_TAG='monthly'
  # Call function to perform the actual upload
  upload_file_s3
elif [ "$DAYOFWEEK" = 5 ]
then
  FILE_EXT='.FRI'
  # Tag weekly backups appropriately
  # Weekly backups are kept 90 days
  BACKUP_TYPE_TAG='weekly'
  upload_file_s3
else
  # Assume this is a normal daily backup if the date is not the first or a Friday.
  # Note that if the date is Friday the 1st, the FOM extension is used as the month is checked first in this list.
  FILE_EXT=''
  # Tag daily backups appropriately
  # Daily backups are kept 30 days
  BACKUP_TYPE_TAG='daily'
  upload_file_s3
fi
echo "$(nstime) $PGDESC finished"
cleanup 0
