#!/bin/bash # #-------------------------------------------------------------------------------------------------------- # RSC 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 check_get_rsc_token () { if [ -z "${RSC_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 exit_with_error fi # If there is a cached credential file, use it if [ -f ~/.rbkRscsession.$id_string ]; then read expiration token < <(echo $(cat ~/.rbkRscsession.$id_string)) # If token expires within 30 min, get a new one if [ $expiration -lt $(( $($DATE +%s) + 1800 )) ]; then get_rsc_token else RSC_AUTH_TOKEN=$token fi else get_rsc_token fi fi } get_rsc_token () { MYENDPOINT="https://${RSC_HOST}/api/client_token" MYPAYLOAD="{\"client_id\":\"$ID\",\"client_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 RSC_AUTH_TOKEN=$(cat /tmp/rbkresponse.$$ | jq -r '.access_token') SECONDS=$(cat /tmp/rbkresponse.$$ | jq -r '.expires_in') EXPIRATION=$($DATE +%s -d "+${SECONDS} seconds") #cat /tmp/rbkresponse.$$ | jq echo "$EXPIRATION $RSC_AUTH_TOKEN" > ~/.rbkRscsession.$id_string } rsc_api_get () { check_get_rsc_token http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X GET $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $RSC_AUTH_TOKEN") check_http_error } rsc_api_post () { check_get_rsc_token http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X POST $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $RSC_AUTH_TOKEN" -H "Content-Type: application/json" -d $PAYLOAD) check_http_error } rsc_gql_query_old () { check_get_rsc_token ENDPOINT="https://${RSC_HOST}/api/graphql" #curl -s -o /tmp/rbkresponse.$$ -w "%{http_code}" -X POST $ENDPOINT \ curl -s -o /tmp/rbkresponse.$$ -X POST $ENDPOINT \ -H "Authorization: Bearer ${RSC_AUTH_TOKEN}" \ -H 'Content-Type: application/json' \ -d @- < /tmp/payload.$$ {"query": "$gqlQuery", "variables": $gqlVars} EOF http_response=$(curl -s -o /tmp/rbkresponse.$$ -w "%{http_code}" -X POST $ENDPOINT \ -H "Authorization: Bearer ${RSC_AUTH_TOKEN}" \ -H 'Content-Type: application/json' \ -d @/tmp/payload.$$) #cat /tmp/payload.$$ | jq -r error=$(cat /tmp/rbkresponse.$$ | jq -r '.errors // empty') if [ "$error" ]; then echo "ERROR: The last GraphQL API call returned an error" echo echo "PAYLOAD:" cat /tmp/payload.$$ | jq -r echo "RESPONSE:" cat /tmp/rbkresponse.$$ | jq -r '.errors' exit_with_error fi check_http_error } rsc_find_database () { # if cluster_uuid is not set, get it # gql query to find DB name, return the best one (based on CDM UUID etc) # if [ -z "${cluster_uuid}" ]; then #echo cluster UUID not, set, getting it get_cluster_uuid #echo Cluster UUID is $cluster_uuid else echo Cluster UUID was already $cluster_uuid fi variables="{ \"filter\":[{\"field\":\"REGEX\",\"texts\":[\"$RBK_SID\"]},{\"field\":\"IS_GHOST\",\"texts\":[\"false\"]},{\"field\":\"IS_ACTIVE\",\"texts\":[\"true\"]},{\"field\":\"CLUSTER_ID\",\"texts\":[\"$cluster_uuid\"]}], \"sortBy\":\"NAME\", \"sortOrder\":\"ASC\", \"first\":500 }" gql_GlobalSearchOracle='query GlobalSearchObjectQuery($first: Int!, $filter: [Filter!]!, $sortBy: HierarchySortByField, $sortOrder: SortOrder, $after: String) { globalSearchResults( first: $first filter: $filter sortBy: $sortBy sortOrder: $sortOrder after: $after ) { edges { cursor node { id name objectType logicalPath { fid name objectType __typename } physicalPath { fid name objectType __typename } ... on HierarchyObject { ...EffectiveSlaColumnFragment __typename } ... on OracleDatabase { cluster { ...ClusterFragment __typename } primaryClusterLocation { id __typename } isRelic __typename } ... on OracleRac { cluster { ...ClusterFragment __typename } primaryClusterLocation { id __typename } __typename } ... on OracleDataGuardGroup { cluster { ...ClusterFragment __typename } primaryClusterLocation { id __typename } isRelic __typename } __typename } __typename } pageInfo { endCursor startCursor hasNextPage hasPreviousPage __typename } __typename } } fragment ClusterFragment on Cluster { id name __typename } fragment EffectiveSlaColumnFragment on HierarchyObject { id effectiveSlaDomain { ...EffectiveSlaDomainFragment ... on GlobalSlaReply { description __typename } __typename } ... on CdmHierarchyObject { pendingSla { ...SLADomainFragment __typename } __typename } __typename } fragment EffectiveSlaDomainFragment on SlaDomain { id name ... on GlobalSlaReply { isRetentionLockedSla retentionLockMode __typename } ... on ClusterSlaDomain { fid cluster { id name __typename } isRetentionLockedSla retentionLockMode __typename } __typename } fragment SLADomainFragment on SlaDomain { id name ... on ClusterSlaDomain { fid cluster { id name __typename } __typename } __typename }' gqlQuery="$(echo $gql_GlobalSearchOracle)" gqlVars="$(echo $variables)" rsc_gql_query #cat /tmp/rbkresponse.$$ | jq -r num=$(cat /tmp/rbkresponse.$$ | jq -r '[.data.globalSearchResults.edges[] | select (.node.objectType=="ORACLE_DATA_GUARD_GROUP" and .node.isRelic==false)]| length') if [ $num -eq 1 ]; then #echo Good, There is just one DG with name $RBK_SID read name rsc_db_id < <(echo $(cat /tmp/rbkresponse.$$ | jq -r '.data.globalSearchResults.edges[] | select (.node.objectType=="ORACLE_DATA_GUARD_GROUP" and .node.isRelic==false)| .node.name, .node.id')) database_type="Data Guard" elif [ $num -gt 1 ]; then echo "ERROR: There were $num entries returned for Data Guard databases with name $RBK_SID" exit_with_error fi if [ -z "$rsc_db_id" ]; then #echo INFO: No Data Guard DB found with SID $RBK_SID. Looking for standalone DBs if [ -z "$RBK_HOST" ]; then num=$(cat /tmp/rbkresponse.$$ | jq -r '[.data.globalSearchResults.edges[] | select (.node.objectType=="OracleDatabase" and .node.isRelic==false)] | length') if [ $num -eq 1 ]; then read name rsc_db_id < <(echo $(cat /tmp/rbkresponse.$$ | jq -r '.data.globalSearchResults.edges[] | select (.node.objectType=="OracleDatabase" and .node.isRelic==false)| .node.name, .node.id')) database_type="Standalone" #echo Good, There is just one Standalone DB with name $name and RSC ID $rsc_db_id else echo "ERROR: There were $num entries returned from JQ for DB with name $RBK_SID on host $RBK_HOST" exit_with_error fi else num=$(cat /tmp/rbkresponse.$$ | jq -r --arg HOST "$RBK_HOST" '[.data.globalSearchResults.edges[] | select (.node.logicalPath[0].name==$HOST and .node.objectType=="OracleDatabase" and .node.isRelic==false)] | length') if [ $num -eq 1 ]; then read name rsc_db_id < <(echo $(cat /tmp/rbkresponse.$$ | jq -r --arg HOST "$RBK_HOST" '.data.globalSearchResults.edges[] | select (.node.logicalPath[0].name==$HOST and .node.objectType=="OracleDatabase" and .node.isRelic==false)| .node.name, .node.id')) database_type="Standalone" #echo Good, There is just one Standalone DB with name $name on ${RBK_HOST} and RSC ID $rsc_db_id else echo "ERROR: There were $num entries returned from for DB with name $RBK_SID on host $RBK_HOST" exit_with_error fi fi fi }