Skip to content

Instantly share code, notes, and snippets.

@ilobmirt
Last active July 7, 2023 20:21
Show Gist options
  • Save ilobmirt/4852e33aaf0fbb064c2a3b6141ed5172 to your computer and use it in GitHub Desktop.
Save ilobmirt/4852e33aaf0fbb064c2a3b6141ed5172 to your computer and use it in GitHub Desktop.
Shared library for general BASH scripting
#!/bin/bash
#=================================================================================================#
#shared_functs.lib
#----------
#by: ilobmirt @ 2023_JUL_07
#
#Central location for functions shared among various scripts
#=================================================================================================#
echo "===== INCLUDED SHARED_FUNCTS LIBRARY ====="
#=================================================================================================#
declare -A return_code
return_code[SUCCESS]=0
return_code[GENERAL]=1
return_code[INVALID_USAGE]=2
return_code[CANNOT_EXECUTE]=126
return_code[COMMAND_NOT_FOUND]=127
return_code[INVALID_PARAMETER]=128
return_code[FATAL_ERROR]=128
return_code[OUT_OF_RANGE]=255
export return_code
#=================================================================================================#
function fill_params(){
local in_search=''
local in_default=''
local in_input=()
local param_val=''
local is_set=0
local is_found=0
local param_index=1
local param_index_next=0
#Set params for this function
for (( param_index = 1 ; param_index <= $# ; param_index++ )) ; do
param_val=${!param_index}
param_index_next=$((param_index+1))
printf "\n\n-----\n%s\n" "INPUT PARAM $param_index = \"${!param_index}\""
printf "%s\n-----\n\n" "INPUT VALUE $param_index = \"${!param_index_next}\""
case "${param_val}"
in
'--search')
in_search=${!param_index_next}
printf "%s\n" "Set search to \"$in_search\""
param_index=$(( param_index + 1 ))
;;
'--default')
in_default=${!param_index_next}
printf "%s\n" "Set default val to \"$in_default\""
param_index=$(( param_index + 1 ))
;;
'--input')
s2l in_input "${!param_index_next}"
printf "%s\n" "Set input array to \"${in_input[@]}\""
param_index=$(( param_index + 1 ))
;;
'--var')
local -n in_var=${!param_index_next}
printf "%s\n" "Set return var to \"$in_var\""
is_set=1
param_index=$(( param_index + 1 ))
;;
esac
done
#Now we set the value of in_var
if [[ $is_set -eq 0 ]] ; then
#Not set
printf "in_var has not been set\n"
else
#Set
printf "in_var has been set\n"
if [[ ! -z "$in_search" ]] && [[ ! -z "$in_input" ]] ; then
#Set
printf "Search: \"$in_search\"\n"
printf "Input: \"$in_input\"\n"
param_index=0
for (( param_index = 0 ; param_index <= ${#in_input[@]} ; param_index++ )) ; do
param_index_next=$((param_index+1))
param_val=${in_input[param_index]}
printf "SEARCH PARAM $param_index = \"$param_val\"\n"
if [[ "$param_val" = "--$in_search" ]] ; then
in_var=${in_input[param_index_next]}
is_found=1
break
fi
done
#Set Default if not found
if [[ $is_found -eq 0 ]] ; then
in_var=$in_default
fi
else
#Not Set
printf "Search and Input both need to be set\n"
fi
fi
}
export -f fill_params
#=================================================================================================#
function l2s(){
#Convert a list into a single string separated by ';;;'
local main_input="$@"
local main_output=$( echo "${main_input}" | sed 's#\(\".*\"\|\S*\)#\1!!!#g;s#"##g;s#!!! *#!!!#g;s#!!!$##' )
printf "%s" "${main_output}"
}
export -f l2s
#=================================================================================================#
function s2l(){
local -n in_var=$1
local main_input="$2"
local main_output=$(echo "${main_input}" | sed 's#!!!#\n#g')
local calc_list=()
readarray -t calc_list <<<$main_output
in_var=( "${calc_list[@]}" )
}
export -f s2l
#=================================================================================================#
function sync_file(){
local file_target="$1"
local file_contents="$2"
local did_update_var="$3"
if ! [ ${#did_update_var} -eq 0 ]; then
local -n did_update=$3
else
local did_update=0
fi
local check_file_contents=''
if [ -f "$file_target" ] ; then
echo "Target file $file_target found!"
check_file_contents=$(cat "$file_target")
if [ "$check_file_contents" != "$file_contents" ] ; then
echo "Target file $file_target needs an update! Updating!"
echo "$file_contents" | sudo tee "$file_target" > /dev/null
did_update=1
else
echo "Target file $file_target seems up to date."
did_update=0
fi
else
echo "Target file $file_target not found"
did_update=0
fi
}
export -f sync_file
#=================================================================================================#
function rem_ssh_cmd(){
local func_input="$(l2s "$@")"
local target_user=''
local target_host=''
local target_dir=''
local target_cmd=''
local out_result=${return_code[SUCCESS]}
fill_params --input "${func_input}" --var target_user --search user --default 'root' > /dev/null
fill_params --input "${func_input}" --var target_host --search host --default '127.0.0.1' > /dev/null
fill_params --input "${func_input}" --var target_dir --search dir --default "/home/${target_user}" > /dev/null
fill_params --input "${func_input}" --var target_cmd --search cmd --default 'ls' > /dev/null
ssh -t ${target_user}@${target_host} "cd ${target_dir} && ${target_cmd}"
return $out_result
}
export -f rem_ssh_cmd
#=================================================================================================#
function setup_packages(){
sudo apt-get update
local installed_packages=$(apt list --installed)
local to_install=""
local does_exist=""
for input_package in $@
do
does_exist=$(echo "$installed_packages" | grep "$input_package/")
if [ -z "$does_exist" ]; then
echo "Package $input_package not found, adding to list of packages"
to_install="$to_install $input_package"
else
echo "Package $input_package is already installed"
fi
done
if [ ! -z "$to_install" ]; then
echo "Installing $to_install"
sudo apt-get install$to_install -y
else
echo "Nothing found to install"
fi
}
export -f setup_packages
#=================================================================================================#
function set_hostname(){
local target_hostname="$1"
local original_hostname=$(hostname)
local hosts_file_contents=$(sudo cat /etc/hosts)
printf " - (1/3) Updating /etc/hostname ...\n"
echo "${target_hostname}" | sudo tee /etc/hostname
printf " - (2/3) Updating /etc/hosts\n"
hosts_file_contents=$(echo "${hosts_file_contents}" | sed "s/${original_hostname}/${target_hostname}/g")
sync_file "/etc/hosts" "${hosts_file_contents}"
printf " - (3/3) Setting host name to \'${target_hostname}\'\n "
sudo hostname ${target_hostname}
}
export -f set_hostname
#=================================================================================================#
function github_ssh_key(){
local func_input="$(l2s "$@")"
local out_result=${return_code[SUCCESS]}
local local_user=$(id -u -n)
local target_user=''
local target_github=''
local target_method=''
fill_params --input "${func_input}" --var target_user --search user --default "${local_user}" > /dev/null
fill_params --input "${func_input}" --var target_github --search github --default "$1" > /dev/null
fill_params --input "${func_input}" --var target_method --search method --default 'add' > /dev/null
#CONDITION #1 - Github Account must be defined
if [[ "${target_github}" == '' ]]; then
local out_txt=$(cat <<EOF
╔═════════════════════════╗
║github_ssh_key - FAILURE:║
╚═════════════════════════╝
[INVALID_USAGE]. Github Account not defined.
▻ EXAMPLE: github_ssh_key ilobmirt
▔▔▔▔▔▔▔▔
EOF
)
printf "%s\n" "${out_txt}"
out_result=${return_code[INVALID_USAGE]}
return $out_result
fi
#CONDITION #2 - Method needs to be [add|rem|remove]
local method_filter=('add' 'rem' 'remove')
if ! [[ ${method_filter[*]} =~ ${target_method} ]]; then
local out_txt=$(cat <<EOF
╔═════════════════════════╗
║github_ssh_key - FAILURE:║
╚═════════════════════════╝
[INVALID_USAGE]. Invalid method \"${target_method}\"
Acceptable methods are the following...
$(printf "\t[%s]\n" "${method_filter[@]}")
▻ EXAMPLE: github_ssh_key --github ilobmirt --method ${method_filter[0]}
▔▔▔▔▔▔▔▔
EOF
)
printf "%s\n" "${out_txt}"
out_result=${return_code[INVALID_USAGE]}
return $out_result
fi
#CONDITION #3 - User account must have a home directory
if ! [ -d "/home/${target_user}" ]; then
local out_txt=$(cat <<EOF
╔═════════════════════════╗
║github_ssh_key - FAILURE:║
╚═════════════════════════╝
[INVALID_PARAMETER]. The user account \"${target_user}\" does not appear to have a home directory.
EOF
)
out_result=${return_code[INVALID_PARAMETER]}
return $out_result
fi
#After all these checks, lets get the key
local key_comment="${target_github}@github_ssh_key"
local github_key="$(curl https://github.com/${target_github}.keys) ${key_comment}"
#Pull the contents of /home/${target_user}/.ssh/authorized_keys, create if it doesn't exist
if ! [ -d "/home/${target_user}/.ssh" ]; then
sudo mkdir "/home/${target_user}/.ssh"
sudo chmod 700 "/home/${target_user}/.ssh"
sudo chown ${target_user}:${target_user} "/home/${target_user}/.ssh"
fi
if ! [ -f "/home/${target_user}/.ssh/authorized_keys" ]; then
sudo touch "/home/${target_user}/.ssh/authorized_keys"
sudo chmod 600 "/home/${target_user}/.ssh/authorized_keys"
sudo chown ${target_user}:${target_user} "/home/${target_user}/.ssh/authorized_keys"
fi
local auth_key_file=$(sudo cat "/home/${target_user}/.ssh/authorized_keys")
case "${target_method}" in
'rem' | 'remove')
auth_key_file=$(echo "${auth_key_file}" | sed "/${key_comment}/d")
;;
'add')
auth_key_file=$(echo "${auth_key_file}" | sed -r "s/^(ssh-).*(${key_comment})$/${github_key}/g")
if [[ "$(echo "${auth_key_file}" | grep "${key_comment}" )" == '' ]]; then
auth_key_file=$(printf "${auth_key_file}\n${github_key}")
fi
;;
*)
;;
esac
#Now to push the changes to the actual file
sync_file "/home/${target_user}/.ssh/authorized_keys" "${auth_key_file}"
return $out_result
}
export -f github_ssh_key
#=================================================================================================#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment