Skip to content
This repository was archived by the owner on Dec 1, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
237 changes: 237 additions & 0 deletions Filesets/invoke-filesetrestore.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
#!/bin/bash
# Requires 'curl' and 'jq'
# https://build.rubrik.com
# Written by Steven Tong for community usage
# Date: 12/10/20, updated: 10/24/21

# This script will restore a fileset to an alternate host (fileset export).
# A list of source and target directories must be provided.
# The script will list the available snapshots for the fileset so the user can select a point in time for restore.
# Once selected the script will kick off a restore job for each source-target directory pair.

# For authentication, use either an API token or base64 encoded username:password

### RUBRIK VARIABLES - BEGIN ###
# Configure an API token for authentication
TOKEN=''
# Configure a username:password for authenciation
# The username:password must be encoded as a base64 string.
# Use 'echo -n "admin:GoRubrik123" | base64' to generate with most Linux distros
USER_PASS=''
# Hostname or IP address of the Rubrik cluster
RUBRIK=''
# SOURCE - Fileset ID that you want to restore from
FILESETID='Fileset:::62155444-b52f-410b-b5d1-64e371787f5b'
# SOURCE - List of directories to restore, separated by a space in the array.
# All files and sub-directories under these directories will be selected for restore.
SOURCE_DIR=('/epic/prd01' '/epic/prd02' '/epic/prd03')
# TARGET - List of directories to restore to, must have same number of directories as $SOURCE_DIR.
# All files and sub-directories from each source directory will be restored to the corresponding target directory.
TARGET_DIR=('/restore/prd01' '/restore/prd02' '/restore/prd03')
# TARGET - Host ID that you want to restore to.
# If $TARGET_HOSTID is blank, the restore will be done to the same host it was backed up from
TARGET_HOSTID=''
# TARGET_HOSTID='Host:::37eaa1b3-df31-4c06-9ae5-18e0f9ce8769'
# Set MONITOR to non-zero if you want the script to monitor progress until the backup has finished
MONITOR=0
# Script execution time
LOGPATH= #SomePath
LAUNCHTIME=`date +%m%d%y_%H%M%S`
################################################################################

### Check to ensure the json utility jq is installed
echo $SHELL

command -v jq >/dev/null 2>&1 || { echo >&2 "Script requires the utility jq. Aborting."; exit 1; }

# If an API token is provided, use that. Otherwise, use username password
if [ "$TOKEN" != '' ]
then
AUTH_HEADER='Authorization:bearer '
AUTH_HEADER+=$TOKEN
else
AUTH_HEADER='Authorization:basic '
AUTH_HEADER+=$USER_PASS
fi

# Checks if the number of restore directories to target directories is equal, exits on error
if [ ${#SOURCE_DIR[@]} != ${#TARGET_DIR[@]} ]
then
echo "ERROR: Number of SOURCE_DIR is not equal to TARGET_DIR. ABORTING"
exit 1
fi

# Check that the target host is valid if it is configured
if [ "$TARGET_HOSTID" != '' ]
then
# Gets the hostname of the Target Host ID and exits if the host is not found
TARGET_HOSTNAME=''
HOSTINFO=$(curl -H "$AUTH_HEADER" -X GET -H 'Content-Type: application/json' 'https://'$RUBRIK'/api/v1/host/'$TARGET_HOSTID -k -1 -s)
TARGET_HOSTNAME=$(echo $HOSTINFO | jq -r '.name')

if [ "$TARGET_HOSTNAME" = '' ]
then
echo "ERROR: No TARGET_HOSTID found. ABORTING"
exit 1
fi
fi

# Grabs the info and snapshot list for the Source Fileset ID
FILESETINFO=$(curl -H "$AUTH_HEADER" -X GET -H 'Content-Type: application/json' 'https://'$RUBRIK'/api/v1/fileset/'$FILESETID -k -1 -s)

# Initiate an array to store the snapshot IDs and dates
# The oldest snapshot will be the first index in the array (array[1])
SNAPSHOTIDS=()
SNAPSHOTDATES=()

# Get the snapshots from the fileset data
SNAPSHOTINFO=$(echo $FILESETINFO | jq -c '.snapshots[]')

# Loop through the snapshots and pull out the snapshot IDs and dates
while read -r line
do
SNAPSHOTIDS+=($(echo $line | jq -r '.id'))
SNAPSHOTDATES+=($(echo $line | jq -r '.date'))
done <<< "$SNAPSHOTINFO"

# List out all the snapshots found and the corresponding array index for selection
echo -e "\n## Snapshot Dates (UTC)"
echo "-- --------------------"

i=0
while [ $i -lt ${#SNAPSHOTDATES[@]} ]
do
printf '%-3s %-20s\n' $i ${SNAPSHOTDATES[$i]}
((i++))
done

USERSNAPSHOT=-1

# Prompts for which snapshot # to recover from with some lightweight checking
while [[ $USERSNAPSHOT -lt 0 || $USERSNAPSHOT -ge ${#SNAPSHOTDATES[@]} ]]
do
echo -e -n "\nEnter snapshot # to recover from: "
read USERSNAPSHOT

if [[ $USERSNAPSHOT -lt 0 || $USERSNAPSHOT -ge ${#SNAPSHOTDATES[@]} ]]
then
echo "Selection outside acceptable range, try again"
fi
done

# Sets the snapshot ID that is selected by the user to $SNAPSHOTIDTORESTORE
SNAPSHOTIDTORESTORE=${SNAPSHOTIDS[$USERSNAPSHOT]}

# Lists out the details of the snapshot selected for review
echo -e "\nRestoring from: ${SNAPSHOTDATES[$USERSNAPSHOT]} UTC; snapshot ID: $SNAPSHOTIDTORESTORE"

if [ "$TARGET_HOSTID" != '' ]
then
echo "Target hostname: $TARGET_HOSTNAME; host ID: $TARGET_HOSTID"
else
echo "Restoring to same host since no target host id was configured"
fi

echo -e "Fileset ID: $FILESETID\n"
echo "Source Directory to Target Directory"
echo "--------------------------------------"

i=0
while [ $i -lt ${#SOURCE_DIR[@]} ]
do
echo "${SOURCE_DIR[$i]} to ${TARGET_DIR[$i]}"
((i++))
done

# Checks that the user wants to proceed by typing 'y'. Otherwise, exits script
echo -e -n "\nType 'y' to proceed: "
read USERPROCEED

if [ "$USERPROCEED" != 'y' ]
then
echo "Exiting script"; exit 2
fi

# Create JSON for restore body
RESTORE_JSON='{ "restoreConfig": [ '

# Loop through all the source directories to create JSON body
SOURCECOUNT=0
while [ $SOURCECOUNT -lt ${#SOURCE_DIR[@]} ]
do
# Get the list of files and sub-folders under the source directory
DIRINFO=$(curl -H "$AUTH_HEADER" -X GET -H 'Content-Type: application/json' \
'https://'$RUBRIK'/api/internal/browse?limit=500&snapshot_id='$SNAPSHOTIDTORESTORE'&path='${SOURCE_DIR[$SOURCECOUNT]} -k -1 -s)

# Test if the source directory info was returned, and if not, exit script
TESTDIRINFO=$(echo $DIRINFO | jq -r '.data[].filename')
if [ "$TESTDIRINFO" = '' ]
then
echo "ERROR: Invalid path info for source directory: ${SOURCE_DIR[$SOURCECOUNT]}. ABORTING"
exit 1
else
# Create an array of all the files and sub-folders (paths) under the source directory
PATHLIST=()

PATHINFO=$(echo $DIRINFO | jq -r '.data[].filename')
while read -r line
do
PATHLIST+=($line)
done <<< $PATHINFO
fi

# Loop through each path, create a JSON for the source-target pair, and add to the restore JSON body
PATHCOUNT=0
while [ $PATHCOUNT -lt ${#PATHLIST[@]} ]
do
PATHBODY='{ "path": "'${SOURCE_DIR[$SOURCECOUNT]}'/'${PATHLIST[$PATHCOUNT]}'", "restorePath": "'${TARGET_DIR[$SOURCECOUNT]}'" }'
RESTORE_JSON+=$PATHBODY
((PATHCOUNT++))

# Check if this is the last path to be added, and if not, add ", " to the JSON body
if [ $PATHCOUNT -lt ${#PATHLIST[@]} ]
then
RESTORE_JSON+=', '
fi
done # while [ $PATHCOUNT -le ${#PATHLIST[@]} ]
((SOURCECOUNT++))

# Check if this is the last source directory to be processed, and if not, add ", " to the JSON body
if [ $SOURCECOUNT -lt ${#SOURCE_DIR[@]} ]
then
RESTORE_JSON+=', '
fi
done # while [ $SOURCECOUNT -le ${#SOURCE_DIR[@]} ]

# Complete JSON for the restore body
RESTORE_JSON+=' ], "ignoreErrors": false }'

echo "Restore request:"
echo $RESTORE_JSON | jq

# Invoke the restore task
RESULT=$(curl -X POST -H "$AUTH_HEADER" -H 'Content-Type: application/json' -d "$RESTORE_JSON" 'https://'$RUBRIK'/api/internal/fileset/snapshot/'$SNAPSHOTIDTORESTORE'/restore_files' -k -1 -s)
echo $RESULT

if [ $MONITOR -ne 0 ]; then
# Reset $STATUS in case it contains other values
STATUS=""

# Pull out the URL that we use to query status
HREF=$(echo $RESULT | sed -e 's/.*href\"\:\"\(.*\)\"\,.*/\1/')
RUBRIKSTATUS=0

while [ $RUBRIKSTATUS -eq 0 ]
do
# Query the URL for the current status of the on demand backup
STATUS=$(curl -H "$AUTH_HEADER" -X GET -H 'Content-Type: application/json' "$HREF" -k -1 -s)

# Check if any of the end states are found, if so, $RUBRIKSTATUS changes and loop exits
RUBRIKSTATUS=$(echo $STATUS | grep 'SUCCESS\|SUCCESSWITHWARNINGS\|FAILURE\|CANCELED' -c)

echo $STATUS
sleep 30
done

echo $STATUS
fi
117 changes: 117 additions & 0 deletions Filesets/iperf_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/bin/bash
# https://build.rubrik.com
# Written by Steven Tong for community usage
# Date: 10/15/21

# This script will run 'iperf3' against several source-target host pairs using specified iPerf parameters.
# The results will output to a JSON file which can then be parsed using:
# - https://github.com/rubrikinc/rubrik-scripts-for-powershell/blob/master/MISC/Parse-iPerfResults.ps1
# The script can log into each TARGET host to put it in '-s' mode,
# or you can manually put all TARGETS in '-s'.
# The script will cycle through all the SOURCE hosts and run iPerf to the TARGET hosts.
# iPerf parameters should be specified and each parameter will be a test run.
# You will need passwordless SSH in order for this script to work.
# The script is setup to use Rubrik nodes as the source and ESXi hosts as a target as an example.

# File results will be appended to
RESULTS="./iperf_results_$(date +%Y-%m-%d)_$(date +%H%M).json"
# Log file
LOGPATH="./iperf_test.log"
# iPerf command to run on source side (Tx, executes -c with arguments)
SOURCE_IPERF3="network iperf -3"
# iPerf command to run on target side (Rx, executes -s)
TARGET_IPERF3="/usr/lib/vmware/vsan/bin/iperf3.copy"
# SSH user for source hosts
SOURCE_USERNAME="admin"
# SSH user for target hosts
TARGET_USERNAME="root"
# Service name to kill on target host when finished testing
TARGET_IPERF3_SERVICE="iperf3.copy"

# Array of source hosts, iPerf Tx, these use '-c' and send traffic
SOURCE_IPERF=('rubrik1' 'rubrik2' 'rubrik3' 'rubrik4')

# Array of target hosts, iPerf Rx, these are put in server mode (-s) and receive traffic
# Use the following if you want to specify different targets
TARGET_IPERF=('esxi1' 'esxi2' 'esxi3')

# Use the following if you want to test between all source pairs
# TARGET_IPERF=("${SOURCE_IPERF[@]}")

# Whether to SSH to each TARGET to put it in iperf server (-s) mode
# '1' or non-zero to put the TARGET in -s mode
# '0' to not put the TARGET in -s mode
# If '0' then you will manually login to each target host and put into 'iperf3 -s' mode
TARGET_SERVER_MODE=1

# iPerf parameters to use, below are some common ones
# -J : Always include to output results to JSON
# -t <#> : # of seconds to run each test for
# -P <#> : # of parallel threads, default 1, recommend also testing w/4
# -w <#> : TCP window size
# -R : Reverse the direction of source / target (send and receive)
IPERF_PARAMS=('-t 15 -J' '-t 15 -P 4 -J' '-t 15 -R -J' '-t 15 -P 4 -R -J')

echo -e "\n\nLogging started: $(date +%m-%d-%y) $(date +%H:%M:%S)" >> $LOGPATH

# Make a copy of iperf3 to use if testing ESXi hosts
echo -e "\n\nMaking a copy of iperf3: $(date +%m-%d-%y) $(date +%H:%M:%S)" | tee -a $LOGPATH
COMMAND="cp /usr/lib/vmware/vsan/bin/iperf3 $IPERF3"
# for i in "${SOURCE_IPERF[@]}"; do
# ssh -t $SOURCE_USERNAME@$i -- $COMMAND >> $LOGPATH
# done
for i in "${TARGET_IPERF[@]}"; do
ssh -t $TARGET_USERNAME@$i -- $COMMAND >> $LOGPATH
done

# Run iperf3 test matrix for each host
echo -e "\n\nRunning iperf3 test matrix: $(date +%m-%d-%y) $(date +%H:%M:%S)" | tee -a $LOGPATH

# Loop through each host as the target
for target in "${TARGET_IPERF[@]}"; do
# Put the target into iPerf '-s' server mode
if [ $TARGET_SERVER_MODE != 0 ]; then
echo -e "\n${target}: Putting into iperf3 server mode (-s): $(date +%m-%d-%y) $(date +%H:%M:%S)" | tee -a $LOGPATH
COMMAND="hostname;$TARGET_IPERF3 -s"
ssh -f $TARGET_USERNAME@$target -- $COMMAND >> $LOGPATH
fi

# Loop through each host as a source
for source in "${SOURCE_IPERF[@]}"; do
# Loop through each param and perform an iperf for each source-target-param pairing
for param in "${IPERF_PARAMS[@]}"; do
# Run test if the source and target host are different
if [ $source != $target ]; then
echo -e "\nSource: $source; Target: $target; $SOURCE_IPERF3 -c $param" | tee -a $LOGPATH
COMMAND="$SOURCE_IPERF3 -c $target $param"
ssh -t $SOURCE_USERNAME@$source -- $COMMAND >> $RESULTS

SLEEP 3
fi
done
done

if [ $TARGET_SERVER_MODE != 0 ]; then
# Kill iPerf3 service on the target host
echo -e "\n${target}: Killing iperf3 service: $(date +%m-%d-%y) $(date +%H:%M:%S)" | tee -a $LOGPATH
COMMAND="hostname;pkill $TARGET_IPERF3_SERVICE"
ssh -t $TARGET_USERNAME@$target -- $COMMAND >> $LOGPATH
fi

done


# Put iperf3 in server mode on all hosts
# echo -e "\n\nPutting all hosts into iperf3 server mode: $(date +%m-%d-%y) $(date +%H:%M:%S)" | tee -a $LOGPATH
# COMMAND="hostname;$IPERF3 -s"
#
# for i in "${SOURCE_IPERF[@]}"; do
# ssh -f $SOURCE_USERNAME@$i -- $COMMAND >> $LOGPATH
# done

# Kill any running iPerf3 process
# echo -e "\n\nKilling iperf3 service on all hosts: $(date +%m-%d-%y) $(date +%H:%M:%S)" | tee -a $LOGPATH
# COMMAND="hostname;pkill $IPERF3_SERVICE"
# for i in "${SOURCE_IPERF[@]}"; do
# ssh -t $SOURCE_USERNAME@$i -- $COMMAND >> $LOGPATH
# done
Loading