#!/bin/bash # #-------------------------------------------------------------------------------------------------------- # Oracle shell script support functions # v0.2 - James Pattinson - August 2021 # v0.3 - U701053 - 30.03.2022 - if database not found, try to search with the ENDPOINT datagurad # v0.4 - James Pattinson 25/01/23 - Adding support for Service Accounts #-------------------------------------------------------------------------------------------------------- MYDIR="$(dirname "$(realpath "$0")")" source $MYDIR/rbk_api.conf # -- Mobi config --------- #RBK_ENV=$OUTI/shell/rubrik/conf/rbk_env # -- End Mobi config ---- # -- Mobi config ----------- #if [ -f "${RBK_ENV}" ] ; then # source ${RBK_ENV} #else # echo "The ${RBK_ENV} file is not found ...." # exit_with_error #fi # -- End Mobi config ------- nowait=0 if [[ "$OSTYPE" == "darwin"* ]]; then DATE=gdate else DATE=date fi exit_with_error () { rm -f /tmp/rbkresponse.$$ echo Aborting Script! exit 1 } # for canceled status exit_with_cancel () { rm -f /tmp/rbkresponse.$$ echo Canceling Script! exit 1 } # for undoing status exit_with_undoing () { rm -f /tmp/rbkresponse.$$ echo undoing Script! 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 } # Given RBK_SID return $db_id of matching database find_database () { # 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 dtaabse is found, try with dataguard if [ `cat /tmp/rbkresponse.$$ | grep "id\":" | wc -l` -eq 0 ]; then echo " DB not found, try with dataguard..." ENDPOINT="https://$RUBRIK_IP/api/v1/oracle/db?is_data_guard_group=true&is_relic=false&name=$RBK_SID" rest_api_get fi #echo "=================================" #cat /tmp/rbkresponse.$$ | jq -r '.data[]' | tee /tmp/titi #echo "=================================" #echo "cat /tmp/rbkresponse.$$ | jq -r '.data[]'" # 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 and .isRelic==false) | .id' ; cat /tmp/rbkresponse.$$ | jq -r --arg SID "$RBK_SID" '.data[] | select(.name==$SID and .isRelic==false) | .dataGuardGroupId' | sort | uniq) for db in $myDBs; do id=$(echo $db | cut -d: -f 4) if grep -q $id /tmp/mountedDBs.$$; then continue else break fi done # Get the details for the specific DB ID read name db_id sla_id dg_type dg_id RBK_HOST num_instances grp_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')) # Host was specified else read name db_id sla_id dg_type dg_id RBK_HOST num_instances grp_name < <(echo $(cat /tmp/rbkresponse.$$ | jq -r --arg SID "$RBK_SID" --arg HOST "$RBK_HOST" '.data[] | select(.sid==$SID and .infraPath[0].name==$HOST and .isRelic==false) | .name, .id, .effectiveSlaDomainId, .dataGuardType, .dataGuardGroupId, .instances[0].hostName, .numInstances, .dataGuardGroupName')) fi if [ "$dg_type" == "DataGuardMember" ]; 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 echo FATAL: No DB found with SID $RBK_SID on host $RBK_HOST if [ "${SCRIPT}" = "check_recoverable_range.sh" ] ; then export ret=11 else exit_with_error fi else echo " db_id is: $db_id" fi } check_get_token () { if [ -z "${AUTH_TOKEN}" ]; then if [[ "${ID}" =~ ^client ]]; then # Looks like an RSC service account id_string=$(echo $ID | cut -d\| -f 2) else # Not an RSC service account id_string=$(echo $ID | cut -d: -f 4) fi # If there is a cached credential file, use it if [ -f ~/.rbksession.$id_string ]; then read expiration token < <(echo $(cat ~/.rbksession.$id_string)) # If token expires within 30 min, get a new one if [ $($DATE +%s -d $expiration) -lt $(( $($DATE +%s) + 1800 )) ]; then get_token else AUTH_TOKEN=$token fi else get_token fi fi } get_token () { 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 "$EXPIRATION $AUTH_TOKEN" > ~/.rbksession.$id_string } # 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") 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) check_http_error } rest_api_post_file () { 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" --data-binary @/tmp/payload.$$) check_http_error rm -f /tmp/payload.$$ } 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") 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) 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") check_http_error } get_cluster_uuid () { ENDPOINT="https://$RUBRIK_IP/api/v1/cluster/me" rest_api_get cluster_uuid=$(cat /tmp/rbkresponse.$$ | jq -r .id) } # 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" ] && [ $status != "CANCELED" ] && [ $status != "UNDOING" ]; then echo Status is $status, checking in 30 seconds else if [ $status != "SUCCEEDED" ]; then if [ $status = "CANCELED" ] ; then echo OPERATION FAILED WITH STATUS $status exit_with_cancel elif [ $status = "UNDOING" ] ; then echo OPERATION FAILED WITH STATUS $status exit_with_undoing else echo OPERATION FAILED WITH STATUS $status exit_with_error fi else echo OPERATION SUCCEEDED exit 0 fi fi sleep 30 done fi } cleanup () { rm -f /tmp/mountedDBs.$$ rm -f /tmp/rbkresponse.$$ rm -f /tmp/payload.$$ }