#!/bin/bash # # Author: Georg Voell - georg.voell@standby.cloud # Version: @(#)do-action 1.1.0 13.09.2024 (c)2024 Standby.cloud # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ # #@ Call oci-instance with 'action' and one or more hostnames (display names) or instance OCID. #@ #@Usage: do-action [action] [hostnames] #@ Action: #@ list : List all instances. #@ status : List only lifecycle-state of instance specified with instance-id. #@ show : Show one instance specified with instance-id. #@ stop : Stop instance specified with instance-id. #@ start : Start instance specified with instance-id. #@ open : Attach reserved public ip and allow access for ssh. #@ close : Detach reserved public ip and deny access for ssh. #@ add : Attach a Virtual IP (VIP) to instance. Extra parameter: IPV4 #@ delete : Detach a Virtual IP (VIP) from instance. Extra parameter: IPV4 #@ fullbackup : Make a full backup of all attached volumes (additional to regular backups). Extra parameter: Number between 0 and 99 #@ backup : Make a backup of all attached volumes. #@ restore : Restore previously backuped volumes. #@ maintenance: Manage backups. #@ update : Not yet implemented. # # Exit codes: # 01: No Tools installed. # 02: Need one or more hostnames. # 03: Tools not configured. # 04: Unable to get subscribed regions. # 05: Hostname does not match any instance display name. # # Update history: # # V 1.0.0 15.05.2021 First version # V 1.0.1 25.04.2022 New option "all" to find all instances / hostnames # V 1.0.2 30.04.2023 Accept hostnames with blank # V 1.1.0 13.09.2024 New minor version # # Find executable bash library and source it lib=`which lib.bash 2>/dev/null | sed 's|^no 'lib.bash' in .*||'` if [ "$lib" != "" ]; then source "$lib" else progdir=`dirname "$0"` if [ -r "${progdir}/lib.bash" ]; then source "${progdir}/lib.bash" else echo "Unexpected error: Unable to locate bash library 'lib.bash'." exit 1 fi fi # Do extra cleanup function ExtraCleanup() { filecheck -rm ${scratchfile}.inst } # Update the instance function DoUpdate() { local name=${1} local state=${2} printf "\nName: %s - State: %s\n" $name $state } # Preset action="" hostnames="" # Check parameters: Loop until all parameters are used up while [ $# -gt 0 ]; do pname=${1} case "$pname" in -v | --version) shift showversion=true ;; -h | --help) shift showhelp=true ;; *) shift paramck=`echo "$pname" | grep '^-'` # Keys don't begin with '-' if [ "$paramck" != "" ]; then errstr="Unknown option '$pname'." else if [ "$action" = "" ]; then action=`echo "$pname" | tolower` else if [ "$hostnames" = "" ]; then hostnames="$pname" else errstr="Unknown additional parameter: '$pname'." fi fi fi esac done # Display help or error message DisplayHelp # Plausibility check if [ "$action" = "" -o "$action" = "list" ]; then oci-instance list exit elif [ "$hostnames" = "" ]; then exitcode=2 errormsg $exitcode "Need one or more hostnames as second parameter (e.g. 'Bastion,Operator' or 'all')." exit $exitcode fi # Find oci-api ociapi=`which "oci-api" 2>/dev/null | sed 's|^no 'oci-api' in .*||'` if [ "$ociapi" = "" ]; then exitcode=3 errormsg $exitcode "'oci-api' not found." exit $exitcode fi # Source .admintools if [ -f "${HOME}/.admintools" ]; then source "${HOME}/.admintools" else exitcode=3 errormsg $exitcode "Please config Tools first with 'setup-tools config'." exit $exitcode fi # Define needed variables param=`echo "$action" | toupper` param2=`echo "$hostnames" | toupper` if [ "$param2" = "ALL" ]; then hostnames="ALL" else hosts=`ConvertKeys "$hostnames"` fi # Print start curdate=`date` printf "\n" printf "Starting : %s\nAction : %s\nInstances: %s\n" "$curdate" "$param" "$hostnames" | print-header # Check if we need to lookup OCIDs lookup=false for item in ${hosts}; do result=`echo "$item" | grep "^ocid.\.instance\."` if [ "$result" = "" ]; then # Something else then OCID found -> need lookup lookup=true fi done # Lookup all instance OCIDs in all regions if [ "$lookup" = true ]; then # Find region subscriptions regions=`$ociapi "identity.${HOME_REGION}.oraclecloud.com" "get" "/20160918/tenancies/${TENANCY_ID}/regionSubscriptions" \ | convert-json "regionName" --quiet --output tsv --noheader` if [ "$regions" = "" ]; then exitcode=4 errormsg $exitcode "Could no find any subscribed regions." exit $exitcode fi # Find all instances printf '{\n "type": "Structured",\n "query": "query %s resources"\n}\n' "instance" > $scratchfile touch ${scratchfile}.inst for region in $regions; do $ociapi query.${region}.oraclecloud.com "post" $scratchfile "/20180409/resources" \ | convert-json "displayName,lifecycleState,identifier,availabilityDomain,compartmentId" --quiet --output tsv --noheader \ | grep . >> ${scratchfile}.inst done fi if [ "$hostnames" = "ALL" ]; then while IFS=$'\t' read -r name state instanceid avd cid; do if [ "$action" = "update" ]; then DoUpdate $name $state else oci-instance "$action" --id "$instanceid" fi done < ${scratchfile}.inst else # Call oci-instance on each item count=`echo "$hosts" | wc -w` for item in ${hosts}; do item=`echo "$item" | tr ' ' ' '` # Convert non breaking space to space if [ $count -gt 1 ]; then printf "\n" printf "%s Instance: %s\n" "$param" "$item" | print-header fi if [ -f "${scratchfile}.inst" ]; then instanceid="" state="" result=`echo "$item" | grep "^ocid.\.instance\."` if [ "$result" = "" ]; then result=`grep "^$item " ${scratchfile}.inst | head -n 1` if [ "$result" != "" ]; then instanceid=`echo "$result" | cut -d$'\t' -f3` state=`echo "$result" | cut -d$'\t' -f2` fi else instanceid="$item" fi if [ "$instanceid" != "" ]; then if [ "$action" != "update" ]; then oci-instance "$action" --id "$instanceid" else DoUpdate $item $state fi else errormsg 5 "No instance '$item' found." fi else if [ "$action" != "update" ]; then oci-instance "$action" --id "$item" fi fi done fi # Print end curdate=`date` printf "\n" printf "Completed: %s\n" "$curdate" | print-header # Cleanup and exit Cleanup exit $exitcode