#!/bin/bash # # Author: Georg Voell - georg.voell@standby.cloud # Version: @(#)setup-tools 3.2.0 12.08.2024 (c)2024 Standby.cloud # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ # # This script can be used free of charge. Use it as is or customize as needed. It is not guaranteed to be # error free and you will not be reimbursed for any damage it may cause. # #@ Check if all needed tools are installed and have the right version - else install them. #@ Configure oci tools and copy configuration to an operator host. #@ Optional: Setup a core infrastructure with terraform and execute terraform commands. #@ #@Usage: setup-tools [options] [action] #@ Options: -h, --help : Displays helptext. #@ -v, --version: Displays the version of the script. #@ Action: #@ update : Install or update Scripts and Tools. #@ remove : Delete installed Scripts and Tools. #@ config : Configure oci tools. #@ classic : Configure classic tools. #@ setup : Setup a core infrastructure (multitier) via terraform. #@ terraform : Manage your resources with terraform e.g.: setup-tools terraform "apply -auto-approve". #@ push : Copy configuration to destination ("user@ip" e.g. "opc@130.61.219.239"). # # Update history: # # V 3.0.0 24.04.2020 New version # V 3.0.1 11.06.2020 Using library # V 3.0.2 22.06.2020 Renamed "check-tools" to "setup-tools" and added actions # V 3.0.3 12.07.2020 Calling bootstrap # V 3.0.4 06.09.2020 Terraform config # V 3.0.5 06.09.2020 16.09.2020 Use new download URL: https://standby.cloud/download # V 3.0.6 23.09.2020 Packer included # V 3.0.7 17.10.2020 Warning if local keys could not be imported # V 3.0.8 17.01.2021 Remove get-authkeys also / bootstrap disabled # V 3.0.9 21.03.2021 Create file api-config # V 3.0.10 26.05.2021 New PreAuth Rules for Project Bucket and Terraform compartment with subs # V 3.0.11 15.11.2021 Include multitier infrastructure # V 3.0.12 13.12.2021 Small changes (Log handling) # V 3.0.13 06.09.2022 Init cli psm # V 3.1.0 05.06.2023 New copyright # V 3.1.1 23.08.2023 Install oci-tools and ocifs and start oci service # V 3.1.2 15.11.2023 Minor bugfixes # V 3.1.3 18.07.2024 Check for internet connectivity # V 3.2.0 12.08.2024 New minor version # # Exit codes: # 01: Unknown or wrong parameter. # 02: Unknown action # 03: Need root privileges # 04: No internet # 05: Unexpected error # 99: User interrupt. # # 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 # Repository where we load out scripts and tools from readonly baseurl="https://standby.cloud/download" # Logfile if [ "$LOGFILE" != "" ]; then logfile="$LOGFILE" else if [ ! -d "${REALHOME}/logs" ]; then mkdir -p "${REALHOME}/logs" fi logfile="${REALHOME}/logs/${progstr}.log" fi # Set some defaults needinstall=0 # Do extra cleanup function ExtraCleanup() { filecheck -rm ${scratchfile}.comp filecheck -rm ${scratchfile}.user if [ "$authuserid" != "" ]; then # Cleanup api key if [ "$fpid" != "" ]; then $oci iam user api-key delete --user-id "$authuserid" --fingerprint "$fpid" --force 2>/dev/null fi # Cleanup access key if [ "$s3id" != "" ]; then $oci iam customer-secret-key delete --user-id "$authuserid" --customer-secret-key-id "$s3id" --force 2>/dev/null fi fi if [ "$projectname" != "" ]; then # Cleanup PreAuth bucket access if [ "$preauthwid" != "" ]; then $oci os preauth-request delete --bucket-name "$projectname" --par-id "$preauthwid" --force 2>/dev/null fi if [ "$preauthrid" != "" ]; then $oci os preauth-request delete --bucket-name "$projectname" --par-id "$preautrwid" --force 2>/dev/null fi fi # Reset terminal tset } function CheckNewerVersion() { local tool=${1} local curvers=${2} local newvers="" local response="" local resultstr="" curl=`filecheck -x curl` if [ "$curl" != "" ]; then if [ "$tool" != "" -a "$curvers" != "" ]; then cmd=`basename $tool` case "$cmd" in terraform | packer | jq | rclone | opc) # echo "$curl -L -s ${baseurl}/lists/cmd${bits}.txt" >/dev/stderr response=`$curl -L -s ${baseurl}/lists/cmd${bits}.txt | grep "^${cmd}"$'\t' | grep $'\t'"$OS$"` ;; ansible | psm | oci | sdk) response=`$curl -L -s ${baseurl}/lists/zip.txt | grep "^${cmd}"$'\t'` ;; esac if [ "$response" != "" ]; then newvers=`echo "$response" | cut -d$'\t' -f2` if [ "$newvers" != "" ]; then resultstr=`compare-version --quiet $curvers $newvers` # echo "resultstr: '$resultstr'." if [ "$resultstr" = "newer" ]; then echo " (newer version $newvers available)" fi fi fi fi fi } function DisplayVersion() { stat=0 printf "\nInstalled tools:\n\n" printf "tool\tversion\n" > $scratchfile cmds="grep tail tar sed curl file tcsh zip unzip wget base32 telnet puttygen nslookup git java python3 pip3 jq rclone opc terraform packer ansible psm oci sdk" for cmd in $cmds; do case "$cmd" in java) cmd="$cmd --min 1.8.0.5 --max 1.8.0" # Needed by glassfish ;; python3) cmd="$cmd --min 3.3" # Needed by psm ;; jq) cmd="$cmd --min 1.5" # Needed by browse-json ;; terraform) cmd="$cmd --min 1.0" # Needed by templates / modules ;; puttygen) cmd="$cmd --min 0.76" # Needed by key creation ;; esac installed=`check-version $cmd` stat=$? if [ $stat -gt 0 ]; then needinstall=1 if [ "$proc" = "arm" ]; then if [ "$cmd" = "opc" ]; then printf "%s ${red}(not available for ARM architecture)${normal}\n" "$installed" else printf "%s ${red}(needs to be installed)${normal}\n" "$installed" fi else if [ "$OS" = "SunOS" -a "$cmd" = "puttygen" -o "$OS" = "SunOS" -a "$cmd" = "opc" ]; then printf "%s ${red}(not available for Solaris)${normal}\n" "$installed" else printf "%s ${red}(needs to be installed)${normal}\n" "$installed" fi fi else tool=`echo "$installed" | cut -d' ' -f1` version=`echo "$installed" | cut -d' ' -f2` okstr=`echo "$installed" | cut -d' ' -f3` printf "$tool\t$version\n" >> $scratchfile if [ "$okstr" = "need" ]; then needinstall=1 printf "%s ${red}(needs to be updated)${normal}\n" "$installed" else cmd=`echo "$installed" | cut -d' ' -f1` vers=`echo "$installed" | cut -d' ' -f2` found=`echo "$installed" | cut -d' ' -f3` newerstr=`CheckNewerVersion "$cmd" "$vers"` if [ "$found" = "ok" ]; then printf "%s %s ${green}%s${normal}%s\n" "$cmd" "$vers" "$found" "$newerstr" else printf "%s %s ${yellow}%s${normal}%s\n" "$cmd" "$vers" "$found" "$newerstr" fi fi fi done # Reset terminal tset } #function DisplayAll() { # if [ -f $infofile ]; then # printf "\nOS Info:\n\n" # osinfos="os id_like name version_id pretty_name machine release" # for key in $osinfos; do # value=`grep "^${key}:" $infofile | cut -d':' -f2-` # if [ "$value" != "" ]; then # printf "%12s: %s\n" "$key" "$value" # fi # done # # printf "\nIP Info:\n\n" # value=`grep "^ip:" $infofile | cut -d':' -f2` # if [ "$value" = "" ]; then # printf "%12s: No internet connection\n\n" "ip" # else # ipinfos="ip country city asn asn_org" # for key in $ipinfos; do # value=`grep "^${key}:" $infofile | cut -d':' -f2-` # if [ "$value" != "" ]; then # printf "%12s: %s\n" "$key" "$value" # fi # done # fi # # printf "\nCloud Info:\n\n" # value=`grep "^cloud_id:" $infofile | cut -d':' -f2` # if [ "$value" = "" ]; then # printf "%12s: No internet connection\n\n" "cloud_id" # else # cdinfos="cloud_id instance_id" # for key in $cdinfos; do # value=`grep "^${key}:" $infofile | cut -d':' -f2-` # if [ "$value" != "" ]; then # printf "%12s: %s\n" "$key" "$value" # fi # done # fi # fi # # if [ -f $scratchfile ]; then # printf "\nInstalled Tools:\n\n" # print-table --import $scratchfile # fi # # if [ -f $scriptsfile ]; then # printf "\nInstalled Scripts:\n\n" # print-table --import $scriptsfile # fi # # if [ -f $templatesfile ]; then # printf "\nInstalled Templates:\n\n" # print-table --import $templatesfile # fi #} WriteOCIJson() { # Check if we could write to file touch $ocijson > /dev/null 2>&1 stat=$? if [ $stat -eq 0 ]; then printf '{\n' > $ocijson printf ' "oci": {\n' >> $ocijson printf ' "tenancyname": "%s",\n' $tenancyname >> $ocijson printf ' "tenancyid": "%s",\n' $tenancyid >> $ocijson printf ' "homeregion": "%s"\n' $homeregion >> $ocijson printf ' },\n' >> $ocijson printf ' "keys": {\n' >> $ocijson printf ' "username": "%s",\n' $username >> $ocijson printf ' "userid": "%s",\n' $authuserid >> $ocijson printf ' "apikey": "%s",\n' $apikey >> $ocijson printf ' "fingerprint": "%s",\n' $fingerprint >> $ocijson printf ' "passphrase": "%s",\n' $passphrase >> $ocijson printf ' "privkey": "%s",\n' $privkey >> $ocijson printf ' "pubkey": "%s"\n' $pubkey >> $ocijson printf ' },\n' >> $ocijson printf ' "s3": {\n' >> $ocijson printf ' "namespace": "%s",\n' $namespace >> $ocijson printf ' "accesskey": "%s",\n' $accesskeyid >> $ocijson printf ' "secretkey": "%s"\n' $secretaccesskey >> $ocijson printf ' }\n' >> $ocijson printf '}\n' >> $ocijson chmod 600 $ocijson fi return $stat } WriteProjectJson() { # Check if we could write to file touch $projectjson > /dev/null 2>&1 stat=$? if [ $stat -eq 0 ]; then printf '{\n' > $projectjson printf ' "project": {\n' >> $projectjson printf ' "name": "%s",\n' $projectname >> $projectjson printf ' "compartmentid": "%s",\n' $compartmentid >> $projectjson printf ' "writeuri": "%s",\n' $writeuri >> $projectjson printf ' "readuri": "%s"\n' $readuri >> $projectjson printf ' }\n' >> $projectjson printf '}\n' >> $projectjson chmod 600 $projectjson fi return $stat } ReadOCIJson() { # Check if json config file exisits and is readable if [ -r "$ocijson" ]; then stat=0 else stat=1 fi if [ $stat -eq 0 ]; then tenancyname="`cat "$ocijson" | browse-json oci/tenancyname --select 1 --quiet --raw`" tenancyid="`cat "$ocijson" | browse-json oci/tenancyid --select 1 --quiet --raw`" homeregion="`cat "$ocijson" | browse-json oci/homeregion --select 1 --quiet --raw`" username="`cat "$ocijson" | browse-json keys/username --select 1 --quiet --raw`" authuserid="`cat "$ocijson" | browse-json keys/userid --select 1 --quiet --raw`" privkey="`cat "$ocijson" | browse-json keys/privkey --select 1 --quiet --raw`" pubkey="`cat "$ocijson" | browse-json keys/pubkey --select 1 --quiet --raw`" apikey="`cat "$ocijson" | browse-json keys/apikey --select 1 --quiet --raw`" fingerprint="`cat "$ocijson" | browse-json keys/fingerprint --select 1 --quiet --raw`" passphrase="`cat "$ocijson" | browse-json keys/passphrase --select 1 --quiet --raw`" namespace="`cat "$ocijson" | browse-json s3/namespace --select 1 --quiet --raw`" accesskeyid="`cat "$ocijson" | browse-json s3/accesskey --select 1 --quiet --raw`" secretaccesskey="`cat "$ocijson" | browse-json s3/secretkey --select 1 --quiet --raw`" fi return $stat } ReadProjectJson() { # Check if json config file exisits and is readable if [ -r "$projectjson" ]; then stat=0 else stat=1 fi if [ $stat -eq 0 ]; then projectname="`cat "$projectjson" | browse-json project/name --select 1 --quiet --raw`" compartmentid="`cat "$projectjson" | browse-json project/compartmentid --select 1 --quiet --raw`" writeuri="`cat "$projectjson" | browse-json project/writeuri --select 1 --quiet --raw`" readuri="`cat "$projectjson" | browse-json project/readuri --select 1 --quiet --raw`" fi return $stat } function InitOCITool() { local tenancyid=${1} local ociregion=${2} local username=${3} local authuserid=${4} local myprivkey=${5} local fingerprint=${6} local passphrase=${7} # Check if .oci folder exists - otherwise create it if [ ! -d "$ocifolder" ]; then mkdir -m 0755 -p "$ocifolder" printf "Created folder '$ocifolder'.\n" fi # Create oci config file from template if it doesn't exists yet if [ ! -f "$ocicfgfile" ]; then if [ -f "$ocitemplate" ]; then myprivkey=`echo "$myprivkey" | sed 's|~/|'${REALHOME}'/|'` cat "$ocitemplate" | sed 's||'$tenancyid'|g' | sed 's||'$ociregion'|g' \ | sed 's||'$authuserid'|g' | sed 's||'$myprivkey'|g' \ | sed 's||'$username'|g' | sed 's||'$fingerprint'|g' \ | sed 's||'$passphrase'|g' > $ocicfgfile # if [ "$passphrase" != "" ]; then # echo "pass_phrase=$passphrase" >> $ocicfgfile # fi chmod 600 $ocicfgfile if [ -f "$ociapitemplate" ]; then cat "$ociapitemplate" | sed 's||'$tenancyid'|g' | sed 's||'$passphrase'|g' \ | sed 's||'$ociregion'|g' | sed 's||'$fingerprint'|g' \ | sed 's||'$authuserid'|g' | sed 's||'$myprivkey'|g' \ | sed 's||'$username'|g' > $ociapicfgfile chmod 600 $ociapicfgfile if [ "$passphrase" != "" ]; then echo "$passphrase" > $ociapipwdfile chmod 600 $ociapipwdfile fi fi else # No template - create config by user interaction if [ "$OCI_CLI_CLOUD_SHELL" = "True" ]; then echo "Nothing to do in Cloud Shell." else oci setup config fi fi else errormsg 0 "OCI configuration '$ocicfgfile' already exists." fi # Check if oci-cli-rc file exists - otherwise create it if [ ! -f "$ocircfile" ]; then $oci setup oci-cli-rc --file "$ocircfile" > /dev/null 2>&1 fi } function InitRCLONETool() { local cloudtype=${1} local tenancyid=${2} local namespace=${3} local accesskeyid=${4} local secretaccesskey=${5} # echo "accesskeyid: '$accesskeyid'." # echo "secretaccesskey: '$secretaccesskey'." # Check if .rclone folder exists - otherwise create it if [ ! -d "$rclonefolder" ]; then mkdir -m 0755 -p "$rclonefolder" printf "Created folder '$rclonefolder'.\n" fi if [ -f "$rclonecfgfile" ]; then errormsg 0 "RCLONE configuration '$rclonecfgfile' already exists." fi # Create config file from template if [ "$cloudtype" = "ORACLE-OCI" ]; then if [ ! -r "$rcocitemplate" ]; then echo "No template for rclone oci '$rcocitemplate'." else ociregions=`$oci iam region-subscription list --tenancy-id "$tenancyid" --all | convert-json "regionName" --quiet --noheader --output tsv | sort` if [ "$ociregions" != "" ]; then touch $rclonecfgfile > /dev/null 2>&1 stat=$? if [ $stat -eq 0 ]; then for region in $ociregions; do cat "$rcocitemplate" | sed 's||'$region'|g' | sed 's||'$accesskeyid'|g' \ | sed 's||'$secretaccesskey'|g' | sed 's||'$namespace'|g' >> $rclonecfgfile printf "\n" >> $rclonecfgfile done fi chmod 600 $rclonecfgfile fi fi fi } function InitTerraformTool() { local tenancyname=${1} local tenancyid=${2} local username=${3} local ociregion=${4} local authuserid=${5} local fingerprint=${6} local projectname=${7} local compartmentid=${8} # Check if .terraform.d folder exists - otherwise create it if [ ! -d "$ocifolder" ]; then mkdir -m 0755 -p "$ocifolder" printf "Created folder '$ocifolder'.\n" fi # Create profile file from template if [ ! -r "$tftemplate" ]; then echo "No template for terraform '$tftemplate'." else myprivkey=`echo "$myprivkey" | sed 's|~/|'${REALHOME}'/|'` cat "$tftemplate" | sed 's||'$tenancyid'|g' | sed 's||'$ociregion'|g' \ | sed 's||'$authuserid'|g' | sed 's||'$tenancyname'|g'\ | sed 's||'$projectname'|g' | sed 's||'$compartmentid'|g' \ | sed 's||'$username'|g' | sed 's||'$fingerprint'|g' > $tfprofilefile chmod 600 $tfprofilefile fi } function InitTerraformProject() { local statewriteuri=${1} # Check if projct folder already exists if [ ! -d "$tfpjfolder" ]; then # Download terraform files git clone "https://gitlab.com/georg.voell/multitier.git" "$tfpjfolder" 2>/dev/null stat=$? if [ $stat -eq 0 ]; then # Create profile file from template if [ ! -r "$tfstatefiletemplate" ]; then echo "No template for terraform '$tfstatefiletemplate'." else cat "$tfstatefiletemplate" | sed 's||'$statewriteuri'|g' > $tfpjstatefile chmod 600 $tfpjstatefile fi echo "Please deploy your infrastructure with:" printf "\nsource %s\n" "$tcfgfile" printf "cd %s\n" "$tfpjfolder" echo "terraform init" echo "terraform apply" else echo "Unable to download multitier git repository." fi fi } function InitPSMTool() { local tenancyid=${1} local ociregion=${2} local username=${3} local stat=0 local url="" local region="" # psmfolder="${REALHOME}/.psm/conf" # psmcfgfile="${psmfolder}/setup.conf" # psmtemplate="${templatesfolder}/psm/psm.template" # printf "tenancyid: '%s'.\n" "$tenancyid" # printf "ociregion: '%s'.\n" "$ociregion" # printf "username: '%s'.\n" "$username" # Check if psm and oci can be used psm=`filecheck -x psm` oci=`filecheck -x oci` if [ "$psm" = "" -o "$oci" = "" ]; then stat=1 else # Check if psm was already configured if [ -r "$psmcfgfile" ]; then confirm "Tool 'psm' already configured. Delete old configuration?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then $psm cleanup --force true >/dev/null 2>&1 stat=$? fi fi # Check if psm is already initialized if [ ! -r "$psmcfgfile" -a "$tenancyid" != "" -a "$username" != "" -a "$ociregion" != "" ]; then # Source .admintools if it is available before first usage of oci cli if [ -r "$tcfgfile" ]; then source "$tcfgfile" fi # Get oci provider infos $oci iam identity-provider list --compartment-id $tenancyid --protocol SAML2 > $scratchfile stat=$? result=`filecheck -sl $scratchfile` if [ $stat -eq 0 -a "$result" != "" ]; then url=`browse-json --quiet --select 1 --import $scratchfile "metadataUrl"` if [ "$url" = "" ]; then url=`browse-json --quiet --select 1 --import $scratchfile "redirectUrl"` fi if [ "$url" != "" ]; then idcs=`echo "$url" | cut -d'/' -f3 | cut -d'.' -f1` fi fi # Get region from oci region region=`echo "$ociregion" | cut -d'-' -f1` case "$region" in ap) region="aucom" ;; eu | uk | il | me | af) region="emea" ;; *) region="us" esac # echo "idcs: '$idcs'." # echo "region: '$region'." # Create profile file from template if [ ! -r "$psmtemplate" ]; then echo "No template for psm '$psmtemplate'." stat=2 else if [ "$idcs" != "" -a "$region" != "" ]; then stat=1 while [ $stat -ne 0 ]; do printf "Enter password for user '$username': " read -s url printf "\n" cat "$psmtemplate" | sed 's||'$idcs'|g' | sed 's||'$region'|g' \ | sed 's||'$username'|g' | sed 's||'$url'|g' > $scratchfile $psm setup -c $scratchfile >/dev/null 2>&1 stat=$? if [ ! -r "$psmcfgfile" ]; then confirm "Tool 'psm' configuration failed (maybe wrong password). Abort?" --yes "y/[yes]" --no "n/no" stat=$? else echo "Tool 'psm' configured." fi done else stat=3 fi fi else stat=4 fi fi return $stat } function ShrinkString() { local str=${1} local slen=${2} local size=0 if [ "$str" != "" ]; then size=`printf "$str" | wc -m` if [ "$slen" = "" ]; then slen=$size fi if [ $size -gt $slen ]; then let slen-- echo "${str:0:$slen}*" else echo "$str" fi fi } # Get all compartments an write them to file function GetCompartments() { local cid=${1} # To list all compartments, add: --compartment-id-in-subtree true $oci iam compartment list --compartment-id $cid --all --compartment-id-in-subtree true > $scratchfile stat=$? result=`filecheck -sl $scratchfile` if [ $stat -eq 0 -a "$result" != "" ]; then cat $scratchfile | convert-json "lifecycleState,id,name,description" --quiet --noheader --output tsv > ${scratchfile}.temp result=`filecheck -sl ${scratchfile}.temp` if [ "$result" != "" ]; then printf "name\tdescription\tid\n" > ${scratchfile}.comp while IFS=$'\t' read -r state id name description; do if [ "$state" = "ACTIVE" -a "$name" != "ManagedCompartmentForPaaS" ]; then description=`ShrinkString "$description" 40` printf "%s\t%s\t%s\n" "$name" "$description" "$id" >> ${scratchfile}.comp fi done < ${scratchfile}.temp fi # Did we found at least one compartment? result=`filecheck -sl ${scratchfile}.comp` if [ "$result" = "" ]; then filecheck -rm ${scratchfile}.comp stat=1 fi filecheck -rm ${scratchfile}.temp fi return $stat } # Get the passphrase from ppfile function GetPassphraseFromPassphraseFile() { local username=${1} local pp="" local ppfile="${keyshome}/passphrase.txt" if [ "$username" != "" ]; then if [ -r "$ppfile" ]; then pp="`grep "^$username " "$ppfile" | cut -d$'\t' -f2`" fi fi echo "$pp" } # Return Namespace of Tenancy function GetNamespace() { # set some defaults local stat=1 local max=60 local i=0 local ns="" if [ "$oci" != "" ]; then while [ $stat -ne 0 -a $i -lt $max ]; do sleep 3 ns=`echo "n" | $oci os ns get 2>/dev/null` stat=$? if [ $stat -eq 0 -a "$ns" != "" ]; then # ns=`echo "$ns" | browse-json data --select 1 --quiet` ns=`echo "$ns" | norm-json --select 1 --quiet` stat=$? if [ $stat -eq 0 -a "$ns" != "" ]; then echo "$ns" fi fi let "i++" done fi return $stat } # Access to Object Storage (needed by rclone) function CreateSecretKey() { # set some defaults local stat=1 local max=30 local i=0 local result="" if [ "$oci" != "" ]; then while [ $stat -ne 0 -a $i -lt $max ]; do sleep 3 $oci iam customer-secret-key create --display-name "S3 Access" --user-id "$authuserid" > $scratchfile 2>/dev/null stat=$? result=`filecheck -s "$scratchfile"` if [ $stat -eq 0 -a "$result" != "" ]; then accesskeyid=`cat $scratchfile | browse-json id --select 1 --quiet` s3id="$accesskeyid" secretaccesskey=`cat $scratchfile | browse-json key --select 1 --quiet` else stat=1 fi let "i++" done fi return $stat } function CreateSSHKey() { local userstr=${1} local inp1="" local inp2="" local pp="" local stat=1 if [ "$userstr" != "" ]; then while [ $stat -ne 0 ]; do printf "\nEnter new private key passphrase for key '$userstr': " read -s inp1 printf "\n" if [ "$inp1" = "" ]; then confirm "Leaving passphrase empty is insecure. Do you want to continue without it?" --yes "y/yes" --no "n/[no]" stat=$? else inp2=`printf "${#inp1}"` if [ $inp2 -lt 5 ]; then printf "Passphrase has to have at least 5 chars.\n" stat=1 else printf "Repeat the passphrase: " read -s inp2 printf "\n" if [ "$inp1" = "$inp2" ]; then stat=0 else printf "Passphrase not equal.\n" stat=1 fi if [ $stat -eq 0 ]; then pp="$inp1" if [ "$userstr" = "$tenancyname" ]; then tenantpassphrase="$pp" else passphrase="$pp" fi fi fi fi if [ $stat -eq 0 ]; then if [ "$pp" = "" ]; then key-management create --username "$userstr" stat=$? else key-management create --username "$userstr" --passphrase "$pp" stat=$? fi fi done fi # Reset terminal tset return $stat } function ImportPrivateKey() { local userstr=${1} local keyfile=${2} local stat=1 if [ "$userstr" != "" -a "$keyfile" != "" ]; then if [ -r "$keyfile" ]; then confirm "\nPrivate Key found at '$keyfile'. Import it?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then # Existing key found - try to import key-management import "$keyfile" --username "$userstr" stat=$? if [ $stat -gt 0 ]; then errormsg 0 "Creating new key intead of using '$keyfile'." else if [ "$userstr" = "$tenancyname" ]; then tenantpassphrase=`GetPassphraseFromPassphraseFile "$userstr"` else passphrase=`GetPassphraseFromPassphraseFile "$userstr"` fi fi fi fi fi return $stat } # Check if oci cli works with defined API key function CheckOCIConfig() { local userstr=${1} local fp=${2} local configfile=${3} local stat=0 local result="" if [ ! -r "$configfile" -o "$userstr" = "" -o "$fp" = "" ]; then stat=1 else result=`grep "^\[$userstr\]" "$configfile"` if [ "$result" = "" ]; then # User is not defined in config file stat=2 else result=`grep "^fingerprint=$fp" "$configfile"` if [ "$result" = "" ]; then # Fingerprint is not defined in config file stat=3 else export OCI_CLI_AUTH="api_key" export OCI_CLI_CONFIG_FILE="$configfile" export OCI_CLI_PROFILE="$userstr" # Check if configuration works result=`GetNamespace` stat=$? if [ $stat -gt 0 -o "$result" = "" ]; then stat=4 fi fi fi fi return $stat } function InitTools() { # set some defaults stat=0 apicap="" secretcap="" # Look for oci cli tool oci=`filecheck -x oci` # Check if json config exists - the get all infos from there if [ -r "$ocijson" ]; then ReadOCIJson stat=$? if [ ! -f "$ocicfgfile" ]; then # Get passphrase if possible # passphrase=`GetPassphraseFromPassphraseFile "$username"` # Init OCI InitOCITool "$tenancyid" "$homeregion" "$username" "$authuserid" "$apikey" "$fingerprint" "$passphrase" CheckOCIConfig "$username" "$fingerprint" "$ocicfgfile" stat=$? if [ $stat -gt 0 ]; then # OCI not configured printf "\n" exitcode=5 errormsg $exitcode "Tool 'oci' not configured correctly." "Code: $stat" # API Key does not work: Unexpected Error Cleanup exit $exitcode else printf "\nTool 'oci' configured.\n" fi else printf "\nTool 'oci' already configured.\n" # Source .admintools to set needed environment variables if [ -r "$tcfgfile" ]; then source "$tcfgfile" fi fi else if [ "$oci" != "" ]; then # Check if CloudShell is active if [ "$OCI_CLI_CLOUD_SHELL" = "True" ]; then printf "\nCollecting needed infos from cloud.\n" # Source .admintools to set needed environment variables if [ -r "$tcfgfile" ]; then source "$tcfgfile" fi # Check if we can use oci namespace=`GetNamespace` stat=$? # Namespace is set if oci ist installed and configured if [ $stat -eq 0 -a "$namespace" != "" ]; then if [ "$OCI_TENANCY" != "" ]; then tenancyid="$OCI_TENANCY" stat=0 else tenancyid=`$oci iam compartment list --all | browse-json compartmentId --select 1 --quiet` stat=$? fi if [ $stat -eq 0 -a "$tenancyid" != "" ]; then $oci iam tenancy get --tenancy-id $tenancyid > $scratchfile 2>&1 stat=$? if [ $stat -eq 0 ]; then tenancyname=`browse-json name --import $scratchfile --select 1 --quiet` hrkey=`browse-json homeRegionKey --import $scratchfile --select 1 --quiet` if [ "$tenancyname" != "" -a "$hrkey" != "" ]; then ### homeregion=`$oci iam region-subscription list | convert-json --quiet --noheader --output tsv | grep "Yes" | cut -d$'\t' -f3` homeregion=`$oci iam region list --all | convert-json --quiet --output tsv | grep "^$hrkey " | cut -d$'\t' -f2` fi else # Unfortunately we don't have rights to get tenancy details homeregion="$OCI_REGION" $oci iam compartment get --compartment-id $tenancyid > $scratchfile 2>&1 stat=$? if [ $stat -eq 0 ]; then # Name of the root compartment tenancyname=`cat $scratchfile | browse-json name --select 1 --quiet` else tenancyname="UNKNOWN" fi fi else exitcode=5 errormsg $exitcode "Unexpected error. Unable to detect tenancyid." Cleanup exit $exitcode fi # Userinfo csuser="" if [ -r "$ociapicfgfile" ]; then csuser=`grep "^export API_USER_ID=" "$ociapicfgfile" | head -n 1 | cut -d'"' -f2` elif [ -r "$ocicfgfile" ]; then csuser=`grep "^user=" "$ocicfgfile" | head -n 1 | cut -d'=' -f2` else if [ "$OCI_CS_USER_OCID" != "" ]; then csuser=`echo $OCI_CS_USER_OCID | cut -d'/' -f2` fi fi if [ "$csuser" = "" ]; then csuser=`echo $REALUSER | tr '_' '.'` fi printf "\nWe need a user where we can attach the API key (needed for OCI CLI and terraform).\n" printf "Normally this is your account but also a technical user account can be useed here.\n" # Get a list for all users $oci iam user list --all > $scratchfile stat=$? result=`filecheck -s $scratchfile` if [ $stat -eq 0 -a "$result" != "" ]; then cat $scratchfile | convert-json "name,id" --quiet --output tsv > ${scratchfile}.user result=`filecheck -s ${scratchfile}.user` if [ "$result" != "" ]; then stat=1 while [ $stat -ne 0 ]; do if [ "$csuser" != "" ]; then user=`grep "$csuser" ${scratchfile}.user` else user="" fi if [ "$user" = "" ]; then printf "\nPlease choose your account from list (by number):\n" select-table ${scratchfile}.user $scratchfile stat=$? if [ $stat -eq 0 ]; then user=`cat $scratchfile` csuser="`echo "$user" | head -n 1 | cut -d$'\t' -f1`" else csuser="$oldcsuser" if [ "$csuser" != "" ]; then user=`grep "$csuser" ${scratchfile}.user` else user="" fi fi fi username="`echo "$user" | head -n 1 | cut -d$'\t' -f1`" authuserid="`echo "$user" | head -n 1 | cut -d$'\t' -f2`" confirm "\nIs this your account name: '$username'?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then # Get all infos about user $oci iam user get --user-id $authuserid > $scratchfile result=`filecheck -s $scratchfile` if [ "$result" != "" ]; then apicap=`cat "$scratchfile" | browse-json capabilities/canUseApiKeys --select 1 --quiet` secretcap=`cat "$scratchfile" | browse-json capabilities/canUseCustomerSecretKeys --select 1 --quiet` if [ "$apicap" != "true" -o "$secretcap" != "true" ]; then echo "User cannot attach API keys or create User Secret Keys - Please choose another user." csuser="" stat=1 fi else echo "Could not locate user - Please choose another user." csuser="" stat=1 fi else oldcsuser="$csuser" csuser="" fi done # printf "\n" if [ "$username" != "" ]; then username="`basename $username`" fi fi fi else printf "\n" exitcode=5 errormsg $exitcode "Unexpected error. Please exit CloudShell and reconnect again." Cleanup exit $exitcode fi else printf "\nNo Cloud Shell and no JSON info files. Exiting.\n" Cleanup exit 5 fi fi fi # We only create the keys if they do not already exist if [ ! -r "$ocijson" ]; then passphrase="" keys=`key-management list | grep "/${username}/"` if [ "$keys" = "" ]; then # We don't have api keys created yet printf "\nCreating ssh keys for User.\n" ImportPrivateKey "$username" "${REALHOME}/.oci/oci_api_key.pem" stat=$? if [ $stat -gt 0 ]; then # Import of existing key failed or key does not exists yet CreateSSHKey "$username" fi # Get key infos keys=`key-management list | grep "/${username}/"` else # Get passphrase if possible passphrase=`GetPassphraseFromPassphraseFile "$username"` fi # Get api Key and Fingerprint fingerprint=`echo "$keys" | head -n 1 | sed 's|^'$username'||' | tr -s ' ' | cut -d' ' -f3` apikey=`echo "$keys" | head -n 1 | sed 's|^'$username'||' | tr -s ' ' | cut -d' ' -f4` # if [ -r "${apikey}.pk8" ]; then # # Prefering this key # apikey=`echo "${apikey}.pk8" | sed 's|^'${REALHOME}'|~|'` # else apikey=`echo "$apikey" | sed 's|^'${REALHOME}'|~|'` # fi # Check ssh key for tenancy already exists keys=`key-management list | grep "/${tenancyname}/"` if [ "$keys" = "" ]; then # We don't have ssh keys created yet printf "\nCreating ssh keys for Tenancy.\n" ImportPrivateKey "$tenancyname" "${REALHOME}/.ssh/id_rsa" stat=$? if [ $stat -gt 0 ]; then # Import of existing key failed or key does not exists yet CreateSSHKey "$tenancyname" fi # Get key infos keys=`key-management list | grep "/${tenancyname}/"` fi # Get priv Key privkey=`echo "$keys" | head -n 1 | sed 's|^'$tenancyname'||' | tr -s ' ' | cut -d' ' -f4` # Try to find pubkey if [ -r "${privkey}.pub" ]; then pubkey=`echo "${privkey}.pub" | sed 's|^'${REALHOME}'|~|'` else pubkey="" fi # if [ -r "${privkey}.pk8" ]; then # # Prefering this key # privkey=`echo "${privkey}.pk8" | sed 's|^'${REALHOME}'|~|'` # else privkey=`echo "$privkey" | sed 's|^'${REALHOME}'|~|'` # fi fi # We need oci for this if [ "$oci" != "" -a ! -r "$ocijson" ]; then stat=0 # If user has api key capability - show existing keys and upload api key to user if [ "$apicap" = "true" ]; then # Check if our api key is already uploaded $oci iam user api-key list --user-id $authuserid > $scratchfile result=`filecheck -s $scratchfile` if [ "$result" != "" ]; then # User has api keys - grep the fingerprints fpfound=`cat $scratchfile | convert-json "fingerprint" --quiet --noheader --output tsv | grep "$fingerprint"` else fpfound="" fi if [ "$fpfound" = "" ]; then # we don't have uploaded the api key yet # We can add max 3 api keys - so check if we can upload one if [ "$result" != "" ]; then result=`cat $scratchfile | convert-json "fingerprint" --quiet --noheader --output tsv | wc -l` else result=0 fi if [ $result -gt 2 ]; then printf "\n" exitcode=5 errormsg $exitcode "Maximum number of 'API Keys' reached for user '$username' - please delete one first." Cleanup exit $exitcode else stat=1 while [ $stat -ne 0 ]; do # Auto upload file key-management show api --username "$username" | grep -v '^$' > $scratchfile $oci iam user api-key upload --user-id $authuserid --key-file $scratchfile > /dev/null 2>&1 stat=$? if [ $stat -ne 0 ]; then # Unable to auto aupload - load the key manually via GUI printf "\nPlease copy this API key to your account in Web-GUI:\n\n" cat $scratchfile confirm "\nDid you attach the above public key to your user account?" --yes "y/[yes]" --no "n/no" stat=$? else fpid="$fingerprint" fi if [ $stat -eq 0 ]; then $oci iam user api-key list --user-id $authuserid > $scratchfile result=`filecheck -s $scratchfile` if [ "$result" != "" ]; then # User has api keys - grep the fingerprints result=`cat $scratchfile | convert-json "fingerprint" --quiet --noheader --output tsv | grep "$fingerprint"` fi if [ "$result" = "" ]; then confirm "API key could not be found. Try again?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -gt 0 ]; then # User wants to exit here stat=0 fi else # fpid=`key-management show fp --username "$username"` fpid="$fingerprint" fi fi done fi fi # Check if oci config exists - otherwise create it by configuring oci tool if [ "$result" != "" -a ! -r "$ocicfgfile" ]; then # Init OCI tool printf "\n" InitOCITool "$tenancyid" "$homeregion" "$username" "$authuserid" "$apikey" "$fingerprint" "$passphrase" # Using new api key CheckOCIConfig "$username" "$fingerprint" "$ocicfgfile" stat=$? if [ $stat -gt 0 ]; then # OCI not configured exitcode=5 errormsg $exitcode "Tool 'oci' not configured correctly." "Code: $stat" # API Key does not work: Unexpected Error Cleanup exit $exitcode else echo "Tool 'oci' configured." # Append new config to .bashrc ### printf 'source %s\n' "$tcfgfile" >> $brcfile fi fi fi # If user has secret key capability - show existing secrets and create a new one if no secret exists if [ $stat -eq 0 -a "$secretcap" = "true" ]; then $oci iam customer-secret-key list --user-id $authuserid > $scratchfile 2>&1 result=`filecheck -s $scratchfile` if [ "$result" != "" ]; then # User has secret keys - check it is less than 2 result=`cat $scratchfile | convert-json "id" --quiet --noheader --output tsv | wc -l` if [ $result -gt 1 ]; then printf "\n" exitcode=5 errormsg $exitcode "Maximum number of 'Customer Secret Keys' reached for user '$username' - please delete one first." Cleanup exit $exitcode fi fi if [ $stat -eq 0 -a -r "$ocicfgfile" ]; then # Using new api key CheckOCIConfig "$username" "$fingerprint" "$ocicfgfile" stat=$? if [ $stat -gt 0 ]; then exitcode=5 errormsg $exitcode "Unable to use oci cli. Please try '$progstr config' again." "Code: $stat" Cleanup exit $exitcode else CreateSecretKey stat=$? printf "\n" if [ $stat -eq 0 ]; then echo "Secret-key created." else exitcode=5 errormsg $exitcode "Unable to create secret-key. Please try '$progstr config' again." "Code: $stat" Cleanup exit $exitcode fi fi fi fi fi # We should have all infos now - so write them to oci json config if [ -d "$ocifolder" ]; then if [ ! -r "$ocijson" -a "$accesskeyid" != "" ]; then WriteOCIJson stat=$? if [ $stat -eq 0 ]; then fpid="" s3id="" fi fi fi # Init rclone tool=`filecheck -x rclone` if [ "$tool" != "" -a "$accesskeyid" != "" -a ! -f "$rclonecfgfile" ]; then # Check if already defined namespace if [ "$namespace" = "" ]; then namespace=`GetNamespace` fi if [ "$namespace" != "" ]; then InitRCLONETool "ORACLE-OCI" "$tenancyid" "$namespace" "$accesskeyid" "$secretaccesskey" echo "Tool 'rclone' configured." else echo "Tool 'rclone' not configured." fi # # Check if configuration works # result=`rclone lsd "${homeregion}:" 2>/dev/null` # if [ "$result" = "" ]; then # # rclone not configured # echo "Tool 'rclone' not configured correctly." # else # echo "Tool 'rclone' configured." # fi fi # Check if project config exists - then get all infos from there if [ -r "$projectjson" ]; then ReadProjectJson stat=$? else # Get Projectname and compartment ocid if [ "$tenancyid" != "" ]; then printf "\nFor a terraform project, we need to define a compartment. If you don't want to\n" printf "use an existing compartment (preferred), stop here and create your compartment -\n" printf "or create a new one with this tool in the root compartment.\n" stat=1 while [ $stat -gt 0 ]; do confirm "\nDoes the compartment exists for your project?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then if [ ! -f "${scratchfile}.comp" ]; then GetCompartments "$tenancyid" stat=$? fi if [ $stat -eq 0 ]; then printf "\nPlaease select a compartment (by number):\n" select-table ${scratchfile}.comp $scratchfile stat=$? if [ $stat -eq 0 ]; then line=`cat $scratchfile` if [ "$line" != "" ]; then projectname=`echo "$line" | cut -d' ' -f1` compartmentid=`echo "$line" | cut -d' ' -f3` printf "\nChoosen compartment: '%s' - id: '%s'.\n" "$projectname" "$compartmentid" confirm "ok?" --yes "y/[yes]" --no "n/no" stat=$? else stat=1 fi fi else printf "\nNo compartment found - please create one.\n" fi else # stat=3 projectname="" compartmentid="" printf "\nPlease enter name and description for new compartment.\n" printf "Name: " read inp if [ "$inp" != "" ]; then projectname="$inp" printf "Description: " read inp printf "\n" if [ "$inp" != "" ]; then confirm "Name: '$projectname' - Description: '$inp' - ok?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then $oci iam compartment create --name "$projectname" --description "$inp" --compartment-id "$tenancyid" > $scratchfile stat=$? if [ $stat -eq 0 ]; then compartmentid=`grep '"id": "' $scratchfile | cut -d'"' -f 4` fi fi fi fi if [ "$projectname" != "" -a "" != "$compartmentid" ]; then printf "\nChoosen compartment: '%s' - id: '%s'.\n" "$projectname" "$compartmentid" stat=0 else stat=1 fi fi done printf "\n" fi fi # Create Project Bucket with pre-auth if [ "$oci" != "" ]; then CheckOCIConfig "$username" "$fingerprint" "$ocicfgfile" stat=$? if [ $stat -gt 0 ]; then exitcode=5 errormsg $exitcode "Unable to use oci cli. Please try '$progstr config' again." "Code: $stat" Cleanup exit $exitcode else # Check if we already defined namespace if [ "$namespace" = "" ]; then namespace=`GetNamespace` fi # Get list of buckts bucketlist=`$oci os bucket list --compartment-id "$compartmentid" --namespace "$namespace" | norm-json --quiet --raw | grep '"name":' | cut -d'"' -f4` if [ "$bucketlist" != "" ]; then bucket=`echo "$bucketlist" | grep '^'${projectname}'$'` else bucket="" fi if [ "$bucket" = "" ]; then # Bucket does not exists yet - create it $oci os bucket create --compartment-id "$compartmentid" --namespace "$namespace" --name "$projectname" >/dev/null 2>&1 stat=$? if [ $stat -eq 0 ]; then printf "Bucket '%s' created.\n" "$projectname" else printf "Bucket '%s' creation failed.\n" "$projectname" fi fi if [ ! -r "$projectjson" -a "$projectname" != "" ]; then case "$OS" in Darwin) expires1day=`date -v+1d +'%Y-%m-%d %H:%M' 2>/dev/null` expires10years=`date -v+10y +'%Y-%m-%d %H:%M' 2>/dev/null` ;; *) expires1day=$(date -d "today + 1 days" +'%Y-%m-%d %H:%M' 2>/dev/null) expires10years=$(date -d "today + 10 years" +'%Y-%m-%d %H:%M' 2>/dev/null) ;; esac $oci os preauth-request create --bucket-name "$projectname" --name "BucketWriteAccess" --time-expires "$expires10years" \ --access-type "AnyObjectReadWrite" >$scratchfile 2>&1 stat=$? if [ $stat -eq 0 ]; then writeuri=`browse-json accessUri --import $scratchfile --select 1 --quiet` if [ "$writeuri" != "" ]; then writeuri="https://objectstorage.${homeregion}.oraclecloud.com${writeuri}" printf "Write PreAuth for bucket '%s' created.\n" "$projectname" preauthwid=`browse-json id --import $scratchfile --select 1 --quiet` fi fi $oci os preauth-request create --bucket-name "$projectname" --name "BucketReadAccess" --time-expires "$expires10years" \ --access-type "AnyObjectRead" >$scratchfile 2>&1 stat=$? if [ $stat -eq 0 ]; then readuri=`browse-json accessUri --import $scratchfile --select 1 --quiet` if [ "$readuri" != "" ]; then readuri="https://objectstorage.${homeregion}.oraclecloud.com${readuri}" printf "Read PreAuth for bucket '%s' created.\n\n" "$projectname" preauthrid=`browse-json id --import $scratchfile --select 1 --quiet` fi fi fi fi fi # We should have all infos now - so write them to project json config if [ -d "$ocifolder" ]; then if [ ! -r "$projectjson" -a "$projectname" != "" ]; then WriteProjectJson stat=$? if [ $stat -eq 0 ]; then preauthwid="" preauthrid="" fi fi fi # Init terraform tool=`filecheck -x terraform` if [ "$tool" != "" -a "$projectname" != "" -a ! -f "$tfprofilefile" ]; then InitTerraformTool "$tenancyname" "$tenancyid" "$username" "$homeregion" "$authuserid" "$fingerprint" "$projectname" "$compartmentid" echo "Tool 'terraform' configured." fi # Create Tools config file # if [ ! -f "$tcfgfile" -a "$username" != "" ]; then if [ "$username" != "" ]; then if [ ! -f "$tcfgfile" ]; then # Show usage message only the first time printf "\nBefore using cloud tools, call 'source $tcfgfile'.\n" fi printf '# Source this file\n\n' > $tcfgfile printf '# Needed by oci api\n' >> $tcfgfile printf 'if [ -r "%s" ]; then\n' $ociapicfgfile >> $tcfgfile printf ' source %s\n' "$ociapicfgfile" >> $tcfgfile printf 'fi\n\n' >> $tcfgfile printf '# Needed by terraform\n' >> $tcfgfile printf 'if [ -r "%s" ]; then\n' $tfprofilefile >> $tcfgfile printf ' source %s\n' "$tfprofilefile" >> $tcfgfile printf 'fi\n\n' >> $tcfgfile printf '# Needed by oci cli\n' >> $tcfgfile printf 'if [ -r "%s" ]; then\n' $ocicfgfile >> $tcfgfile printf ' export OCI_CLI_AUTH="api_key"\n' >> $tcfgfile printf ' export OCI_CLI_CONFIG_FILE="%s"\n' "$ocicfgfile" >> $tcfgfile printf ' export OCI_CLI_PROFILE="%s"\n' "$username" >> $tcfgfile printf 'else\n' >> $tcfgfile printf ' if [ -r "/etc/oci/config" -a "$OCI_REGION" != "" ]; then\n' >> $tcfgfile printf ' export OCI_CLI_AUTH="instance_obo_user"\n' >> $tcfgfile printf ' export OCI_CLI_CONFIG_FILE="/etc/oci/config"\n' >> $tcfgfile printf ' export OCI_CLI_PROFILE="$OCI_REGION"\n' >> $tcfgfile printf ' else\n' >> $tcfgfile printf ' export OCI_CLI_AUTH="instance_principal"\n' >> $tcfgfile printf ' unset OCI_CLI_CONFIG_FILE\n' >> $tcfgfile printf ' unset OCI_CLI_PROFILE\n' >> $tcfgfile printf ' fi\n' >> $tcfgfile printf 'fi\n\n' >> $tcfgfile # Create Link if [ ! -f "${infofolder}/.admintools" ]; then if [ "$USER" != "root" ]; then check-sudo stat=$? if [ $stat -eq 0 ]; then sudo ln -s $tcfgfile "${infofolder}/.admintools" fi else ln -s $tcfgfile "${infofolder}/.admintools" fi fi fi return $stat } # Update mandb with new manuals function UpdateWhatis() { # Create mandb case "$OS" in Darwin) makewhatis=`filecheck -x "/usr/libexec/makewhatis"` if [ "$makewhatis" != "" ]; then filecheck -rm "${manfolder}/whatis" $makewhatis "${manfolder}" > /dev/null 2>&1 fi ;; Linux) mandb=`filecheck -x mandb` if [ "$mandb" != "" ]; then $mandb "${manfolder}" > /dev/null 2>&1 fi ;; SunOS) catman=`filecheck -x catman` if [ "$catman" != "" ]; then $catman -M "${manfolder}" > /dev/null 2>&1 fi ;; esac if [ "$needchown" = true ]; then chown -fR ${REALUSER}:$REALGROUP $manfolder fi } function UpdateOS() { # Update the whole OS printf "\n" echo "Will update the OS now. This may takes a couple of minutes." echo "Please do not stop the script while updating." case "$id_like" in fedora) yum=`filecheck -x yum` if [ "$yum" != "" ]; then sudo $yum -y upgrade | tee --append $logfile # Move new repo files repodir="/etc/yum.repos.d" repofiles=`ls ${repodir}/*.repo 2>/dev/null` rpmnewfiles=`ls ${repodir}/*.rpmnew 2>/dev/null` if [ "$rpmnewfiles" != "" ]; then if [ ! -d ${repodir}/old ]; then sudo mkdir ${repodir}/old fi fi for rfile in $repofiles; do if [ -f ${rfile}.rpmnew ]; then sudo mv -f $rfile ${repodir}/old sudo mv -f ${rfile}.rpmnew $rfile echo "Old repo file '$rfile' moved to '${repodir}/old'." fi done fi ;; debian) aptget=`filecheck -x apt-get` if [ "$aptget" != "" ]; then sudo $aptget -y update | tee --append $logfile sudo $aptget -y upgrade | tee --append $logfile fi ;; suse) zypper=`filecheck -x zypper` if [ "$zypper" != "" ]; then sudo $zypper up | tee --append $logfile fi ;; alpine) apk=`filecheck -x apk` if [ "$apk" != "" ]; then sudo $apk update | tee --append $logfile sudo $apk upgrade | tee --append $logfile fi ;; *) echo "Can't update OS for Linux Type '$id_like'." esac echo "OS update completed." } function CallTerraform() { local cmd=${1} local currdir=`pwd` local firstarg="" local moreargs="" local stat=0 if [ "$cmd" != "" ]; then if [ ! -d "$tfpjfolder" ]; then printf "\nFolder '%s' does not exists. Please create it first with '$progstr setup'.\n" "$tfpjfolder" else if [ -r "$tcfgfile" ]; then source "$tcfgfile" # Source .admintools to set needed environment variables cd "${tfpjfolder}" firstarg=`echo "$cmd" | cut -d' ' -f1` moreargs=`echo "$cmd" | cut -d' ' -f2-` if [ "$moreargs" = "$firstarg" ]; then moreargs="" fi if [ "$OCI_CLI_CLOUD_SHELL" != "True" ]; then if [ "$firstarg" = "destroy" -o "$firstarg" = "apply" -a "$moreargs" = "-destroy" ]; then printf "\nNot recommended to destroy all resources outside Cloud Shell.\n" confirm "Do you want to continue and destroy all resources?" --yes "y/yes" --no "n/[no]" stat=$? if [ $stat -gt 0 ]; then return 1 fi fi fi if [ "$firstarg" != "init" ]; then printf "\n" fi if [ "$firstarg" = "plan" -o "$firstarg" = "apply" -o "$firstarg" = "destroy" ]; then terraform init >/dev/null 2>&1 stat=$? if [ $stat -gt 0 ]; then # May need newer version if [ -f ".terraform.lock.hcl" ]; then rm -f ".terraform.lock.hcl" terraform init >/dev/null 2>&1 stat=$? fi fi if [ $stat -gt 0 ]; then printf "Unable to initialize terraform. Stopping here.\n" else # Validate terraform code terraform validate stat=$? fi fi # Call terraform with parameter if [ $stat -eq 0 ]; then terraform $cmd # 2>&1 | grep -v "\[DEBUG\] GET https://objectstorage.eu-frankfurt-1.oraclecloud.com/" stat=$? fi cd "$currdir" else printf "\nFile '%s' does not exists. Please create it first with '%s config'.\n" "$tcfgfile" "$progstr" fi fi else printf "\nNo options specified. Usage e.g.: '$progstr terraform \"apply -auto-approve\"'.\n" fi return $stat } function CallTerraformOutput() { local cmd=${1} local jq=`filecheck -x jq` local python=`filecheck -x python` local stat=0 terraform -chdir="${tfpjfolder}" $cmd -json 2>/dev/null >${scratchfile}.out stat=$? if [ "$jq" != "" ]; then terraform -chdir="${tfpjfolder}" $cmd -json 2>/dev/null | $jq -M . >${scratchfile}.out stat=$? else terraform -chdir="${tfpjfolder}" $cmd -json 2>/dev/null | python -m json.tool >${scratchfile}.out stat=$? fi if [ $stat -eq 0 ]; then if [ "$jq" != "" ]; then cat ${scratchfile}.out | $jq -M . else if [ "$python" != "" ]; then cat ${scratchfile}.out | $python -m json.tool else cat ${scratchfile}.out fi fi fi # Cleanup and exit filecheck -rm ${scratchfile}.out return $stat } # Preset param1="" param2="" # 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 '^-'` # Types don't begin with '-' if [ "$paramck" != "" ]; then errstr="Unknown option '$pname'." else if [ "$param1" = "" ]; then param1=`echo "$pname" | tolower` else if [ "$param2" = "" ]; then param2="$pname" else errstr="Unknown additional parameter: '$pname'." fi fi fi esac done # Plausibility check if [ "$param1" != "" ]; then if [ "$param1" != "update" -a "$param1" != "remove" -a "$param1" != "config" -a "$param1" != "setup" -a "$param1" != "classic" -a "$param1" != "terraform" -a "$param1" != "push" ]; then errstr="Unknown action '$param1'." fi fi # Check if setup-tools is alrady running result=`ps -ef | grep "${progstr}$" | grep -v "grep" | tr -s ' ' | wc -l` if [ $result -gt 2 -a "$IGNORERUNNING" = "" ]; then errstr="Tool '$progstr' already running. Please wait until this has finished." fi # Display help or error message DisplayHelp # Main export LOGFILE=$logfile # Define default variables firsttime=false # If script is called the first time, set this to true needsudo=false # We could install all scripts with user rights needchown=false # Need to change filerights toolsname="tools" scriptsname="scripts" templatesname="templates" # Check if we laready installed the scripts result=`filecheck -x /usr/local/bin/$progstr` if [ "$result" != "" ]; then userhome="/usr/local" if [ "$USER" != "root" ]; then needsudo=true fi else result=`filecheck -x ${REALHOME}/.local/bin/$progstr` if [ "$result" != "" ]; then userhome="${REALHOME}/.local" if [ "$USER" = "root" ]; then needchown=true fi else # We install the first time firsttime=true if [ "$USER" = "root" ]; then userhome="/usr/local" else userhome="${REALHOME}/.local" fi fi fi binfolder="${userhome}/bin" libfolder="${userhome}/lib" # lib64 manfolder="${userhome}/share/man" infofolder="${userhome}/share/info" appfolder="${userhome}/share/applications" templatesfolder="${userhome}/share/$templatesname" toolsfile="${infofolder}/installed-${toolsname}.txt" scriptsfile="${infofolder}/installed-${scriptsname}.txt" manfile="${infofolder}/installed-manuals.txt" manfile2="${infofolder}/installed-cmd-manuals.txt" templatesfile="${infofolder}/installed-${templatesname}.txt" zipsfile="${infofolder}/installed-zips.txt" libsfile="${infofolder}/installed-libs.txt" sshconfig="${REALHOME}/.ssh/config" keyshome="${REALHOME}/.ssh/keys" brcfile="${REALHOME}/.bashrc" tcfgfile="${REALHOME}/.admintools" ocifolder="${REALHOME}/.oci" ocicfgfile="${ocifolder}/config" ociapicfgfile="${ocifolder}/api-config" ociapipwdfile="${ocifolder}/api-passwd" ocircfile="${ocifolder}/oci_cli_rc" ocijson="${ocifolder}/config.json" projectjson="${ocifolder}/project.json" ocitemplate="${templatesfolder}/oci/oci.template" ociapitemplate="${templatesfolder}/oci/api.template" psmfolder="${REALHOME}/.psm/conf" psmcfgfile="${psmfolder}/setup.conf" psmtemplate="${templatesfolder}/psm/psm.template" rclonefolder="${REALHOME}/.config/rclone" rclonecfgfile="${rclonefolder}/rclone.conf" rcocitemplate="${templatesfolder}/rclone/oci.template" rcopctemplate="${templatesfolder}/rclone/opc.template" tfprofilefile="${ocifolder}/tf-config" tftemplate="${templatesfolder}/terraform/profile.template" tfpjfolder="${REALHOME}/multitier" tfpjstatefile="${tfpjfolder}/statefile.tf" tfstatefiletemplate="${templatesfolder}/terraform/statefile.template" cloudfile="${infofolder}/cloud.json" platformfile="${infofolder}/platform.json" # Set some more defaults stat=0 username="" passphrase="" namespace="" homeregion="" tenancyid="" tenancyname="" authuserid="" fingerprint="" privkey="" apikey="" pubkey="" projectname="" writeuri="" readuri="" compartmentid="" s3id="" fpid="" preauthwid="" preauthrid="" # Reset the terminal #if [ "$IGNORERUNNING" = "" ]; then # reset #fi if [ "$param1" = "remove" ]; then if [ "$needsudo" = true ]; then if [ "$USER" != "root" ]; then check-sudo stat=$? if [ $stat -eq 0 ]; then export IGNORERUNNING="true" # sudo --preserve-env "$0" remove sudo --preserve-env=PATH "$0" remove stat=$? exit $stat else errormsg 3 "Root privileges needed to delete scripts." fi fi fi echo "$progstr $param1" | toupper > $scratchfile printf "\n" print-header --import $scratchfile printf "\n" # Check if CloudShell is active if [ "$OCI_CLI_CLOUD_SHELL" = "True" ]; then # Try to remove terraform folder if state is empty if [ -d "$tfpjfolder" ]; then result=`CallTerraformOutput show | wc -l` if [ $result -gt 3 ]; then errormsg 5 "Folder '$tfpjfolder' exists and statefile not empty. Please delete resources first with '$progstr terraform destroy'." rm -f $scratchfile exit 5 else # Ask for remove terraform project confirm "Do you want to remove folder '$tfpjfolder' (terraform project)?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then rm -fR "$tfpjfolder" stat=$stat if [ $stat -eq 0 ]; then printf "Folder '$tfpjfolder' deleted.\n\n" fi else printf "Skipped.\n\n" fi fi fi # Look for oci cli tool and check if we can use it stat=1 oci=`filecheck -x oci` if [ "$oci" != "" ]; then if [ -r "$tcfgfile" ]; then source "$tcfgfile" # Source .admintools to set needed environment variables fi namespace=`GetNamespace` stat=$? if [ $stat -gt 0 ]; then printf "Unexpected error: Unable to use 'oci'.\n\n" fi fi if [ ! -d "$tfpjfolder" -a $stat -eq 0 ]; then # Read json config file ReadProjectJson stat=$? if [ $stat -eq 0 ]; then confirm "Do you want to delete bucket '$projectname' (terraform project)?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then # Remove bucket $oci os bucket delete --name "$projectname" --namespace "$namespace" --empty --force >/dev/null 2>&1 stat=$? if [ $stat -eq 0 ]; then printf "Bucket '$projectname' deleted.\n\n" # Delete config files filecheck -rm "$projectjson" filecheck -rm "$tfprofilefile" fi else printf "Skipped.\n\n" stat=0 fi fi fi if [ $stat -eq 0 ]; then # Read json config file ReadOCIJson stat=$? if [ $stat -eq 0 ]; then confirm "Do you want to detach keys from user and delete oci configuration files?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then $oci iam customer-secret-key delete --user-id "$authuserid" --customer-secret-key-id "$accesskeyid" --force stat=$? if [ $stat -eq 0 ]; then $oci iam user api-key delete --user-id "$authuserid" --fingerprint "$fingerprint" --force stat=$? if [ $stat -eq 0 ]; then printf "Keys (api-key and secret-key) detached from user and oci configuration deleted.\n\n" # Delete config files filecheck -rm "$rclonecfgfile" filecheck -rm "$ociapicfgfile" filecheck -rm "$ociapipwdfile" filecheck -rm "$ocircfile" filecheck -rm "$ocicfgfile" filecheck -rm "$ocijson" # filecheck -rm "$tcfgfile" # .admintools rmdir "$ocifolder" 2>/dev/null rmdir "$rclonefolder" 2>/dev/null else printf "Unable to detach api-key '$fingerprint'.\n\n" fi else printf "Unable to detach secret-key '$accesskeyid'.\n\n" fi else printf "Skipped.\n\n" fi fi fi else if [ -f "$projectjson" -o -f "$ocijson" ]; then confirm "Do you want to delete oci configuration files?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then # Not in Cloud Shell - delete config files filecheck -rm "$projectjson" filecheck -rm "$tfprofilefile" filecheck -rm "$rclonecfgfile" filecheck -rm "$ociapicfgfile" filecheck -rm "$ociapipwdfile" filecheck -rm "$ocircfile" filecheck -rm "$ocicfgfile" filecheck -rm "$ocijson" # filecheck -rm "$tcfgfile" # .admintools rmdir "$ocifolder" 2>/dev/null rmdir "$rclonefolder" 2>/dev/null rm -f "$psmcfgfile" 2>/dev/null printf "Configuration deleted.\n\n" else printf "Skipped.\n\n" fi fi fi # Only delete keys if configuration is deleted if [ ! -f "$projectjson" -a ! -f "$ocijson" ]; then key-management list > $scratchfile result=`head -n 1 $scratchfile | grep "^No keys"` if [ "$result" = "" ]; then grep . $scratchfile confirm "\nDo you want to remove the keys from above?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then rm -fR "$keyshome" mv -f $sshconfig ${sshconfig}.old printf "Renamed '$sshconfig' to '${sshconfig}.old'.\n" printf "Keys deleted.\n\n" else printf "Skipped.\n\n" fi fi rm -f $scratchfile fi # Check if we have print-table available pt=`filecheck -x print-table` if [ -r $manfile -a -r $manfile2 ]; then cat $manfile > $scratchfile cat $manfile2 | tailfromline2 >> $scratchfile if [ "$pt" != "" ]; then $pt --import $scratchfile else cat $scratchfile fi # Ask for remove manuals confirm "\nDo you want to remove the manuals from above?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then printf "\n" while IFS=$'\t' read -r cmd svers; do if [ "$cmd" != "" -a "$svers" != "" ]; then if [ -f "$cmd" ]; then echo "Deleting manual '$cmd'." filecheck -rm "$cmd" fi fi done < <(cat "$scratchfile" | tailfromline2 | stripcomment) filecheck -rm "$manfile" filecheck -rm "$manfile2" UpdateWhatis printf "Manuals removed.\n\n" else printf "Skipped.\n\n" fi rm -f $scratchfile fi if [ -r $toolsfile ]; then if [ "$pt" != "" ]; then print-table --import $toolsfile else cat $toolsfile fi # Ask for remove tools confirm "\nDo you want to remove the tools from above?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then printf "\n" while IFS=$'\t' read -r cmd svers; do if [ "$cmd" != "" -a "$svers" != "" ]; then if [ -f "$cmd" ]; then echo "Deleting tool '$cmd'." filecheck -rm "$cmd" fi fi done < <(cat "$toolsfile" | tailfromline2 | stripcomment) if [ -r "$zipsfile" ]; then while IFS=$'\t' read -r cmd svers; do if [ "$cmd" != "" -a "$svers" != "" ]; then echo "Deleting python-dir '$cmd'." rm -fR "$cmd" fi done < <(cat "$zipsfile" | tailfromline2 | stripcomment) fi if [ -r "$libsfile" ]; then while IFS=$'\t' read -r cmd; do if [ "$cmd" != "" ]; then echo "Deleting library '$cmd'." filecheck -rm "$cmd" fi done < <(cat "$libsfile" | tailfromline2 | stripcomment) fi if [ -r "$templatesfile" ]; then while IFS=$'\t' read -r cmd; do if [ "$cmd" != "" ]; then echo "Deleting template '$cmd'." filecheck -rm "$cmd" basedir=`dirname "$cmd"` rmdir "$basedir" 2>/dev/null fi done < <(cat "$templatesfile" | tailfromline2 | stripcomment) fi filecheck -rm "$toolsfile" filecheck -rm "$zipsfile" filecheck -rm "$libsfile" filecheck -rm "$templatesfile" rmdir "$templatesfolder" 2>/dev/null # rmdir "$manfolder" 2>/dev/null # rmdir "$infofolder" 2>/dev/null # rmdir "$appfolder" 2>/dev/null # rmdir "$binfolder" 2>/dev/null # rmdir "$libfolder" 2>/dev/null # rmdir "$userhome" 2>/dev/null filecheck -rm "/etc/yum.repos.d/tools${bits}.repo" filecheck -rm "/etc/yum.repos.d/tools${bits}.repo.osms-backup" filecheck -rm "$cloudfile" # filecheck -rm "${infofolder}/.admintools" # Delete logs filecheck -rm "/var/log/install-tools.log" filecheck -rm "/var/log/bootstrap.log" printf "Tools removed.\n\n" else printf "Skipped.\n\n" fi fi if [ -d "${REALHOME}/logs" ]; then echo "Content of log folder: ${REALHOME}/logs" > $scratchfile ls -l "${REALHOME}/logs" | tailfromline2 >> $scratchfile if [ "$pt" != "" ]; then print-table --import $scratchfile else cat $scratchfile fi confirm "\nDo you want to remove the logs from above?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then rm -fR "${REALHOME}/logs" stat=$? if [ $stat -eq 0 ]; then printf "Logs removed.\n\n" else exitcode=5 fi else printf "Skipped.\n\n" fi fi if [ -f $scriptsfile ]; then if [ "$pt" != "" ]; then $pt --import $scriptsfile else cat $scriptsfile fi # Ask for remove template files confirm "\nDo you want to remove the scripts from above?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then # Remove get-authkeys from sshd_config if [ -f "/etc/ssh/sshd_config.org" ]; then km=`filecheck -x key-management` if [ "$km" != "" ]; then if [ "$USER" = "root" ]; then $km remove else check-sudo stat=$? if [ $stat -eq 0 ]; then sudo $km remove fi fi else printf "\n" fi else printf "\n" fi while IFS=$'\t' read -r cmd svers; do if [ "$cmd" != "" -a "$svers" != "" ]; then if [ -f "$cmd" ]; then # Tool exists - check if it has a version instvers=`head -n 10 $cmd | grep '^# Version: @(#' | cut -d' ' -f4` if [ "$instvers" != "" ]; then echo "Deleting script '$cmd'." rm -f "$cmd" else echo "Script '$cmd' not deleted. Alternative version found." fi fi fi done < <(cat "$scriptsfile" | tailfromline2 | stripcomment) # Cleanup rm -f "$scriptsfile" printf "Scripts removed.\n" else printf "Skipped.\n" fi fi exit $exitcode else if [ "$IGNORERUNNING" = "" ]; then echo "$progstr $param1" | toupper > $scratchfile printf "\n" print-header --import $scratchfile fi result=`get-ip ip` stat=$? if [ $stat -ne 0 ]; then exitcode=4 errormsg $exitcode "No internet connection. Have to stop here." Cleanup exit $exitcode fi get-platform --output keys > $scratchfile id="`grep '^id:' $scratchfile | cut -d':' -f2-`" id_like="`grep '^id_like:' $scratchfile | cut -d':' -f2-`" name="`grep '^name:' $scratchfile | cut -d':' -f2-`" # codename="`grep '^codename:' $scratchfile | cut -d':' -f2-`" # version_id="`grep '^version_id:' $scratchfile | cut -d':' -f2-`" version_main="`grep '^version_main:' $scratchfile | cut -d':' -f2-`" pretty_name="`grep '^pretty_name:' $scratchfile | cut -d':' -f2-`" proc="`grep '^processor:' $scratchfile | cut -d':' -f2-`" # Infos about the processor type (e.g. i386, sparc) bits="`grep '^bit:' $scratchfile | cut -d':' -f2-`" # 32 or 64 # cloud_id="`grep '^cloud_id:' $scratchfile | cut -d':' -f2-`" # asn_id="`grep '^asn_id:' $scratchfile | cut -d':' -f2-`" filecheck -rm $scratchfile if [ "$bits" != "32" -a "$bits" != "64" ]; then exitcode=5 errormsg $exitcode "Unexpected error. Have to stop here." "Unknown parameter returned by 'get-platform bit'" Cleanup exit $exitcode fi if [ "$param1" = "update" -o "$param1" = "" ]; then result=`filecheck "$0" -fmin` if [ "$result" != "" -a "$param1" = "" -o "$IGNORERUNNING" = "true" ]; then # We installed the scripts 0-15 minutes ago - there is no need for an update stat=1 else if [ "$param1" = "" ]; then confirm "\nDo you want to update scripts?" --yes "y/[yes]" --no "n/no" stat=$? else stat=0 fi fi if [ $stat -eq 0 ]; then # Create tmp script with update if [ "$USER" = "root" ]; then echo "transfer --quiet ${baseurl}/beta/install-scripts | bash" > $scratchfile else check-sudo stat=$? if [ $stat -eq 0 ]; then echo "transfer --quiet ${baseurl}/beta/install-scripts | sudo bash" > $scratchfile else echo "transfer --quiet ${baseurl}/beta/install-scripts | bash" > $scratchfile fi fi echo "$progstr $param1 $param2" >> $scratchfile echo "rm -f $scratchfile" >> $scratchfile chmod 755 $scratchfile export IGNORERUNNING="true" $scratchfile rm -f $scratchfile stat=$? exit $stat fi DisplayVersion # Check if install-tools is alrady running result=`ps -ef | grep "install-tools" | grep -v "grep" | tr -s ' ' | wc -l` if [ $result -gt 0 ]; then printf "\nTools are updating. Please wait until this has finished.\n" Cleanup exit else warn_user="no" if [ "$name" != "Oracle Linux Server" ]; then warn_user="yes" else resultstr=`compare-version 7 "$version_main"` if [ "$resultstr" = "older" ]; then warn_user="yes" fi fi if [ "$warn_user" = "yes" ]; then printf "\nSystem OS: ${pretty_name}\n" errormsg 0 "Next action works best with Oracle Linux Server 7 or newer." errormsg 0 "Only continue with 'yes' if you want to test on a non productive environment." errormsg 0 "Install tools manually if automation fails." fi confirm "\nDo you want to install / update all listed tools?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then if [ "$USER" = "root" ]; then transfer --quiet ${baseurl}/beta/install-tools | bash else check-sudo stat=$? if [ $stat -eq 0 ]; then # sudo --preserve-env=PATH env install-tools transfer --quiet ${baseurl}/beta/install-tools | sudo --preserve-env=PATH bash else transfer --quiet ${baseurl}/beta/install-tools | bash fi fi DisplayVersion fi fi # check-sudo # stat=$? # # if [ $stat -eq 0 -o "$USER" = "root" ]; then # # We only can update linux yet - maybe more to come # if [ "$OS" = "Linux" -a -f $toolsfile ]; then # confirm "\nDo you want to update the OS?" --yes "y/yes" --no "n/[no]" # stat=$? # # if [ $stat -eq 0 ]; then # UpdateOS # fi # fi # fi fi # if [ "$param1" = "bootstrap" -o "$param1" = "" ]; then # if [ "$USER" = "root" ]; then # bootstrap # else # check-sudo # stat=$? # # if [ $stat -eq 0 ]; then # sudo --preserve-env=PATH env bootstrap # fi # fi # fi if [ "$param1" = "config" -o "$param1" = "" ]; then if [ "$param1" = "" ]; then confirm "\nDo you want to configure cloud tools?" --yes "y/[yes]" --no "n/no" stat=$? else stat=0 fi if [ $stat -eq 0 ]; then InitTools if [ "$OCI_CLI_CLOUD_SHELL" != "True" ]; then confirm "\nDo you want to configure crontab?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then # Download extra scripts curl -skL https://standby.cloud/download/samples/dl-extra.bash -o $scratchfile chmod 755 $scratchfile $scratchfile # Download crontab curl -skL https://standby.cloud/download/samples/crontab -o $scratchfile crontab $scratchfile stat=$? if [ $stat -eq 0 ]; then printf "\nCrontab configured. Check with 'crobtab -l'.\n" else printf "\nCrontab not configured. Create one with 'crobtab -e'.\n" fi fi fi fi fi if [ "$OCI_CLI_CLOUD_SHELL" != "True" ]; then if [ "$param1" = "setup" ]; then printf "\n" errormsg 5 "Setting up the multitier network via this tool only works in Cloud Shell." exit 5 fi else if [ "$param1" = "setup" -o "$param1" = "" ]; then if [ "$param1" = "" ]; then if [ ! -d "$tfpjfolder" ]; then confirm "\nDo you want to setup a multitier network via terraform?" --yes "y/[yes]" --no "n/no" stat=$? else stat=1 fi else stat=0 fi if [ $stat -eq 0 ]; then if [ -d "$tfpjfolder" ]; then printf "\nFolder '%s' already exists. Please rename or remove it first.\n" "$tfpjfolder" else # If we don't have needed variables set - read them from config if [ "$namespace" = "" ]; then ReadOCIJson stat=$? else stat=0 fi # Print new line printf "\n" if [ $stat -gt 0 ]; then printf "Config file '$ocijson' could not be found. Please configure tools first with '$progstr config'.\n" else if [ "$writeuri" = "" ]; then ReadProjectJson stat=$? else stat=0 fi if [ $stat -gt 0 ]; then printf "Config file '$projectjson' could not be found. Please configure tools first with '$progstr config'.\n" else if [ "$namespace" != "" -a "$writeuri" != "" ]; then InitTerraformProject "$writeuri" else printf "Unexpected: namespace '$namespace' or writeuri '$writeuri' is empty.\n" fi fi fi fi fi fi fi if [ "$param1" = "terraform" ]; then CallTerraform "$param2" exitcode=$? fi if [ "$param1" = "classic" ]; then ReadOCIJson stat=$? printf "\n" if [ $stat -eq 0 ]; then InitPSMTool "$tenancyid" "$homeregion" "$username" exitcode=$? else printf "Config file '$ocijson' could not be found. Please configure tools first with '$progstr config'.\n" exitcode=$stat fi fi if [ "$param1" = "push" ]; then if [ "$param1" = "" ]; then confirm "\nDo you want to push configuration to operator?" --yes "y/[yes]" --no "n/no" stat=$? else stat=0 fi if [ $stat -eq 0 ]; then # If we don't have needed variables set - read them from config if [ "$namespace" = "" -a -r "$ocijson" ]; then ReadOCIJson stat=$? else stat=0 fi # Prit new line printf "\n" haveTF=0 if [ $stat -gt 0 ]; then printf "Config file '$ocijson' could not be found. Please configure tools first with '$progstr config'.\n" else if [ "$param2" = "" ]; then if [ -d "${tfpjfolder}/.terraform" ]; then CallTerraformOutput output > $scratchfile destination=`browse-json --select 1 --quiet --import $scratchfile operator_private_ip/value` if [ "$destination" != "" ]; then destination="opc@$destination" haveTF=1 fi else destination="" fi while [ "$destination" = "" -a $stat -eq 0 ]; do printf "Destination address ('user@ip' e.g. 'opc@130.61.219.239'): " read inp if [ "$inp" = "" ]; then confirm "You did not enter a destination address. Do you want to enter again?" --yes "y/[yes]" --no "n/no" stat=$? else destination="$inp" fi done else destination="$param2" fi if [ "$destination" != "" ]; then # Check destination if [ ! -r "$sshconfig" ]; then printf "No '$sshconfig' found. Exiting.\n" else # Create list of hosts hosts=`cat "$sshconfig" | grep '^Host ' | cut -d' ' -f2 | grep -v '*'` destuser=`echo "$destination" | cut -d'@' -f1` destip=`echo "$destination" | cut -d'@' -f2` hostname="" # Check if destination already exists and get the host name for host in $hosts; do hn=`ssh -G $host | grep "^hostname " | cut -d' ' -f2` un=`ssh -G $host | grep "^user " | cut -d' ' -f2` if [ "$hn" = "$destip" -a "$un" = "$destuser" ]; then hostname="$host" fi done if [ "$hostname" = "" ]; then # No entry in sshconfig - write one while [ "$hostname" = "" -a $stat -eq 0 ]; do if [ $haveTF -gt 0 ]; then inp="Operator" else printf "Enter an unique hostname (e.g. 'Operator'): " read inp fi if [ "$inp" = "" ]; then confirm "You did not enter a hostname. Do you want to try again?" --yes "y/[yes]" --no "n/no" stat=$? else result=`cat "$sshconfig" | grep "^Host $inp$"` if [ "$result" != "" ]; then haveTF=0 confirm "Hostname '$inp' already exists. Do you try to enter again?" --yes "y/[yes]" --no "n/no" stat=$? else needproxjump=0 hostname="$inp" sshkeys=`key-management list | grep "/${tenancyname}/"` sshprivkey=`echo "$sshkeys" | head -n 1 | sed 's|^'$tenancyname'||' | tr -s ' ' | cut -d' ' -f4` if [ -r "${sshprivkey}.pk8" ]; then # Prefering this key sshprivkey="${sshprivkey}.pk8" fi # Convert $REALHOME to ~ transpsshprivkey=`echo "$sshprivkey" | sed 's|'"$REALHOME"'|~|'` # Check if we have to encrypt key result=`grep "ENCRYPTED" "$sshprivkey"` sshkeygen=`filecheck -x ssh-keygen` if [ "$result" != "" -a "$sshkeygen" != "" ]; then tenantpassphrase=`GetPassphraseFromPassphraseFile "$tenancyname"` if [ "$tenantpassphrase" != "" ]; then cp "$sshprivkey" "${sshprivkey}.org" $sshkeygen -p -P "$tenantpassphrase" -N "" -m PEM -f "$sshprivkey" >/dev/null 2>&1 stat=$? if [ $stat -gt 0 ]; then # We were unable to decrypt the private key mv -f "${sshprivkey}.org" "$sshprivkey" chmod 600 "$sshprivkey" fi fi fi # Check if we can ssh to hostname ssh -i "$sshprivkey" ${destuser}@$destip -o BatchMode=yes -o ConnectTimeout=2 echo 2>/dev/null stat=$? if [ $stat -gt 0 ]; then if [ $haveTF -gt 0 ]; then bastion=`browse-json --select 1 --quiet --import $scratchfile bastion_public_ip/value` if [ "$bastion" != "" ]; then bastionname="Bastion" stat=0 fi else bastionname="" fi if [ "$bastionname" = "" ]; then # Host not reachable - check for a bastion confirm "Host not reachable. Do you have a bastion host?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -eq 0 ]; then # We do have a bastion - get the name of it while [ "$bastionname" = "" ]; do printf "Bastion hostname (leave blank to use name 'Bastion'): " read inp if [ "$inp" = "" ]; then bastionname="Bastion" else bastionname="$inp" fi confirm "You selected bastion hostname '$bastionname'. Correct?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -gt 0 ]; then bastionname="" fi done else echo "Please setup a bastion host first. Then use 'push' again." hostname="" fi fi if [ "$hostname" != "" ]; then # Check if we already defined the bastion host bastion=`echo $hosts | grep '\<'${bastionname}'\>'` if [ "$bastion" != "" ]; then needproxjump=1 else # No Bastion defined in .ssh/config yet bastion="" while [ "$bastion" = "" -a $stat -eq 0 ]; do if [ $haveTF -gt 0 ]; then bastion=`browse-json --select 1 --quiet --import $scratchfile bastion_public_ip/value` if [ "$bastion" != "" ]; then bastion="opc@$bastion" fi fi if [ "$bastion" = "" ]; then printf "Bastion address ('user@ip' e.g. 'opc@130.61.219.239'): " read inp if [ "$inp" = "" ]; then confirm "You did not enter a bastion address. Do you want to try again?" --yes "y/[yes]" --no "n/no" stat=$? else bastion="$inp" fi fi if [ "$bastion" != "" ]; then ssh -i "$sshprivkey" "$bastion" -o BatchMode=yes -o ConnectTimeout=2 echo >/dev/null 2>&1 stat=$? if [ $stat -eq 0 ]; then # Bastion is reachable - write config needproxjump=1 bastuser=`echo "$bastion" | cut -d'@' -f1` bastip=`echo "$bastion" | cut -d'@' -f2` printf '\nHost %s\n' "$bastionname" >> "$sshconfig" printf '\tHostName %s\n' "$bastip" >> "$sshconfig" printf '\tUser %s\n' "$bastuser" >> "$sshconfig" printf '\tIdentityFile "%s"\n' "$transpsshprivkey" >> "$sshconfig" else # Bastion not reachable - Try again? bastion="" confirm "Bastion not reachable. Do you want to try again?" --yes "y/[yes]" --no "n/no" stat=$? if [ $stat -gt 0 ]; then # Bastion not reachable and we don't want to try again echo "You need to specify a bastion host first before using 'push' for 'private hosts'." hostname="" fi fi fi done fi fi fi fi if [ "$hostname" != "" ]; then # Check if host is reachable if [ $needproxjump -gt 0 ]; then # ssh -i "$sshprivkey" "${destuser}@$destip" -J $bastionname -o BatchMode=yes -o ConnectTimeout=2 echo >/dev/null 2>&1 ssh -i $sshprivkey "${destuser}@$destip" -o ProxyCommand="ssh -W %h:%p $bastionname -i $sshprivkey" \ -o BatchMode=yes -o ConnectTimeout=2 echo >/dev/null 2>&1 stat=$? else ssh -i "$sshprivkey" "${destuser}@$destip" -o BatchMode=yes -o ConnectTimeout=2 echo >/dev/null 2>&1 stat=$? fi if [ $stat -eq 0 ]; then printf '\nHost %s\n' "$hostname" >> "$sshconfig" printf '\tHostName %s\n' "$destip" >> "$sshconfig" printf '\tUser %s\n' "$destuser" >> "$sshconfig" if [ $needproxjump -gt 0 ]; then printf '\tProxyJump %s\n' "$bastionname" >> "$sshconfig" fi printf '\tIdentityFile "%s"\n' "$transpsshprivkey" >> "$sshconfig" else echo "Host '$hostname' not reachable. Unable to 'push'." hostname="" fi fi fi done fi if [ "$hostname" != "" ]; then # currdir=`pwd` # cd # zip -q -r ${scratchfile}.zip .oci .admintools # stat=$? # cd $currdir # # if [ $stat -eq 0 ]; then # scp -q "${scratchfile}.zip" "${hostname}:/tmp/config.zip" >/dev/null 2>&1 # stat=$? # fi # # filecheck -rm ${scratchfile}.zip # # if [ $stat -eq 0 ]; then # printf 'if [ -d .oci ]; then\n' > $scratchfile # printf ' mv -f .oci .oci.org\n' >> $scratchfile # printf 'fi\n\n' >> $scratchfile # printf 'unzip -q /tmp/config.zip\n' >> $scratchfile # printf 'rm -f /tmp/config.zip\n' >> $scratchfile # printf 'rm -f %s\n' $scratchfile >> $scratchfile # # scp -q "$scratchfile" "${hostname}:$scratchfile" >/dev/null 2>&1 # stat=$? # # if [ $stat -eq 0 ]; then # ssh "$hostname" "cat $scratchfile | bash" >/dev/null 2>&1 # stat=$? # fi # fi scp -q "$ocijson" "${hostname}:/tmp/config.json" >/dev/null 2>&1 stat=$? if [ $stat -eq 0 ]; then scp -q "$projectjson" "${hostname}:/tmp/project.json" >/dev/null 2>&1 stat=$? fi if [ $stat -eq 0 ]; then printf 'if [ ! -d "$HOME/.oci" ]; then\n' > $scratchfile printf ' mkdir -m 0755 -p "$HOME/.oci"\n' >> $scratchfile printf 'fi\n\n' >> $scratchfile printf 'mv -f /tmp/config.json "$HOME/.oci/config.json"\n' >> $scratchfile printf 'mv -f /tmp/project.json "$HOME/.oci/project.json"\n' >> $scratchfile printf 'chmod 600 "$HOME/.oci/config.json" "$HOME/.oci/project.json"\n' >> $scratchfile printf 'rm -f %s\n' $scratchfile >> $scratchfile scp -q "$scratchfile" "${hostname}:$scratchfile" >/dev/null 2>&1 stat=$? if [ $stat -eq 0 ]; then ssh "$hostname" "cat $scratchfile | bash" >/dev/null 2>&1 stat=$? fi fi if [ $stat -eq 0 ]; then printf "Pushed configuration to host '$hostname'.\n" # Copy keys to destination key-management push "$hostname" --username "$username" 2>/dev/null else printf "Push configuration (ssh) failed. Please check '$sshconfig'.\n" exitcode=5 fi fi # Cleanup if [ -f "${sshprivkey}.org" ]; then mv "${sshprivkey}.org" "$sshprivkey" chmod 600 "$sshprivkey" fi fi fi fi fi fi fi # Cleanup and exit Cleanup exit $exitcode