#!/bin/bash
##########################################
#
# Script to deal with the maintenance of old EBS volumes
# For running instructions run the script with the -h flag
#
##########################################

SNAPSHOT=0
LIST_VOLUMES=0
DELETE_VOLUMES=0
PURGE_SNAPSHOTS=0
AGE_DEFAULT=$(date --date='-3 months' '+%Y-%m-%d')
BLUE='\033[1;34m'
GREEN='\033[1;32m'
NC='\033[0m' # No Color

usage() {
  cat << EOF
  $0 [-h] [-d <delete_volumes>] [-p <purge_snapshots>] [-a <age(YYYY-MM-DD)>] [-s <create_snapshots>] 
  Flags:
    -h: Help and exit
    -a: Age of volumes to delete, volumes older that this date will be considered, YYYY-MM-DD format (Default: $AGE_DEFAULT)
    -l: List volumes which are in available state before given date
    -s: Create snapshots of the lited volumes as backups before deletion, will be prompted for confirmation before deletion
    -d: Delete Volumes older than a set date, will be prompted for confirmation before deleting
    -p: purge snapshots: Will remove snapshots marked for delete, will be prompted for confirmation before deletion
  Extra:
    *** REQUIRES: Valid AWS API Access (via any of the usual AWS config mechanisms) ***
    
EOF
}


run_checks(){

   AGE=${AGE:-$AGE_DEFAULT}

   # Check permissions

   echo "Checking AWS permissions for all commands needed ..."

   response=$(aws ec2 describe-volumes --dry-run --region us-east-1 2>&1 >/dev/null)
   if [[ $response == *"AuthFailure"* ]]; then
       echo "You do not have permissions to describe volumes"
       exit 1
   fi
   response=$(aws ec2 create-snapshot --dry-run --volume-id vol-1234567 --region us-east-1 2>&1 >/dev/null)
   if [[ $response == *"AuthFailure"* ]]; then
       echo "You do not have permissions to create snapshots"
       exit 1
   fi
   response=$(aws ec2 delete-volume --dry-run --volume-id vol-1234567 --region us-east-1 2>&1 >/dev/null)
   if [[ $response == *"AuthFailure"* ]]; then
       echo "You do not have permissions to delete volumes"
       exit 1
   fi
   response=$(aws ec2 describe-snapshots --dry-run --region us-east-1 2>&1 >/dev/null)
   if [[ $response == *"AuthFailure"* ]]; then
       echo "You do not have permissions to describe snapshots"
       exit 1
   fi
   response=$(aws ec2 delete-snapshot --dry-run --snapshot-id snap-1234567 --region=us-east-1 2>&1 >/dev/null)
   if [[ $response == *"AuthFailure"* ]]; then
       echo "You do not have permissions to delete snapshots"
       exit 1
   fi

   echo "Permissions are accepted"

   if [ ${LIST_VOLUMES} -gt 0 ]; then
       get_volume_list
   fi
   if [ ${SNAPSHOT} -gt 0 ]; then
       get_volume_list
       create_snapshots
   fi
   if [ ${DELETE_VOLUMES} -gt 0 ]; then
       get_volume_list
       delete_volumes
   fi
   if [ ${PURGE_SNAPSHOTS} -gt 0 ]; then
       get_snapshots
   fi


}

get_volume_list (){

   volumes=$(aws ec2 describe-volumes --filters Name=status,Values=available | jq --arg age $AGE -c '.Volumes[] | select(.CreateTime <= $age) | select((.Tags | length) < 1)')


   vol_ids=()
   echo "Volume_ID        Create_Time     Size     State    Volume_Type  Tags"
   for row in $(echo "${volumes}" | jq -r '. | @base64'); do
       _jq() {
        echo ${row} | base64 --decode | jq -r ${1}
       }
       echo $(_jq '.VolumeId,.CreateTime,.Size,.State,.VolumeType,.Tags')
       vol_ids+=($(_jq '.VolumeId'))
   done

   echo -e "${BLUE}${#vol_ids[@]} Volumes would be affected by any potential action${NC}"
}
	
create_snapshots(){
   read -p $'\e[93m Would you like to create snapshots of all the volumes lised above [y/n] \e[0m'  yn
   if [[ $yn == "y" ]] || [[ $yn == "Y" ]];then
        echo "Creating snapshots"
   else
   	echo "exiting now"
   	exit 1
   fi


   timestamp=$(date --iso-8601=seconds)
   delete_date=$(date -I -d '+1 month')
   failure=false
   for vol in ${vol_ids[@]}
   do
      created_snaps=$(aws ec2 create-snapshot --volume-id $vol --description 'Back up old volumes before deletion' --tag-specifications "ResourceType=snapshot,Tags=[{Key=Name,Value=OldVolumeSnapshot},{Key=VolumeId,Value=$vol},{Key=MarkedForDelete,Value=True},{Key=DeleteDate,Value=$delete_date}]")
      current_snap=$(echo $created_snaps | jq -r .SnapshotId)
      if [ ! -z "${current_snap}" ]; then
	   echo $current_snap from $vol >> successful_snaps-${timestamp}.txt
      else
           echo "snapshot failed for $vol"
	   echo $vol >> failed_snaps-${timestamp}.txt
	   failure=true
      fi
   done
   echo "successful snaps written to succesful_snaps-${timestamp}.txt"
   if [ $failure = true ]; then
      echo "failed snaps writen to failed_snaps-${timestamp}.txt"
   fi
}
	
	
delete_volumes(){
   read -p $'\e[93m Would you like to delete the volumes lised above [y/n] \e[0m'  yn
   if [[ $yn == "y" ]] || [[ $yn == "Y" ]];then
        echo "Deleting Volume"
   else
   	echo "exiting now"
   	exit 1
   fi

   timestamp=$(date --iso-8601=seconds)
   failure=false

   for vol in ${vol_ids[@]}
   do
      aws ec2 delete-volume --volume-id $vol
      if [ $? -ne 0 ]; then
	 echo "deletion of volume $vol failed"
         echo "deletion failed on $vol" >> delete_fail-${timestamp}.txt
	 failure=true
      fi
   done

   if [ $failure = true ]; then
      echo "some volumes failed to delete writen to delete_fail-${timestamp}.txt"
   else
      echo "all volumes deleted successfully"
   fi

}

get_snapshots(){
   snapshots=$(aws ec2 describe-snapshots --filters Name=tag:MarkedForDelete,Values=True | jq -r '.Snapshots[]')
   delete_date_snap_ids=$(echo $snapshots | jq -r --arg date $(date --iso-8601) '. | select(.Tags[].Value | . <= $date) | .SnapshotId')
   marked_for_delete_snaps=$(echo $snapshots | jq -r '.SnapshotId')

   echo -e "${GREEN}Which snapshots would you like to delete?"
   echo "    1. All snapshots with MarkedForDelete Tag"
   echo "    2. Only snapshots MarkedForDelete with DeleteDate passed"
   echo "    3. Don't delete, list all effected by option 1"
   echo  -e "    4. Don't delete, list all effected by option 2${NC}"
   read -p $'\e[93m Please enter your selection [1/2/3/4] \e[0m'  option
   if [[ $option == "1" ]];then
        echo "All snaps:" 
	echo "$marked_for_delete_snaps" | xargs -n1
	snap_ids=($marked_for_delete_snaps)
	delete_snapshots
   elif [[ $option == "2" ]]; then
   	echo "Passed date snaps: "
	echo "$delete_date_snap_ids" | xargs -n1
	snap_ids=($delete_date_snap_ids)
	delete_snapshots
   elif [[ $option == "3" ]]; then
        echo "All snaps:" 
	echo "$marked_for_delete_snaps" | xargs -n1
   elif [[ $option == "4" ]]; then
   	echo "Passed date snaps: "
	echo "$delete_date_snap_ids" | xargs -n1
   else
	echo "invalid choice, exiting ...."
	exit 1
   fi
}

delete_snapshots(){
   read -p $'\e[93m Deleting selected snapshots. Are you sure? [y/n] \e[0m' yn
   if [[ $yn == "Y" ]] || [[ $yn == "y" ]]; then
      echo "Deleting snapshots ...."
      failure=false
      for snap in ${snap_ids[@]}
      do
	 aws ec2 delete-snapshot --snapshot-id $snap
	 if [ $? -ne 0 ]; then
            echo "failed to delete snapshot $snap"
            echo "deletion failed on $snap" >> snap_delete_fail-${timestamp}.txt
	    failure=true
	 fi  
      done

      if [ $failure = true ]; then
         echo "some snapshots failed to delete writen to snap_delete_fail-${timestamp}.txt"
      else
         echo "all snapshots deleted successfully"
      fi
   else
      echo "Snapshots will not be deleted. Exiting ..."
   fi 
}


# options
while getopts hpsdla: opt ; do
  case $opt in
    l)
      LIST_VOLUMES=1
      ;;
    s)
      SNAPSHOT=1
      ;;
    d)
      DELETE_VOLUMES=1
      ;;
    p)
      PURGE_SNAPSHOTS=1
      ;;
    a)
      AGE=${OPTARG}
      ;;
    h)
      usage
      exit 0
      ;;
    *)
      usage
      exit 1
      ;;
  esac
done

run_checks 
