first commit

This commit is contained in:
2025-10-03 05:09:37 -04:00
commit 260689d7aa
3 changed files with 655 additions and 0 deletions

0
README.md Normal file
View File

368
oracle_funcs.sh Normal file
View File

@@ -0,0 +1,368 @@
#!/bin/bash
#
# Oracle shell script support functions
# v0.2 - James Pattinson - March 2022
nowait=0
LOGFILE=/tmp/rubrik_oracle.log
tabwidth=25
os=$(uname -o)
if [ $os == "Solaris" ]; then
# Use the GNU version of date binary
DATE=/usr/gnu/bin/date
else
DATE=$(which date)
fi
echo "`$DATE` -$$-: CALLED $0 $@" >> $LOGFILE
trap ctrl_c INT
function ctrl_c () {
echo "`$DATE` -$$-: TRAPPED CTRL-C - EXITING" >> $LOGFILE
exit_with_error
}
function ctrl_c_inhibit () {
echo "`$DATE` -$$-: TRAPPED CTRL-C - CONTINUING" >> $LOGFILE
}
exit_with_error () {
# if [ $usingsatoken ]; then
# ENDPOINT="https://$RUBRIK_IP/api/v1/session/me"
# rest_api_delete
# check_http_error
# fi
rm -f /tmp/rbkresponse.$$
rm -f /tmp/mountedDBs.$$
echo Aborting Script!
echo "`$DATE` -$$-: EXITED WITH ERROR $0 $@" >> $LOGFILE
exit 1
}
check_http_error () {
# All good responses start with a 2
if [ ${http_response:0:1} != "2" ]; then
echo FATAL: HTTP error from API call: $http_response. The server responded with:
cat /tmp/rbkresponse.$$ ; echo ; exit_with_error
fi
}
resolve_db () {
read name db_id sla_id dg_type dg_id RBK_HOST num_instances grp_name rac_name last_snap isrelic < <(echo $(cat /tmp/rbkresponse.$$ | jq -r --arg ID "OracleDatabase:::$id" '.data[] | select(.id==$ID) | .name, .id, .effectiveSlaDomainId, .dataGuardType, .dataGuardGroupId, .instances[0].hostName, .numInstances, .dataGuardGroupName, .racName, .lastSnapshotTime, .isRelic'))
if [ "$dg_id" != "null" ]; then
if [ "$last_snap" != "null" ]; then
[[ $rac_name != "null" ]] && string=$rac_name || string=$RBK_HOST
echo "WARNING: DG member on $string has snapshots created when DB was protected as standalone (non DG)"
echo "WARNING: Latest standalone snapshot taken $last_snap. Use -h $string to view or utilise them"
fi
id=$(echo $dg_id | cut -d: -f 4)
if [[ ! " ${DGDBs[*]} " =~ " ${id} " ]]; then
DGDBs+=("$id")
fi
else
actualDBs+=("$id")
fi
}
show_all_dbs () {
liveDBs=()
liveDBsWithSnaps=()
for id in "${actualDBs[@]}"; do
# cat /tmp/rbkresponse.$$ | jq -r
read name db_id sla_id dg_type dg_id RBK_HOST num_instances grp_name rac_name isrelic standaloneHostName last_snap db_unique_name < <(echo $(cat /tmp/rbkresponse.$$ | jq -r --arg ID "OracleDatabase:::$id" '.data[] | select(.id==$ID) | .name, .id, .effectiveSlaDomainId, .dataGuardType, .dataGuardGroupId, .instances[0].hostName, .numInstances, .dataGuardGroupName, .racName, .isRelic, .standaloneHostName, .lastSnapshotTime, .dbUniqueName'))
echo -n "WARNING: Object ID $id on "
[[ $standaloneHostName != "null" ]] && echo -n "host $standaloneHostName "
[[ $rac_name != "null" ]] && echo -n "RAC $rac_name "
[[ $grp_name != "null" ]] && echo "DG ID: $grp_name"
[[ $isrelic = "true" ]] && echo -n "(Relic)" || liveDBs+=("$id")
[[ $last_snap != "null" ]] && [[ $isrelic = "false" ]] && liveDBsWithSnaps+=("$id")
echo
done
#declare -p liveDBs
#declare -p liveDBsWithSnaps
for id in "${DGDBs[@]}"; do
echo -n "WARNING: Object ID $id on DG Group "
ENDPOINT="https://$RUBRIK_IP/api/v1/oracle/db/OracleDatabase:::$id"
rest_api_get_2
dgname=$(cat /tmp/rbkresponse2.$$ | jq -r '.dbUniqueName')
rm -f /tmp/rbkresponse2.$$
echo $dgname
done
}
select_db () {
# We have more than one matching DB. Select the best one
if [ "${#DGDBs[@]}" -eq 1 ]; then
echo WARNING: Selecting Data Guard DB ${DGDBs[0]}
id="${DGDBs[0]}"
elif [ "${#liveDBs[@]}" -eq 1 ]; then
echo WARNING: Selecting object ID ${liveDBs[0]} as it is not a Relic
id="${liveDBs[0]}"
elif [ "${#liveDBsWithSnaps[@]}" -eq 1 ]; then
echo WARNING: Selecting object ID ${liveDBsWithSnaps[0]} as it is not a Relic and has snapshots
id="${liveDBsWithSnaps[0]}"
else
echo "ERROR: Unable to determine unique DB. Please specify one of the above"
exit_with_error
fi
read name db_id sla_id dg_type dg_id RBK_HOST num_instances grp_name rac_name isrelic standaloneHostName last_snap < <(echo $(cat /tmp/rbkresponse.$$ | jq -r --arg ID "OracleDatabase:::$id" '.data[] | select(.id==$ID or .dataGuardGroupId==$ID) | .name, .id, .effectiveSlaDomainId, .dataGuardType, .dataGuardGroupId, .instances[0].hostName, .numInstances, .dataGuardGroupName, .racName, .isRelic, .standaloneHostName, .lastSnapshotTime'))
#exit_with_error
}
# Given RBK_SID return $db_id of matching database
find_database () {
specifiedhost=$RBK_HOST
# First get IDs of all the mounted DBs for this SID
ENDPOINT="https://$RUBRIK_IP/api/internal/oracle/db/mount"
rest_api_get
cat /tmp/rbkresponse.$$ | jq -r --arg SID "$RBK_SID" '.data[] | select(.mountedDatabaseId!=null and .mountedDatabaseName==$SID) | .mountedDatabaseId' > /tmp/mountedDBs.$$
# Now get a list of Oracle DBs
ENDPOINT="https://$RUBRIK_IP/api/v1/oracle/db?name=$RBK_SID"
rest_api_get
# If no host is specified then just look for the DB with the right SID
if [ -z $RBK_HOST ]; then
# get list of DB IDs in scope (sid matches and not a relic)
myDBs=$(cat /tmp/rbkresponse.$$ | jq -r --arg SID "$RBK_SID" '.data[] | select(.name==$SID) | .id' | sort | uniq)
myDGs=$(cat /tmp/rbkresponse.$$ | jq -r --arg SID "$RBK_SID" '.data[] | select(.name==$SID) | .dataGuardGroupId' | sort | uniq)
for db in $myDBs $myDGs; do
id=$(echo $db | cut -d: -f 4)
if grep -q $id /tmp/mountedDBs.$$; then
continue
else
break
fi
done
myDBs=( $(cat /tmp/rbkresponse.$$ | jq -r --arg SID "$RBK_SID" '.data[] | select(.name==$SID) | .id' | sort | uniq) )
myDGs=( $(cat /tmp/rbkresponse.$$ | jq -r --arg SID "$RBK_SID" '.data[] | select(.name==$SID) | .dataGuardGroupId' | sort | uniq) )
actualDBs=()
DGDBs=()
for db in "${myDBs[@]}"; do
id=$(echo $db | cut -d: -f 4)
resolve_db
done
if [ "$(( ${#actualDBs[@]} + ${#DGDBs[@]} ))" -gt 1 ]; then
echo "WARNING: There are multiple instances of $RBK_SID. Please re run the script with the -h option"
echo "WARNING: to interact with them. Script will attempt to select the correct DB."
show_all_dbs
select_db
else
id="${actualDBs[0]}"
fi
else
# Host was specified
hostspecified=true
read name db_id sla_id dg_type dg_id RBK_HOST racname num_instances grp_name < <(echo $(cat /tmp/rbkresponse.$$ | jq -r --arg SID "$RBK_SID" --arg HOST "$RBK_HOST" '.data[] | select(.name==$SID and (.infraPath[0].name==$HOST or .dataGuardGroupName==$HOST)) | .name, .id, .effectiveSlaDomainId, .dataGuardType, .dataGuardGroupId, .standaloneHostName, .racName, .numInstances, .dataGuardGroupName'))
fi
if [ "$RBK_HOST" = "null" ] && [ "$racname" != "null" ]; then
RBK_HOST=$racname
fi
if [ "$dg_type" == "DataGuardMember" ] && [ "$hostspecified" != "true" ] || [[ "$specifiedhost" == DG_GROUP* ]]; then
db_id=$dg_id
# Now find SLA of the DG GROUP not just the DB (which will be unprotected)
ENDPOINT="https://$RUBRIK_IP/api/v1/oracle/db/$db_id"
rest_api_get
sla_id=$(cat /tmp/rbkresponse.$$ | jq -r '.effectiveSlaDomainId')
fi
if [ -z "$db_id" ]; then
locate_mv_db
fi
if [ -z "$db_id" ]; then
echo FATAL: No DB found with SID $RBK_SID on host / cluster $RBK_HOST
exit_with_error
fi
}
locate_mv_db () {
# Look for a pair of MVs with names like $RBK_SID_data and $RBK_SID_logs
# Get list of MVs
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume"
rest_api_get
mvData=$(cat /tmp/rbkresponse.$$ | jq -r --arg NAME ${RBK_SID}_data '.data[] | select(.name==$NAME)| .id')
mvLogs=$(cat /tmp/rbkresponse.$$ | jq -r --arg NAME ${RBK_SID}_logs '.data[] | select(.name==$NAME)| .id')
if [ -n "$mvData" ] && [ -n "$mvLogs" ]; then
echo "INFO: MV found (Solaris Database)"
db_id=ManagedVolume
fi
}
check_get_token () {
if [ -z "${AUTH_TOKEN}" ]; then
id_string=$(echo $ID | cut -d: -f 4)
if [ -f ~/.rbksession.$id_string ]; then
echo "`$DATE` -$$-: AUTH SESSION FILE EXISTS" >> $LOGFILE
read expiration token < <(echo $(cat ~/.rbksession.$id_string))
if [ $($DATE +%s -d $expiration) -lt $(( $($DATE +%s) + 7200 )) ]; then
echo "`$DATE` -$$-: AUTH TOKEN EXPIRED" >> $LOGFILE
get_token
else
AUTH_TOKEN=$token
fi
else
get_token
fi
fi
}
get_token () {
trap '' INT
echo "`$DATE` -$$-: AUTH USER $ID" >> $LOGFILE
MYENDPOINT="https://$RUBRIK_IP/api/v1/service_account/session"
MYPAYLOAD="{\"serviceAccountId\":\"$ID\",\"secret\":\"$SECRET\"}"
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X POST $MYENDPOINT -H "accept: application/json" -H "Content-Type: application/json" -d $MYPAYLOAD)
check_http_error
AUTH_TOKEN=$(cat /tmp/rbkresponse.$$ | jq -r '.token')
SESSION=$(cat /tmp/rbkresponse.$$ | jq -r '.sessionId')
EXPIRATION=$(cat /tmp/rbkresponse.$$ | jq -r '.expirationTime')
echo "`$DATE` -$$-: AUTH SESSION $SESSION" >> $LOGFILE
echo "`$DATE` -$$-: SAVING TOKEN TO FILE" >> $LOGFILE
echo "$EXPIRATION $AUTH_TOKEN" > ~/.rbksession.$id_string
usingsatoken=1
trap ctrl_c INT
}
# HTTP GET: Given $ENDPOINT write output to file
rest_api_get () {
check_get_token
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X GET $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN")
echo "`$DATE` -$$-: REST API GET: ENDPOINT $ENDPOINT" >> $LOGFILE
echo "`$DATE` -$$-: REST API GET: RESPONSE STARTS" >> $LOGFILE
cat /tmp/rbkresponse.$$ >> $LOGFILE
echo >> $LOGFILE
echo "`$DATE` -$$-: REST API GET: RESPONSE ENDS" >> $LOGFILE
check_http_error
}
rest_api_get_2 () {
check_get_token
http_response=$(curl -s -k -o /tmp/rbkresponse2.$$ -w "%{http_code}" -X GET $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN")
echo "`$DATE` -$$-: REST API GET: ENDPOINT $ENDPOINT" >> $LOGFILE
echo "`$DATE` -$$-: REST API GET: RESPONSE STARTS" >> $LOGFILE
cat /tmp/rbkresponse2.$$ >> $LOGFILE
echo >> $LOGFILE
echo "`$DATE` -$$-: REST API GET: RESPONSE ENDS" >> $LOGFILE
check_http_error
}
# HTTP POST: Given $ENDPOINT and $PAYLOAD write output to file
rest_api_post () {
check_get_token
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X POST $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN" -H "Content-Type: application/json" -d $PAYLOAD)
echo "`$DATE` -$$-: REST API POST: ENDPOINT $ENDPOINT" >> $LOGFILE
echo "`$DATE` -$$-: REST API POST: PAYLOAD $PAYLOAD" >> $LOGFILE
echo "`$DATE` -$$-: REST API POST: RESPONSE STARTS" >> $LOGFILE
cat /tmp/rbkresponse.$$ >> $LOGFILE
echo >> $LOGFILE
echo "`$DATE` -$$-: REST API POST: RESPONSE ENDS" >> $LOGFILE
check_http_error
}
rest_api_post_empty () {
check_get_token
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X POST $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN" -H "Content-Type: application/json")
echo "`$DATE` -$$-: REST API POST: ENDPOINT $ENDPOINT" >> $LOGFILE
echo "`$DATE` -$$-: REST API POST: PAYLOAD <NULL>" >> $LOGFILE
echo "`$DATE` -$$-: REST API POST: RESPONSE STARTS" >> $LOGFILE
cat /tmp/rbkresponse.$$ >> $LOGFILE
echo >> $LOGFILE
echo "`$DATE` -$$-: REST API POST: RESPONSE ENDS" >> $LOGFILE
check_http_error
}
rest_api_patch () {
check_get_token
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X PATCH $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN" -H "Content-Type: application/json" -d "$PAYLOAD")
echo "`$DATE` -$$-: REST API PATCH: ENDPOINT $ENDPOINT" >> $LOGFILE
echo "`$DATE` -$$-: REST API PATCH: PAYLOAD $PAYLOAD" >> $LOGFILE
echo "`$DATE` -$$-: REST API PATCH: RESPONSE STARTS" >> $LOGFILE
cat /tmp/rbkresponse.$$ >> $LOGFILE
echo >> $LOGFILE
echo "`$DATE` -$$-: REST API PATCH: RESPONSE ENDS" >> $LOGFILE
check_http_error
}
rest_api_delete () {
check_get_token
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X DELETE $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN")
echo "`$DATE` -$$-: REST API DELETE: $http_response: ENDPOINT $ENDPOINT" >> $LOGFILE
check_http_error
}
# Given an ENDPOINT of an async job, monitor it
check_status () {
if [ $nowait -ne 1 ]; then
# Check the status in a loop
while true; do
rest_api_get
status=$(cat /tmp/rbkresponse.$$ | jq -r '.status')
if [ $status != "SUCCEEDED" ] && [ $status != "FAILED" ]; then
echo Status is $status, checking in 30 seconds
else
if [ $status != "SUCCEEDED" ]; then
echo OPERATION FAILED WITH STATUS $status
exit_with_error
else
echo OPERATION SUCCEEDED
return
fi
fi
sleep 30
done
else
# Show the Job ID
JOB_ID=$(cat /tmp/rbkresponse.$$ | jq -r '.id')
echo "Job submittsed. For more details of the job run:"
echo "oracle_jobs.sh -d $RBK_SID -j $JOB_ID"
echo "RMAN logs, if applioable, will be in /var/log/rubrik/script_logs/"
fi
}
cleanup () {
# if [ $usingsatoken ]; then
# ENDPOINT="https://$RUBRIK_IP/api/v1/session/me"
# rest_api_delete
# fi
echo "`$DATE` -$$-: EXITED $0 $@" >> $LOGFILE
rm -f /tmp/mountedDBs.$$
rm -f /tmp/rbkresponse.$$
}

287
oracle_mount.sh Normal file
View File

@@ -0,0 +1,287 @@
#!/bin/bash
#
# Perform a Live Mount of an Oracle DB
# v0.2 - James Pattinson - August 2021
#
# usage: oracle_mount.sh [-h <dbhost>] [-d <oracle_home> [-f] <srcSID> <tgtHOSTNAME> <"timestamp">
#
# -d specify $ORACLE_HOME on target - needed for mount of Data Guard DBs
# default is to performing a files-only mount
# -l mount and create DB Live Mount
#
# Timestamp YYYY-MM-DD HH:MM:SS
# Time is passed to 'date' on THIS machine, will use local timezone
MYDIR="$(dirname "$(realpath "$0")")"
source $MYDIR/rbk_api.conf
source $MYDIR/oracle_funcs.sh
# Local commands to mount and unmount NFS volumes
MOUNT="sudo /usr/local/sysadmin/utils/manage_rubrik_restore_mvs.ksh"
UMOUNT="sudo /usr/local/sysadmin/utils/manage_rubrik_restore_mvs.ksh"
usage() { echo "Usage: $0 <-d DBNAME> <-t \"timestamp\"> <-g tgthost || -r rachost> [-h <dbhost>] [-o <oracle_home>] [-m <mountpoint> [-l|-n]" 1>&2; exit 1; }
filesonly=true
while getopts "d:t:g:r:m:h:o:ln" o; do
case "${o}" in
d)
RBK_SID=${OPTARG}
;;
t)
datestring=${OPTARG}
;;
g)
RBK_TGT=${OPTARG}
;;
r)
RAC_TGT=${OPTARG}
;;
m)
mountpoint=${OPTARG}
;;
h)
RBK_HOST=${OPTARG}
;;
o)
oraclehome=${OPTARG}
;;
l)
filesonly=false
;;
n)
nowait=true
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
if [ -z "${RBK_SID}" ] || [ -z "${datestring}" ]; then
usage
fi
#if [ -z "${RAC_TGT}" ] && [ -z "${RBK_TGT}" ]; then
# usage
#fi
if [ -n "${RBK_TGT}" ] && [ -n "${RAC_TGT}" ]; then
echo "ERROR: Specify either -g or -r, not both"
usage
fi
if [ -z "${mountpoint}" ]; then
mountpoint=/rbk
fi
echo Connecting to Rubrik with IP $RUBRIK_IP
# API call to list Oracle DBs
find_database
mount_mv () {
utctime=$($DATE -d"$datestring" +"%Y-%m-%d %H:%M:%S")
if [ $? -ne 0 ]; then
echo ERROR: Unable to convert supplied timestamp to UTC time
exit_with_error
fi
echo INFO: Requested time is $datestring which is $utctime in UTC
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume/$mvData/snapshot"
rest_api_get
# Select snapshot of data volume with timestamp before requested time
read mvDataSnap dtDataSnap < <(echo $(jq -r --arg t "$utctime" '
[($t) | strptime("%Y-%m-%d %H:%M:%S")] as $r
| .data | map(select(
(.date[:19] | strptime("%Y-%m-%dT%H:%M:%S")) as $d
| $d <= $r[0]
)) | sort_by(.date) | last | "\(.id) \(.date)"' /tmp/rbkresponse.$$))
echo Snapshot ID to mount is $mvDataSnap from $dtDataSnap
# List MVs for logs volume
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume/$mvLogs/snapshot"
rest_api_get
# Select snapshot of logs volume with timestamp after requested time
read mvLogsSnap dtLogsSnap < <(echo $(jq -r --arg t "$utctime" '
[($t) | strptime("%Y-%m-%d %H:%M:%S")] as $r
| .data | map(select(
(.date[:19] | strptime("%Y-%m-%dT%H:%M:%S")) as $d
| $d >= $r[0]
)) | sort_by(.date) | first | "\(.id) \(.date)"' /tmp/rbkresponse.$$))
echo Snapshot ID of Logs Volume to mount is $mvLogsSnap from $dtLogsSnap
if [ -z "${RBK_TGT}" ]; then
clients=$(hostname)
echo INFO: hostname $clients is not fully qualified, adding domain name to it. Use -g flag to override client name pattern
clients=$(hostname).$(domainname)
else
clients=${RBK_TGT}
fi
PAYLOAD="{\"hostPatterns\":[\"$clients\"]}"
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume/snapshot/$mvDataSnap/export"
rest_api_post
DATA_ENDPOINT=$(cat /tmp/rbkresponse.$$ | jq -r '.links[0].href')
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume/snapshot/$mvLogsSnap/export"
rest_api_post
LOGS_ENDPOINT=$(cat /tmp/rbkresponse.$$ | jq -r '.links[0].href')
datajobdone=0
logsjobdone=0
while true; do
if [ $datajobdone -eq 0 ]; then
ENDPOINT=$DATA_ENDPOINT
rest_api_get
datastatus=$(cat /tmp/rbkresponse.$$ | jq -r '.status')
echo "INFO: Data Mount status is $datastatus"
if [[ $datastatus =~ SUCCEEDED|FAILED|CANCELED ]]; then
datajobdone=1
dataExport=$(cat /tmp/rbkresponse.$$ | jq -r ' .links | .[] | select(.rel=="result") .href')
fi
fi
if [ $logsjobdone -eq 0 ]; then
ENDPOINT=$LOGS_ENDPOINT
rest_api_get
logsstatus=$(cat /tmp/rbkresponse.$$ | jq -r '.status')
echo "INFO: Logs Mount status is $logsstatus"
if [[ $logsstatus =~ SUCCEEDED|FAILED|CANCELED ]]; then
logsjobdone=1
logsExport=$(cat /tmp/rbkresponse.$$ | jq -r ' .links | .[] | select(.rel=="result") .href')
fi
fi
if [ $logsjobdone -eq 1 ] && [ $datajobdone -eq 1 ]; then
echo Data Export details
ENDPOINT=$dataExport
rest_api_get
dataMounts=$(cat /tmp/rbkresponse.$$ | jq -r '.channels[] | ( .ipAddress + ":" + .mountPoint)')
ENDPOINT=$logsExport
rest_api_get
logMounts=$(cat /tmp/rbkresponse.$$ | jq -r '.channels[] | ( .ipAddress + ":" + .mountPoint)')
for mountPath in $dataMounts $logMounts; do
leaf=$(echo $mountPath | cut -d/ -f4)
echo creating folder and mounting $mountPath at $mountpoint/$RBK_SID/$leaf
mkdir -p $mountpoint/$RBK_SID/$leaf
$MOUNT $mountPath $mountpoint/$RBK_SID/$leaf
done
cleanup
exit
else
sleep 10
fi
done
}
mount_snappable () {
if [ "$dg_type" == "DataGuardMember" ]; then
echo Initiating mount from source $RBK_SID \($grp_name\)
else
[[ $rac_name != "null" ]] && [[ -n "$rac_name" ]] && string=$rac_name || string=$RBK_HOST
echo Initiating mount from source $RBK_SID on $string
fi
if [ -n "${RBK_TGT}" ]; then
# API call to get the host ID of the target
ENDPOINT="https://$RUBRIK_IP/api/internal/oracle/host?name=$RBK_TGT"
rest_api_get
total=$(cat /tmp/rbkresponse.$$ | jq -r .total)
if [ $total -ne 1 ]; then
echo ERROR: Target host name of $RBK_TGT does not map to a single host.
echo ERROR: Matching hosts are listed here. Please re-run using one of the following:
cat /tmp/rbkresponse.$$ | jq -r '.data[].name'
exit_with_error
fi
target_id=$(cat /tmp/rbkresponse.$$ | jq -r '.data[0].id')
else
# API call to get the host ID of the target
ENDPOINT="https://$RUBRIK_IP/api/internal/oracle/rac?name=$RAC_TGT"
rest_api_get
total=$(cat /tmp/rbkresponse.$$ | jq -r .total)
if [ $total -ne 1 ]; then
echo ERROR: Target RAC Cluster name of $RAC_TGT does not map to a single entity:
echo ERROR: Matching clusters are listed here. Please re-run using one of the following:
cat /tmp/rbkresponse.$$ | jq -r '.data[].name'
exit_with_error
fi
target_id=$(cat /tmp/rbkresponse.$$ | jq -r '.data[0].id')
fi
# convert datestamp from string into milliseconds
echo requested timestamp is $datestring
ts=$(date -d"$datestring" +%s)
if [ $? -ne 0 ]; then
echo Problem with timestamp
exit_with_error
fi
((millis = $ts * 1000))
if [ ! -z ${oraclehome+x} ]; then
configmap="\"ORACLE_HOME\":\"$oraclehome\""
fi
# API call to perform the mount
PAYLOAD="{\"recoveryPoint\":{\"timestampMs\":$millis},\"targetOracleHostOrRacId\":\"$target_id\",\"targetMountPath\":\"$mountpoint\",\"shouldMountFilesOnly\":$filesonly,\"advancedRecoveryConfigMap\":{$configmap}}"
ENDPOINT="https://$RUBRIK_IP/api/internal/oracle/db/$db_id/mount"
rest_api_post
ENDPOINT=$(cat /tmp/rbkresponse.$$ | jq -r '.links[0].href')
LOOP=0
while true; do
rest_api_get
status=$(cat /tmp/rbkresponse.$$ | jq -r '.status')
if [ $status != "SUCCEEDED" ] && [ $status != "FAILED" ]; then
echo Status is $status, checking in 15 seconds
if [ $status = "RUNNING" ] && [ ${LOOP} -ne 1 ] ; then
LOOP=1
sleep 5
save=$ENDPOINT
ENDPOINT="https://$RUBRIK_IP/api/internal/oracle/db/mount?source_database_name=$dbname"
rest_api_get
RBK_ID_LV=$(cat /tmp/rbkresponse.$$ | jq -r '.data[] | select(.status=="Mounting") | .id')
ENDPOINT=$save
fi
else
if [ $status != "SUCCEEDED" ]; then
echo LIVE MOUNT FAILED WITH STATUS $status
exit_with_error
else
echo LIVE MOUNT SUCCEEDED
echo "The live mount id is: ${RBK_ID_LV}"
# cat /tmp/rbkresponse.$$ | jq -r ' '
cleanup
exit 0
fi
fi
sleep 15
done
}
if [ "$db_id" == "ManagedVolume" ]; then
mount_mv
else
mount_snappable
fi
cleanup