====== Backup ======
This snapshot backup enable you to have retention.\\
this manage my infrastructure backup on ec2.
==== Requirement : ====
  * perl
  * Net::Amazon::EC2
  * DBI:SQLite
  * bash
==== Files : ====
  * config             # store your amazon key here
  * db.pl              # manage local DB for your snapshot / dates / volume
  * backup.sh          # Cron this script
  * create_snap.pl     # Create Snapshot
  * config_bash        # Manage config of your retention / backup
  * snap_status.pl     # Check status of your snapshot
  * delete_snap.pl     # Delete Snapshot which is out of retention.
===== C0D3s =====
==== config ====
#!/usr/bin/perl
$awsId = ''; 
$awsKey = '';
$awsinstance = ''; ## right now it is not used anywhere
==== bash config ====
# this file contain what need to be backup.  
# Follow the format of value
# instance =   
instance1="vol-2222pqrs 7 2"
instance2="vol-1111abcd 1 1"
==== db.pl ====
#!/usr/bin/perl
# developed by k2patel
# k2patel@hotmail.com
# this Script Manage all Backup Record.
use Switch;
use DBI;
$filename = 'machine.db';
unless (-e $filename) {
	print "Creating Database...";
	$dbh = DBI->connect( "dbi:SQLite:machine.db" ) || die "Cannot connect: $DBI::errstr";
	$dbh->do( "CREATE TABLE DESK ( v_ID, s_ID, Dte )" );
	$dbh->disconnect;
} 
my($num_args) = $#ARGV + 1;
if ($num_args < 3) {
  print "\nUsage: db.pl    []\n";
  print "Operation : Allowed \"add / get / del\" \n";
  print "All three Value require\n";
  print "Snapshot ID must provided when the Operation is Add / Del\n";
  exit 1;
}
$dbh = DBI->connect( "dbi:SQLite:machine.db" ) || die "Cannot connect: $DBI::errstr";
switch( $ARGV[0] ){
	case "add"	{
		if ($ARGV[3] eq ''){
			print "You can not use ADD without Snapshot";
			exit 1;
		}else{
		$dbh->do( "INSERT INTO DESK VALUES ( '$ARGV[1]', '$ARGV[2]', '$ARGV[3]' )" );
		}
	}
	case "del"	{
		if ($ARGV[3] eq ''){
			print "You can not use DEL without Snapshot";
			exit 1;
		}else{
		$dbh->do( "DELETE FROM DESK WHERE s_ID = '$ARGV[2]' AND Dte = '$ARGV[3]'" );
		}
	}
	case "get"	{
		$res = $dbh->selectall_arrayref( "SELECT s_ID, Dte FROM DESK WHERE v_ID = '$ARGV[1]' AND Dte = '$ARGV[2]'" );
		foreach( @$res ) {
			#print "$_->[0] $_->[1] $_->[2]\n";
			print "$_->[0] $_->[1] $_->[2]\n"
			}
	}
	else
		{
		$res = $dbh->selectall_arrayref( "SELECT * FROM DESK" );
		foreach( @$res ) {
			print "$_->[0] $_->[1] $_->[2]\n";
			}
		}
}
$dbh->disconnect;
==== backup.sh ====
#!/bin/bash
# developed by k2patel
# k2patel@hotmail.com
############# Read ME ###############
# this Script will do the Backup and remove old copy.
# This script work based on existing DB Entry.
# When you initialize it only create one copy rest of the dummy entry need to be entered by you.
#####################################
BASE="$( cd "$( dirname "$0" )" && pwd )"
cd $BASE
source config_bash
DATE=$(date +%Y%m%d)
perl=$(which perl)
for inst in instance{1..10}
do
	eval var1=\$$inst
	arry=($var1)
if [[ $1 == "init" ]]; then
	if [ "$var1" != "" ]
		then
			vol=${arry[0]}
			echo "Running backup for $vol stored in "
			newsnp=`$perl create_snap.pl $vol $DATE`
			$perl db.pl add $vol $newsnp $DATE
			echo "waiting."
			$perl snap_status.pl $newsnp
			echo "done"
	fi
else
	if [ "$var1" != "" ]
		then
		freq=${arry[1]}
		vol=${arry[0]}
		iter=${arry[2]}
		lookup=$(echo "$iter * $freq" | bc)
		isit=`date -d "now -$lookup days" +%Y%m%d`
		isit_nxt=`date -d "now -$freq days" +%Y%m%d`
		lstnc=(`$perl $BASE/db.pl get "$vol" "$isit"`)
		if [ "$isit" == "${lstnc[1]}" ];then
				echo "Running backup for $vol stored in "
				newsnp=`$perl create_snap.pl $vol $DATE`
				$perl db.pl add $vol $newsnp $DATE
				echo "waiting."
				$perl snap_status.pl $newsnp
				echo "done"
				lstnx=(`$perl $BASE/db.pl get "$vol" "$isit_nxt"`)
			if [ "${lstnx[0]}" == '' ]; then
				echo "Notify Admin"
			else
				if [ "${lstnc[0]}" != '' ]; then
					$perl delete_snap.pl ${lstnc[0]}
				fi
			fi
		else
			echo "backup is not needed"
		fi
	fi
fi
done
==== create snapshot ====
#!/usr/bin/perl -w
# Created / written by k2patel@hotmail.com
# this script create snapshot for given volume.
use Data::Dumper;
use strict;
#use Date::Calc qw( :all );
use lib "/usr/share/perl5/vendor_perl";
use Net::Amazon::EC2;
# Configuration.
require "config";
# our $ec2;
our $awsId;
our $awsKey;
our $awsinstance;
my($num_args) = $#ARGV + 1;
if ($num_args < 2) {
  print "\nUsage: create_snap.pl  \n";
  print "This will create Snapshot for given Volume\n";
  print "Format for today's Date must be \"YYYYMMDD\"\n";
  exit 1;
}
## Define Access Keys for Amazon.
my $ec2 = Net::Amazon::EC2->new(
        AWSAccessKeyId => $awsId, 
        SecretAccessKey => $awsKey
);
my @result = $ec2->create_snapshot(
VolumeId => $ARGV[0],
Description => $ARGV[1]
);
print $result[0]->{snapshot_id};
#print Dumper \@result;
==== delete shnapshot ====
# This script delete snapshot of requested volume
# Author : k2patel 
# Please send me message for suggestion or update.
# this script delete snapshot
use Data::Dumper;
use strict;
#use Date::Calc qw( :all );
use lib "/usr/share/perl5/vendor_perl";
use Net::Amazon::EC2;
# Configuration.
require "config";
# our $ec2;
our $awsId;
our $awsKey;
our $awsinstance;
my($num_args) = $#ARGV + 1;
if ($num_args < 1) {
  print "\nUsage: delete_snap.pl \n";
  print "This will Delete Snapshot\n";
  exit 1;
}
## Define Access Keys for Amazon.
my $ec2 = Net::Amazon::EC2->new(
        AWSAccessKeyId => $awsId, 
        SecretAccessKey => $awsKey
);
my @result = $ec2->delete_snapshot(
SnapshotId => $ARGV[0]
);
if ( $result[0] eq 1 ){
	#print "Good to go \n";
	exit 0;
}else{
	my $err = Dumper \@result;
	open F,">./rnd895896";
	print F $err;
	close F;
	if(system ("/bin/mail -s \"ERROR : Dump Of Error\" k2patel\@hotmail.com < ./rnd895896") == 0){
		unlink "./rnd895896";
	}
	exit 1;
	}
==== Check Snapshot status ====
# This script check status of given snapshot and wait for it get completed.
# Author : k2patel 
# Please send me message for suggestion or update.
use Data::Dumper;
use strict;
#use Date::Calc qw( :all );
use lib "/usr/share/perl5/vendor_perl";
use Net::Amazon::EC2;
# Configuration.
require "config";
# our $ec2;
our $awsId;
our $awsKey;
our $awsinstance;
my($num_args) = $#ARGV + 1;
if ($num_args < 1) {
  print "\nUsage: snap_status.pl \n";
  print "This will check Snapshot Status\n";
  exit 1;
}
## Define Access Keys for Amazon.
my $ec2 = Net::Amazon::EC2->new(
        AWSAccessKeyId => $awsId, 
        SecretAccessKey => $awsKey
);
my @result = $ec2->describe_snapshots(
SnapshotId => $ARGV[0]
);
while ( $result[0][0]->{status} ne 'completed' ){
	sleep 10;
}
if ( $result[0][0]->{status} eq 'completed' ){
	my $tst = "Good to go \n";
	exit 0;
}else{
	my $err = Dumper \@result;
	open F,">./rnd892346";
	print F $err;
	close F;
	if(system ("/bin/mail -s \"ERROR : Dump Of Error\" k2patel\@hotmail.com < ./rnd892346") == 0){
		unlink "./rnd892346";
	}
	exit 1;
	}
==== Machine DB ====
sqlite3 machine.db
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE DESK ( v_ID, s_ID, Dte );