#!/usr/bin/env bash # # Author: Georg Voell - georg.voell@standby.cloud # Version: @(#)setup-tools 3.2.1 13.11.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 # V 3.2.1 13.11.2024 Use JSON values # # 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() { if [ -f ${scratchfile}.comp ]; then rm -f ${scratchfile}.comp fi if [ -f ${scratchfile}.user ]; then filecheck -rm ${scratchfile}.user fi 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="bash 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 bash) cmd="$cmd --min 4.3" # nameref is needed ;; 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 "true" | 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 --import ${scratchfile}.user --export $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 --import ${scratchfile}.comp --export $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" 2>/dev/null fi else ln -s $tcfgfile "${infofolder}/.admintools" 2>/dev/null 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 result=`filecheck -sl $scratchfile` if [ "$result" != "" ]; then 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 else filecheck -rm $manfile filecheck -rm $manfile2 fi rm -f $scratchfile fi if [ -r $toolsfile ]; then result=`filecheck -sl $toolsfile` if [ "$result" != "" ]; then if [ "$pt" != "" ]; then "$pt" --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 else filecheck -rm $toolsfile fi fi if [ -d "${REALHOME}/logs" ]; then ls -l "${REALHOME}/logs" > $scratchfile result=`filecheck -sl $scratchfile` if [ "$result" != "" ]; then printf "Content of log folder: ${REALHOME}/logs\n\n" tailfromline2 $scratchfile 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 else printf "\nNo logs found. 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 Cleanup 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 result=`get-platform --output keys` id=`GrepKey "$result" "id"` # vers=`GrepKey "$result" "version_main"` id_like=`GrepKey "$result" "id_like"` name=`GrepKey "$result" "name"` # codename=`GrepKey "$result" "codename"` # version_id=`GrepKey "$result" "version_id"` version_main=`GrepKey "$result" "version_main"` pretty_name=`GrepKey "$result" "pretty_name"` proc=`GrepKey "$result" "processor"` # Infos about the processor type (e.g. i386, sparc, arm) bits=`GrepKey "$result" "bit"` # 32 or 64 # gateway=`GrepKey "$result" "gateway"` # iface=`GrepKey "$result" "interface"` # ifup=`GrepKey "$result" "up"` # lip=`GrepKey "$result" "ip_v4"` # cloud_id=`GrepKey "$result" "cloud_id"` # asn_id=`GrepKey "$result" "asn_id"` 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 if [ "$USER" = "root" ]; then transfer --quiet ${baseurl}/beta/install-scripts | bash -s check > $scratchfile stat=$? else check-sudo stat=$? if [ $stat -eq 0 ]; then transfer --quiet ${baseurl}/beta/install-scripts | sudo bash -s check > $scratchfile stat=$? else transfer --quiet ${baseurl}/beta/install-scripts | bash -s check > $scratchfile stat=$? fi fi if [ $stat -eq 0 ]; then printf "\nInstalled scripts:\n\n" grep '^Script ' $scratchfile | sed 's|^Script ||g' confirm "\nDo you want to update scripts?" --yes "y/[yes]" --no "n/no" stat=$? fi 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="false" if [ "$name" != "Oracle Linux Server" ]; then warn_user="true" else resultstr=`compare-version 7 "$version_main"` if [ "$resultstr" = "older" ]; then warn_user="true" fi fi if [ "$warn_user" = "true" ]; 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 tools if possible?" --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