#!/bin/bash
# AUTHOR    :   vinci
# DATE      :   2020-12-23_18:44:26
# PROGRAM   :   minstall
# USAGE     :   minstall <OPTIONS> <INPUT>
#
# NEEDS     :   
#
# PROVIDES  :   
#
# PURPOSE:
# 
# EXAMPLE:
#   
# NOTES:
#

#=========================
# Exit Codes:
# It's a good style to document your exit codes here.
#-# 100 : No option or argument specified
#-# 101 : Unknown option specified
#-# 102 : Wrong option combination
#-# 103 : Wrong or invalid input
#=========================

#=========================
# MY STANDARD COLORS
# Some take the colb/colf input, some the setaf/setab type of writing
# See what supports your system, comment the rest.
bold=$(tput bold)
reset_all=$(tput sgr0 )

black_on_red=$(     tput setaf 0; tput setab 1)
black_on_green=$(   tput setaf 0; tput setab 2)
black_on_yellow=$(  tput setaf 0; tput setab 3)

red_on_white=$(     tput setaf 1; tput setab 7)
green_on_white=$(   tput setaf 2; tput setab 7)
yellow_on_white=$(  tput setaf 3; tput setab 7)
blue_on_white=$(    tput setaf 4; tput setab 7)

red_on_black=$(     tput setaf 1; tput setab 0)
green_on_black=$(   tput setaf 2; tput setab 0)
yellow_on_black=$(  tput setaf 3; tput setab 0)

red=$(      tput setaf 1)
green=$(    tput setaf 2)
yellow=$(   tput setaf 3)
blue=$(     tput setaf 4)
magenta=$(  tput setaf 5)
cyan=$(     tput setaf 6)
#
# MY STANDARD COLORS END
#=========================

#=========================
# MY VARIABLES BEGIN
# Take this for welcome and log actions.
me=$( whoami | awk '{print $1}' )
my_gecos=$( awk -F":" -v me=$me '$1 == me {print $5}' /etc/passwd )

# If we have no gecos (probably because we have LDAP), take username instead.
if [[ -z $my_gecos ]]; then
    my_gecos=$me
fi

# Initial script infos
version='1.0'
state='experimental'
author='vinci'
script_desc="$( basename $0 ), version $version, state $state, author $author ."

# Form welcome string.
separator="=================================================="
script_header="$separator\n Welcome $my_gecos,\n This is $script_desc \n$separator"

# Some colored output markers, 8 chars in length each ...
_ER="${black_on_red}ERROR  :${reset_all}"
_IN="${blue_on_white}INFO   :${reset_all}"
_WA="${black_on_yellow}WARNING:${reset_all}"
_OK="${black_on_green}OK     :${reset_all}"
_DB="${green_on_white}DEBUG  :${reset_all}"
_OE="${black_on_green}OK.${reset_all}"      # Ok at end of line.
# MY VARIABLES END
#=========================


usage()
{
echo -e "
------------------------------------------------------------------------------------
${bold}$(basename $0):${reset_all}

Install MARS client onto another system from MARS Master.

${bold}Synopsis :

$(basename $0) [-OPTIONS] TARGET

OPTIONS:${reset_all}
-r 'OPTIONAL RPMS'  : Take 'mars' packages on target.
-k SSH_PRIVATE_KEY  : Take alternate private key
-C                  : Turn off colors.
-d                  : Turn debug mode on.
-h                  : This usage.
-q                  : quiet output.
-v                  : verbose output.
-V                  : Print version and exit.

TARGET              : Target to install a MARS minion.

HINT:
    If you use the '-r' option, the packages must be in
    absolute paths on the target server.
    You need at least a mars-common and a mars-minion package,
    which must be specified space separated, e.g.
    ... -r '/tmp/mars-common-1.1.0-32.noarch.rpm /tmp/mars-minion-0.1.0-12.noarch.rpm'
------------------------------------------------------------------------------------ "
}

#=========================
# OPTION HANDLING BEGIN
while getopts r:k:CdhqvV option
do
    case $option in
        r)  # Use (whitespace separated) optional RPMs on target system.
            # Must be absolute paths surrounded by quotes, e.g.:
            # -r '/tmp/mars-common-1.1.0-32.noarch.rpm /tmp/mars-minion-0.1.0-12.noarch.rpm'
            flag_rpms="up"
            value_rpms="$OPTARG"
        ;;

        k)  # Take alternate ssh-key instead of default.
            flag_key="up"
            value_key="$OPTARG"
            if [[ ! -f $value_key || ! -r $value_key ]]; then
                echo "$_ER Invalid input for option '-k PRIVATE_SSHKEY'"
                echo "$_IN Not a file or not readable: $value_key"
                exit 103
            fi
        ;;

        C)  # NO Colors
            # Disable standard colors
            bold=""
            reset_all=""
            black_on_red=""
            black_on_green=""
            black_on_yellow=""

            red_on_white=""
            green_on_white=""
            yellow_on_white=""
            blue_on_white=""

            red_on_black=""
            green_on_black=""
            yellow_on_black=""

            red=""
            green=""
            yellow=""
            blue=""
            magenta=""
            cyan=""

            _ER="ERROR  :"
            _IN="INFO   :"
            _WA="WARNING:"
            _OK="OK     :"
            _DB="DEBUG  :"
            _OE="OK."
        ;;

        d)  # Turn debug on
            flag_debug="up"
        ;;

        h) # Help
            usage
            exit 0
        ;;

        q)  # turn on quiet mode
            flag_quiet="up"
        ;;

        v)  # turn on verbose mode
            flag_verbose="up"
        ;;

        V) # version
            echo -e "${bold}\n $script_desc ${reset_all}"
            echo -e "\n Maybe try $(basename $0) -h or man $(basename $0)"
            echo -e " for more information."
            exit 0
        ;;

        *) # Else unknown option
            usage
            exit 101
        ;;
    esac
done
shift $(($OPTIND -1))

TARGET=$1
if [[ ! -z $value_rpm ]]; then
    OPT_RPM=$value_rpm
fi

echo -e "$script_header"

#-------------------------
# Master must have fqdn
MASTER=$( hostname -f )
if [[ -z $MASTER ]]; then
    echo "$_ER This host can not resolve itself which 'hostname -f'"
    exit 1
fi

#-------------------------
# Of course we need the target
if [[ -z $TARGET ]]; then
    echo "$_ER No target defined."
    usage
    exit 1
fi

if [[ ! -z $( echo "$TARGET" | grep '\.' ) ]]; then
    LTARGET=$TARGET
else
    LTARGET=$( /usr/local/bin/longname $TARGET )
    if [[ -z $LTARGET ]]; then
        echo "$_ER Could not get long name of $TARGET."
        echo "$_IN Please retry with FQDN of $TARGET."
    fi
fi

#-------------------------
# We need ssh and scp
SSH=$( which ssh )
if [[ $? -ne 0 ]]; then
    echo "$_ER No ssh found"
    exit 1
fi

SCP=$( which scp )
if [[ $? -ne 0 ]]; then
    echo "$_ER: No ssh found"
    exit 1
fi

#-------------------------
# Target must be at least in netgroup 'mars_all'
in_mars_all=$( marsng -bh $TARGET | awk '$1 == "mars_all"' )
if [[ -z $in_mars_all ]]; then
    echo "$_ER $TARGET must be at least in netgroup 'mars_all'"
    echo "$_IN Please add with 'marsng -ah $TARGET mars_all'"
    echo "$_IN Or to another netgroup that is a subgroup of mars_all"
    exit 1
fi

#-------------------------
# Ensure our ssh-key is on target.
if [[ ! -z $value_key ]]; then
    SSH_KEY=$value_key
else
    SSH_KEY=$( realpath ~/.ssh/id_rsa )
    if [[ ! -f $SSH_KEY ]]; then
        echo "$_ER No ssh private key found."
        echo "$_IN Expected '$SSH_KEY'"
        echo "$_IN Please create a ssh key pair with 'ssh-keygen -t rsa'"
        echo "$_IN or specify a valid ssh private key with the '-k' option."
        exit 1
    fi
fi

ssh-copy-id -f -i $SSH_KEY $LTARGET
if [[ $? -ne 0 ]]; then
    echo "$_ER Could not copy our ssh-key to $TARGET"
    echo "$_IN Please correct, then retry."
    exit 1
fi

#-------------------------
# Remove key on master if found.
if [[ ! -z $( salt-key -L | grep $LTARGET ) ]]; then
    echo "$_IN Removing salt-key ..."
    salt-key -yd $LTARGET
fi

#-------------------------
# Copy helper to target.
# Check if we need python2 or python 3 to run it.
# The helper will install mars-minion and give access to
# marsconfigure_minion.
# Then configure minion with it.
$SCP /usr/local/sbin/minstall_helper.py ${LTARGET}:/tmp

python3=$( $SSH $LTARGET which python3 2>/dev/null )
if [[ $? -eq 0 ]]; then
    $SSH $LTARGET $python3 /tmp/minstall_helper.py "'$value_rpms'"
else
    $SSH $LTARGET python /tmp/minstall_helper.py "'$value_rpms'"
fi

if [[ $? -eq 0 ]]; then
    $SSH $LTARGET /usr/local/sbin/marsconfigure_minion enable -k master=$MASTER
fi

$SSH $LTARGET rm -f /tmp/minstall_helper.py
