mirror of
https://github.com/m8tin/cis.git
synced 2026-06-02 14:56:58 +02:00
Introducing modules and improvements
This commit is contained in:
Executable
+348
@@ -0,0 +1,348 @@
|
||||
#!/bin/bash
|
||||
[ "${BASH_VERSINFO[0]}" -lt 4 ] \
|
||||
&& echo "Version 4 or newer is required, bash has version : '${BASH_VERSION}'." >&2 \
|
||||
&& exit 1
|
||||
|
||||
|
||||
|
||||
function checkAllInputParameters() {
|
||||
local _ALLOWED_CHARS _ARG _SUCCESS
|
||||
# Global whitelist for all start-parameters ($1, $2, ...)
|
||||
_ALLOWED_CHARS='-[:alnum:]_.:'
|
||||
readonly _ALLOWED_CHARS
|
||||
|
||||
_SUCCESS="true"
|
||||
for _ARG in "${@}"; do
|
||||
if [[ -n "${_ARG}" ]]; then
|
||||
# Has to start with an alphanumeric char or --
|
||||
if [[ ! "${_ARG}" =~ ^[[:alnum:]] ]] && [[ ! "${_ARG}" =~ ^--[[:alnum:]] ]]; then
|
||||
echo "❌ Security: No special character is allowed at the bginning of the parameter: '${_ARG}'" >&2
|
||||
_SUCCESS="false"
|
||||
fi
|
||||
# No forbidden character is allowed to remain
|
||||
if [[ -n "${_ARG//[${_ALLOWED_CHARS}]/}" ]]; then
|
||||
echo "❌ Security: Illegal character found in parameter: '${_ARG}'" >&2
|
||||
_SUCCESS="false"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
[ "${_SUCCESS}" == "true" ] \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function checkScriptforCorrectAssignments() {
|
||||
local _LN=0
|
||||
local _SUCCESS="true"
|
||||
|
||||
while IFS= read -r _line || [[ -n "${_line}" ]]; do
|
||||
((_LN++))
|
||||
|
||||
[[ ! "${_line}" =~ ^.*(=\$|=\"\$).*$ ]] && continue # Assignments only
|
||||
|
||||
[[ "${_line}" =~ ^[[:space:]]*# ]] && continue # Comments are okay
|
||||
|
||||
[[ "${_line}" =~ ^[[:space:]]+[a-zA-Z0-9_]+=[^\ ]+ ]] && continue # Allow assignments in functions
|
||||
|
||||
[[ "${_line}" =~ ^[a-zA-Z0-9_]+=[^\ ]+ ]] && [[ ! "${_line}" =~ "base.set" ]] \
|
||||
&& echo "❌ line ${_LN}: direct assignment prohibited! Use 'base.set VARNAME VALUE REGEX' instead." >&2 \
|
||||
&& _SUCCESS="false"
|
||||
|
||||
done < "${0}"
|
||||
|
||||
[ "${_SUCCESS}" == "true" ] \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function prepare.setCIS(){
|
||||
# Check precondition
|
||||
[[ "${CIS[SET]:+isset}" != "isset" ]] \
|
||||
&& base.abort "Array CIS was not initialized correctly."
|
||||
|
||||
# Retrieves the variables for this module using 'BASH_SOURCE[0]', the infos about the script using '$0'.
|
||||
local _CISROOT _FULLBASENAME _FULLSCRIPTNAME
|
||||
_FULLBASENAME=$(readlink -e "${BASH_SOURCE[0]}" 2> /dev/null)
|
||||
_FULLSCRIPTNAME=$(readlink -e "${0}" 2> /dev/null)
|
||||
_CISROOT=$(echo "${_FULLSCRIPTNAME}" | grep -o '^.*/cis/')
|
||||
readonly _CISROOT _FULLBASENAME _FULLSCRIPTNAME
|
||||
|
||||
# Folders always ends with an tailing '/'
|
||||
CIS[ROOT]="${_CISROOT:?"Missing CISROOT"}"
|
||||
CIS[COREROOT]="${CIS[ROOT]}core/"
|
||||
CIS[SCRIPTSROOT]="${CIS[ROOT]}script/"
|
||||
CIS[DOMAIN]=$("${CIS[COREROOT]}"printOwnDomain.sh)
|
||||
CIS[MODULEDIR]="${CIS[ROOT]}module/"
|
||||
|
||||
[ -z "${CIS[DOMAIN]}" ] \
|
||||
&& echo \
|
||||
&& echo "No domain could be found for this host:" \
|
||||
&& echo " This may be due to an incorrect configuration." \
|
||||
&& echo \
|
||||
&& return 1
|
||||
|
||||
# Sets the valus of the global array 'CIS' and set it readonly
|
||||
CIS[ARGS]="${@}"
|
||||
CIS[HOME]="${HOME:-"/root"}/"
|
||||
CIS[HOST]="$(hostname -b)"
|
||||
CIS[USER]="$(whoami)"
|
||||
|
||||
# Ensures each user is allowed to create 'his' folder.
|
||||
CIS[LOGDIR]="/tmp/${CIS[USER]:-"UNKNOWN"}/cis/"
|
||||
CIS[WORKDIR]="$(pwd)/"
|
||||
|
||||
CIS[BASE]="${_FULLBASENAME:?"Missing FULLBASENAME"}"
|
||||
CIS[FULLSCRIPTNAME]="${_FULLSCRIPTNAME:?"Missing FULLSCRIPTNAME"}"
|
||||
|
||||
# Like 'dirname ${CIS[FULLSCRIPTNAME]}'
|
||||
CIS[SCRIPTDIR]="${CIS[FULLSCRIPTNAME]%/*}/"
|
||||
|
||||
# Like 'basename ${CIS[FULLSCRIPTNAME]}'
|
||||
CIS[SCRIPTNAME]="${CIS[FULLSCRIPTNAME]##*/}"
|
||||
|
||||
CIS[DEFAULTDEFINITIONS]="${CIS[ROOT]}definitions/default/"
|
||||
CIS[DOMAINDEFINITIONS]="${CIS[ROOT]}definitions/${CIS[DOMAIN]}/"
|
||||
CIS[DOMAINSTATES]="${CIS[ROOT]}states/${CIS[DOMAIN]}/"
|
||||
|
||||
CIS[SET]="normal"
|
||||
# Sets the write protection of array 'CIS'
|
||||
declare -A -g -r CIS
|
||||
return 0
|
||||
}
|
||||
|
||||
function prepare.setCOLOR(){
|
||||
# Check the procondition,
|
||||
[[ "${COLOR[SET]:+isset}" != "isset" ]] \
|
||||
&& base.abort "Array COLOR was not initialized correctly."
|
||||
|
||||
# set the values into the global array 'COLOR',
|
||||
COLOR[NO]='\033[0m'
|
||||
COLOR[RED]='\033[0;31m'
|
||||
COLOR[GREEN]='\033[0;32m'
|
||||
COLOR[DARKYELLOW]='\033[0;33m'
|
||||
COLOR[BLUE]='\033[0;34m'
|
||||
COLOR[PURPLE]='\033[0;35m'
|
||||
COLOR[CYAN]='\033[0;36m'
|
||||
COLOR[LIGHTGREY]='\033[0;37m'
|
||||
COLOR[DARKGREY]='\033[1;30m'
|
||||
COLOR[LIGHTRED]='\033[1;31m'
|
||||
COLOR[LIGHTGREEN]='\033[1;32m'
|
||||
COLOR[YELLOW]='\033[1;33m'
|
||||
COLOR[LIGHTBLUE]='\033[1;34m'
|
||||
COLOR[WHITE]='\033[1;37m'
|
||||
|
||||
# and define the array 'COLOR' as readonly.
|
||||
declare -A -g -r COLOR
|
||||
return 0
|
||||
}
|
||||
|
||||
function prepare.setPATH(){
|
||||
local _GREP_PATH
|
||||
_GREP_PATH="${1:?"Missing parameter GREP_PATH"}"
|
||||
readonly _GREP_PATH
|
||||
# Fixes the paths, ...
|
||||
if [ -x ${_GREP_PATH} ]; then
|
||||
echo ":${PATH}:" | ${_GREP_PATH} -q ":/bin:" || export PATH="${PATH}:/bin" 2> /dev/null
|
||||
echo ":${PATH}:" | ${_GREP_PATH} -q ":/sbin:" || export PATH="${PATH}:/sbin" 2> /dev/null
|
||||
echo ":${PATH}:" | ${_GREP_PATH} -q ":/usr/bin:" || export PATH="${PATH}:/usr/bin" 2> /dev/null
|
||||
echo ":${PATH}:" | ${_GREP_PATH} -q ":/usr/sbin:" || export PATH="${PATH}:/usr/sbin" 2> /dev/null
|
||||
echo ":${PATH}:" | ${_GREP_PATH} -q ":/usr/local/bin:" || export PATH="${PATH}:/usr/local/bin" 2> /dev/null
|
||||
echo ":${PATH}:" | ${_GREP_PATH} -q ":/usr/local/sbin:" || export PATH="${PATH}:/usr/local/sbin" 2> /dev/null
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
function base.abort(){
|
||||
# Minimalmode in case of emergency
|
||||
[[ "${COLOR[SET]:+isset}" != "isset" ]] \
|
||||
&& printf %b "\nScript aborted during preparation (State: '${CIS[SET]:-""}')!\n" >&2 \
|
||||
&& printf %b " ${@}\n\n" >&2 \
|
||||
&& exit 1
|
||||
|
||||
local _FULLSCRIPTNAME=$(readlink -e "${0}" 2> /dev/null)
|
||||
local _SCRIPTNAME="${_FULLSCRIPTNAME##*/}"
|
||||
|
||||
[ "${1:+isset}" != "isset" ] \
|
||||
&& base.printWithColor LIGHTRED "\nScript ${_SCRIPTNAME} aborted!\n\n" >&2 \
|
||||
&& exit 1
|
||||
|
||||
[ "${2:+isset}" != "isset" ] \
|
||||
&& base.printWithColor LIGHTRED "\nScript ${_SCRIPTNAME} aborted!\n" >&2 \
|
||||
&& base.printWithColor WHITE "${1:?"Missing parameter MESSAGE."}\n\n" >&2 \
|
||||
&& exit 1
|
||||
|
||||
[ "${3:+isset}" != "isset" ] \
|
||||
&& base.printWithColor LIGHTRED "\nScript ${_SCRIPTNAME} aborted!\n" >&2 \
|
||||
&& base.printWithColor WHITE "${1:?"Missing parameter MESSAGE."}\n\n" >&2 \
|
||||
&& base.printWithColor CYAN "TIP: ${2:?"Missing parameter TIP."}\n" >&2 \
|
||||
&& exit 1
|
||||
|
||||
base.printWithColor LIGHTRED "\nScript ${_SCRIPTNAME} aborted!\n" >&2
|
||||
base.printWithColor WHITE "${1:?"Missing parameter MESSAGE."}\n\n" >&2
|
||||
base.printWithColor CYAN "TIP - ${2:?"Missing parameter TIP."}:\n" >&2
|
||||
while shift; do
|
||||
[ -z "${2:-""}" ] && break
|
||||
base.printWithColor LIGHTGREY " ${2}\n" >&2
|
||||
done
|
||||
exit 1
|
||||
}
|
||||
|
||||
function base.filterComments(){
|
||||
local _FILENAME
|
||||
_FILENAME="${1:?"base.filterComments() Missing first parameter FILENAME"}"
|
||||
readonly _FILENAME
|
||||
|
||||
# Filters comments (# und ;) and empty lines, retuns the remaining content...
|
||||
grep -o "^[[:blank:]]*[^[:blank:]#;].\+$" "${_FILENAME}" \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Funktionen von Module, die mit dieser Funktion geladen werden, behalten ihren Name.
|
||||
# Deshalb dürfen solche Funktionen auch nicht per '→ FunktionsName' aufgerufen werden!
|
||||
function base.loadModule(){
|
||||
local _MODULENAME _MODULEFULLNAME
|
||||
_MODULENAME="${1:?"Function base.loadModule(): Missing parameter MODULENAME."}"
|
||||
_MODULEFULLNAME="${CIS[MODULEDIR]:?"Function base.loadModule(): Missing CISMODULEDIR."}/${_MODULENAME}.module.sh"
|
||||
readonly _MODULENAME _MODULEFULLNAME
|
||||
|
||||
#module already is loaded => return
|
||||
declare -f "module.${_MODULENAME}" > /dev/null 2>&1 \
|
||||
&& return 0
|
||||
|
||||
#Iterates each function and checks for name-collisions with other programms or functions
|
||||
local _functionName _programPath
|
||||
for _functionName in $(grep "^[[:space:]]*function" "${_MODULEFULLNAME}" | cut -d' ' -f2 | cut -d'(' -f1); do
|
||||
_programPath="$(which "${_functionName}")"
|
||||
echo "${_programPath}" | grep -q "/${_functionName}" \
|
||||
&& echo "WARNING: Loading this module '${_MODULEFULLNAME}' hides the program '${_programPath}'."
|
||||
|
||||
[ "${_functionName}" == "$(declare -F ${_functionName})" ] \
|
||||
&& echo "WARNING: Loading this module '${_MODULEFULLNAME}' replaces the existing function '${_functionName}'."
|
||||
|
||||
# Checks the convention of the function's names
|
||||
echo "${_functionName}" | grep -q "${_MODULENAME}." \
|
||||
&& continue
|
||||
|
||||
base.abort "Module ${_MODULEFULLNAME} does not comply the convention." "All function names has to start with '${_MODULENAME}.'."
|
||||
done
|
||||
|
||||
#Command source actually loads the module.
|
||||
# source <(sed 's/\bfunction \b/&.cis_/' "${_MODULEFULLNAME}") would rename the functions additionally...
|
||||
#Command eval creates a function which is used to determine if the module already is loaded
|
||||
source "${_MODULEFULLNAME}" \
|
||||
&& eval "function module.${_MODULENAME}(){ declare -F | grep '${_MODULENAME}\.' >&2; }" \
|
||||
&& return 0
|
||||
|
||||
base.abort "Unable to load module '${_MODULEFULLNAME}'."
|
||||
}
|
||||
|
||||
function base.log() {
|
||||
local _LOGLEVEL _LOGLEVEL_UPPER
|
||||
base.set _LOGLEVEL "${1}" '^(error|warn|info|debug)$' || exit 1
|
||||
_LOGLEVEL_UPPER="${_LOGLEVEL:?"base.log(): Missing valid first parameter LOGLEVEL"}"
|
||||
_LOGLEVEL_UPPER="${_LOGLEVEL_UPPER^^}"
|
||||
readonly _LOGLEVEL_UPPER
|
||||
|
||||
case "${CIS[LOGLEVEL]:-warn}" in
|
||||
debug) [ "${_LOGLEVEL_UPPER}" = "DEBUG" ] && echo "[${_LOGLEVEL_UPPER}] $(date +%H:%M:%S) - ${2}" >&2 ;& # Forces execution to continue in the next block
|
||||
info) [ "${_LOGLEVEL_UPPER}" = "INFO" ] && echo "[${_LOGLEVEL_UPPER}] $(date +%H:%M:%S) - ${2}" >&2 ;&
|
||||
warn) [ "${_LOGLEVEL_UPPER}" = "WARN" ] && echo "[${_LOGLEVEL_UPPER}] $(date +%H:%M:%S) - ${2}" >&2 ;&
|
||||
error) [ "${_LOGLEVEL_UPPER}" = "ERROR" ] && echo "[${_LOGLEVEL_UPPER}] $(date +%H:%M:%S) - ${2}" >&2 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
function base.printModuleFunctions(){
|
||||
local _MODULENAME
|
||||
_MODULENAME="${1:?"Function base.printModuleFunctions(): Missing parameter MODULENAME."}"
|
||||
readonly _MODULENAME
|
||||
|
||||
[ "${_MODULENAME}" = "base" ] \
|
||||
&& declare -f $(declare -F | grep "${_MODULENAME}." | cut -d" " -f3) \
|
||||
&& return 0
|
||||
|
||||
# If module is loaded => continue
|
||||
declare -f "module.${_MODULENAME}" > /dev/null 2>&1 \
|
||||
&& declare -f $(declare -F | grep "${_MODULENAME}." | cut -d" " -f3) \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function base.printWithColor() {
|
||||
local _COLOR _COLOR_KEY _MESSAGE _NO_COLOR
|
||||
_COLOR_KEY="${1:?"log.color(): Missing first parameter COLOR."}"
|
||||
# It printing target is a terminal which supports more than 8 colors.
|
||||
if [ -t 1 ] \
|
||||
&& [ "$(tput colors 2>/dev/null || echo 0)" -ge 8 ] \
|
||||
&& [[ "$(declare -p COLOR 2>/dev/null)" == "declare -A"* ]] \
|
||||
&& [ -n "${COLOR[${_COLOR_KEY}]}" ]
|
||||
then
|
||||
_COLOR="${COLOR[${_COLOR_KEY}]}"
|
||||
_NO_COLOR="${COLOR[NO]}"
|
||||
fi
|
||||
shift
|
||||
if [ $# -gt 0 ]; then
|
||||
_MESSAGE="$*"
|
||||
elif [ ! -t 0 ]; then
|
||||
# Read from stdin, if there is something in the pipe only.
|
||||
_MESSAGE=$(cat)
|
||||
fi
|
||||
|
||||
printf "%b%b%b" "${_COLOR:-""}" "${_MESSAGE}" "${_NO_COLOR:-""}" \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function base.set() {
|
||||
local _VARNAME="${1:?"base.set(): Missing first parameter VARNAME"}"
|
||||
local _VALUE="${2}"
|
||||
local _REGEX="${3:?"base.set(): Missing third parameter REGEX"}"
|
||||
|
||||
# Sets the value to a global variable with name $_VARNAME
|
||||
[[ "${_VALUE}" =~ $_REGEX ]] \
|
||||
&& printf -v "${_VARNAME}" "%s" "${_VALUE}" \
|
||||
&& readonly "${_VARNAME}" \
|
||||
&& return 0
|
||||
|
||||
echo "❌ Security: Validation '$_REGEX' failed for ${_VARNAME}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Check if this module was started correctly using source
|
||||
if [ "${BASH_SOURCE[0]}" == "${0}" ]; then
|
||||
# Script was executed directly, e.g. by ./base.sh
|
||||
echo "FAILURE: you are using this module 'base.sh' in a wrong way."
|
||||
echo " It is intended as a utility library and should not be called directly."
|
||||
echo
|
||||
echo "Usage: Call the base module at the beginning of your script e.g. like this:"
|
||||
echo
|
||||
echo ' #!/bin/bash'
|
||||
echo ' source /cis/core/base.module.sh'
|
||||
echo
|
||||
echo "Now you can use the functions provided by this module inside your script:"
|
||||
echo "-------------------------------------------------------------------------"
|
||||
declare -F | grep "base." | cut -d" " -f3
|
||||
exit 1
|
||||
else
|
||||
# If not exists, define a global array 'COLOR'
|
||||
trap "base.abort ' User-initiated termination.'" INT \
|
||||
&& checkAllInputParameters "${@}" \
|
||||
&& declare -A -g COLOR=([SET]=unprepared) \
|
||||
&& prepare.setCOLOR \
|
||||
&& prepare.setPATH "/bin/grep" \
|
||||
&& declare -A -g CIS=([SET]=unprepared) \
|
||||
&& prepare.setCIS \
|
||||
&& checkScriptforCorrectAssignments \
|
||||
|| base.abort "The necessary preparations have failed."
|
||||
|
||||
base.log debug "Module '${BASH_SOURCE[0]}' loaded by script: ${0}"
|
||||
fi
|
||||
Executable
+215
@@ -0,0 +1,215 @@
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
#Function, to highlight bad messages.
|
||||
function log.bad() {
|
||||
local _MESSAGE="${@:?"log.bad(): Missing first parameter MESSAGE."}"
|
||||
|
||||
base.printWithColor LIGHTRED "${_MESSAGE}" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, for data.
|
||||
function log.data() {
|
||||
local _MESSAGE="${@:?"log.data(): Missing first parameter MESSAGE."}"
|
||||
|
||||
base.printWithColor LIGHTGREY "${_MESSAGE}" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, for uncorrectable errors.
|
||||
function log.error() {
|
||||
local _MESSAGE="${@:-""}"
|
||||
|
||||
[ -z "${_MESSAGE:-""}" ] \
|
||||
&& base.printWithColor LIGHTRED "ERROR!\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
base.printWithColor LIGHTRED "ERROR!\n" >&2 \
|
||||
&& base.printWithColor WHITE " ${_MESSAGE}\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, for very important information.
|
||||
function log.essential() {
|
||||
local _MESSAGE="${@:?"log.essential(): Missing first parameter MESSAGE."}"
|
||||
|
||||
base.printWithColor LIGHTRED "${_MESSAGE}" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, for failures.
|
||||
function log.failure() {
|
||||
local _MESSAGE="${@:-""}"
|
||||
|
||||
[ -z "${_MESSAGE:-""}" ] \
|
||||
&& base.printWithColor LIGHTRED "FAILURE!\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
base.printWithColor LIGHTRED "FAILURE!\n" >&2 \
|
||||
&& base.printWithColor WHITE " ${_MESSAGE}\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, to finish a script.
|
||||
function log.finish() {
|
||||
local _SCRIPTNAME="${CIS[SCRIPTNAME]:?"log.finish(): Missing CIS[SCRIPTNAME]."}"
|
||||
|
||||
base.printWithColor WHITE "\nScript ${_SCRIPTNAME}: " >&2 \
|
||||
&& base.printWithColor LIGHTGREEN "successful!\n\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, to highlight good messages.
|
||||
function log.good() {
|
||||
local _MESSAGE="${@:?"log.good(): Missing first parameter MESSAGE."}"
|
||||
|
||||
base.printWithColor LIGHTGREEN "${_MESSAGE}" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, for important information.
|
||||
function log.important() {
|
||||
local _MESSAGE="${@:?"log.important(): Missing first parameter MESSAGE."}"
|
||||
|
||||
base.printWithColor YELLOW "${_MESSAGE}" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, for normal information.
|
||||
function log.info(){
|
||||
local _MESSAGE="${1:?"log.info(): Missing first parameter MESSAGE."}"
|
||||
shift
|
||||
local _DECRIPTION="${@:-""}"
|
||||
|
||||
[ -z "${_DECRIPTION:-""}" ] \
|
||||
&& base.printWithColor LIGHTBLUE "INFO:\n" >&2 \
|
||||
&& base.printWithColor WHITE " ${_MESSAGE}\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
base.printWithColor LIGHTBLUE "INFO - " >&2 \
|
||||
&& base.printWithColor WHITE "${_MESSAGE}:\n" >&2 \
|
||||
&& base.printWithColor LIGHTGREY "${_DECRIPTION}\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, for highlighted messages.
|
||||
function log.message(){
|
||||
local _MESSAGE="${@:?"log.message(): Missing first parameter MESSAGE."}"
|
||||
|
||||
base.printWithColor WHITE "${_MESSAGE}" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, for additional information.
|
||||
function log.optional(){
|
||||
local _MESSAGE="${@:?"log.optional(): Missing first parameter MESSAGE."}"
|
||||
|
||||
base.printWithColor LIGHTBLUE "${_MESSAGE}" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, to start a script.
|
||||
function log.start(){
|
||||
local _MESSAGE="${@:-""}"
|
||||
local _CISROOT="${CIS[ROOT]:?"log.start(): Missing CIS[ROOT]."}"
|
||||
local _SCRIPTDIR="${CIS[SCRIPTDIR]:?"log.start(): Missing CIS[SCRIPTDIR]."}"
|
||||
local _SERVICE="$(echo "${_SCRIPTDIR##${_CISROOT}/}" | tr '[:lower:]' '[:upper:]')"
|
||||
local _COMMAND="${CIS[SCRIPTNAME]:?"log.start(): Missing CIS[SCRIPTNAME]."}"
|
||||
|
||||
[ -z "${_MESSAGE:-""}" ] \
|
||||
&& base.printWithColor YELLOW "${_SERVICE} ${_COMMAND}:\n\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
base.printWithColor YELLOW "${_SERVICE} ${_COMMAND}:\n" >&2 \
|
||||
&& base.printWithColor LIGHTBLUE "${_MESSAGE}\n\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, for successful messages.
|
||||
function log.success(){
|
||||
local _MESSAGE="${@:-""}"
|
||||
|
||||
[ -z "${_MESSAGE:-""}" ] \
|
||||
&& base.printWithColor LIGHTGREEN "SUCCESS!\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
base.printWithColor LIGHTGREEN "SUCCESS!\n" >&2 \
|
||||
&& base.printWithColor WHITE " ${_MESSAGE}\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Function, for tips.
|
||||
function log.tip(){
|
||||
local _MESSAGE="${1:?"log.tip(): Missing first parameter MESSAGE."}"
|
||||
|
||||
base.printWithColor CYAN "TIP:\n" >&2
|
||||
while [ "${_MESSAGE:-""}" != "" ]; do
|
||||
base.printWithColor LIGHTGREY " ${_MESSAGE}\n" >&2 \
|
||||
&& shift \
|
||||
&& _MESSAGE="${1:-""}" \
|
||||
&& continue
|
||||
return 1
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#Function, for warnings.
|
||||
function log.warn(){
|
||||
local _MESSAGE="${@:?"log.warn(): Missing first parameter MESSAGE."}"
|
||||
|
||||
base.printWithColor YELLOW "WARNING:\n" >&2 \
|
||||
&& base.printWithColor WHITE " ${_MESSAGE}\n" >&2 \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Check if this module was started correctly using source
|
||||
if [ "${BASH_SOURCE[0]}" == "${0}" ]; then
|
||||
# Script was executed directly
|
||||
echo "FAILURE: you are using this module 'log.module.sh' in a wrong way."
|
||||
echo " It is intended as a utility library and should not be called directly."
|
||||
echo
|
||||
echo "Usage: Call this module at the beginning of your script e.g. like this:"
|
||||
echo
|
||||
echo ' #!/bin/bash'
|
||||
echo ' source /cis/core/base.module.sh'
|
||||
echo
|
||||
echo ' #Loads this module'
|
||||
echo ' base.loadModule log'
|
||||
echo
|
||||
echo "Now you can use the functions provided by this module inside your script:"
|
||||
echo "-------------------------------------------------------------------------"
|
||||
declare -F | grep "log." | cut -d" " -f3
|
||||
exit 1
|
||||
fi
|
||||
@@ -5,10 +5,45 @@
|
||||
&& echo "so this script is allowed to be executed if you are root only." \
|
||||
&& exit 1
|
||||
|
||||
function goOn() {
|
||||
local _QUESTION="${1:?"goOn(): Mising first parameter QUESTION"}"
|
||||
local _TIPP="${2}"
|
||||
local _ANSWER
|
||||
|
||||
read -p "${_QUESTION}: [y]es or [n]o : " _ANSWER
|
||||
[ "${_ANSWER}" == "y" ] && return 0
|
||||
[ "${_ANSWER}" == "Y" ] && return 0
|
||||
[ "${_ANSWER}" == "yes" ] && return 0
|
||||
[ "${_ANSWER}" == "Yes" ] && return 0
|
||||
[ "${_ANSWER}" == "YES" ] && return 0
|
||||
|
||||
echo
|
||||
echo "${_TIPP}"
|
||||
echo
|
||||
return 1
|
||||
}
|
||||
|
||||
function setNeededHostnameOrExit() {
|
||||
_FQDN="${1:?"Missing unique long hostname (fqdn, eg.: host1.example.net) for this host as first parameter."}"
|
||||
_FQDN="${1}"
|
||||
|
||||
[ -z "${_FQDN}" ] \
|
||||
&& ! echo "$(hostname -b)" | grep -q -F '.' \
|
||||
&& echo "This host needs a unique long hostname (fqdn, eg.: host1.example.net)" \
|
||||
&& echo "Call this script with a full qualified domain name as first parameter." \
|
||||
&& exit 1
|
||||
|
||||
[ -z "${_FQDN}" ] \
|
||||
&& echo "$(hostname -b)" | grep -q -F '.' \
|
||||
&& echo "The name of this host is: $(hostname -b)" \
|
||||
&& goOn "Is this correct?" "Restart this script with a full qualified domain name as first parameter." \
|
||||
&& return 0
|
||||
|
||||
[ "${_FQDN}" == "$(hostname -b)" ] \
|
||||
&& echo "Name of this host already is: $(hostname -b)" \
|
||||
&& return 0
|
||||
|
||||
echo "${_FQDN}" | grep -F '.' &> /dev/null \
|
||||
&& "Setting name of this host to: ${_FQDN}" \
|
||||
&& hostnamectl set-hostname "${_FQDN}" \
|
||||
&& return 0
|
||||
|
||||
@@ -17,12 +52,16 @@ function setNeededHostnameOrExit() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
function printOrGenerateSSHKeysForRoot() {
|
||||
function printOrGenerateSSHKeys() {
|
||||
git --version > /dev/null || (apt update; apt upgrade -y; apt install git)
|
||||
|
||||
local _FULL_USERNAME="$(whoami)@$(hostname -b)"
|
||||
local _PUBKEY_FILE=~/.ssh/id_ed25519.pub
|
||||
|
||||
echo
|
||||
echo "Public SSH-Key for root@$(hostname -b):"
|
||||
cat "/root/.ssh/id_ed25519.pub" \
|
||||
echo "Printing public SSH-Key of ${_FULL_USERNAME}:"
|
||||
echo " - Content of '${_PUBKEY_FILE}':"
|
||||
cat "${_PUBKEY_FILE}" \
|
||||
&& return 0
|
||||
|
||||
# -t type of the key pair
|
||||
@@ -32,19 +71,19 @@ function printOrGenerateSSHKeysForRoot() {
|
||||
# -C defines a comment
|
||||
ssh-keygen \
|
||||
-t ed25519 \
|
||||
-f "/root/.ssh/id_ed25519" -q -N "" \
|
||||
-C "$(date +%Y%m%d)-root@$(hostname -b)"
|
||||
-f "${_PUBKEY_FILE}" -q -N "" \
|
||||
-C "$(date +%Y%m%d)-${_FULL_USERNAME}"
|
||||
|
||||
cat "/root/.ssh/id_ed25519.pub" \
|
||||
cat "${_PUBKEY_FILE}" \
|
||||
&& return 0
|
||||
|
||||
echo
|
||||
echo "FAILED: somthing went wrong during the generation the ssh keys."
|
||||
echo "FAILED: somthing went wrong during the generation the ssh keys for '${_FULL_USERNAME}'."
|
||||
echo " These keys are mandantory. You can try to restart this script."
|
||||
echo
|
||||
}
|
||||
|
||||
function showFurtherSteps() {}
|
||||
function showFurtherSteps() {
|
||||
echo
|
||||
echo "IMPORTANT: It is assumed that repositories for definitions and states already exist"
|
||||
echo " and comply with the naming convention."
|
||||
@@ -66,7 +105,7 @@ function showFurtherSteps() {}
|
||||
|
||||
# sanitizes all parameters
|
||||
setNeededHostnameOrExit "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \
|
||||
&& printOrGenerateSSHKeysForRoot \
|
||||
&& printOrGenerateSSHKeys \
|
||||
&& showFurtherSteps \
|
||||
&& exit 0
|
||||
|
||||
|
||||
+38
-63
@@ -1,4 +1,7 @@
|
||||
#!/bin/bash
|
||||
source ${CUSTOM_CIS_ROOT:-/}./cis/core/base.module.sh
|
||||
|
||||
|
||||
|
||||
[ "$(id -u)" != "0" ] \
|
||||
&& sudo "${0}" "${1}" \
|
||||
@@ -6,13 +9,6 @@
|
||||
|
||||
|
||||
|
||||
# Folders always ends with an tailing '/'
|
||||
_SETUP="$(readlink -f "${0}" 2> /dev/null)"
|
||||
_CIS_ROOT="${_SETUP%/setupCoreOntoThisHost.sh}/" #Removes shortest matching pattern '/setupCoreOntoThisHost.sh' from the end
|
||||
_CORE_SCRIPTS="${_CIS_ROOT:?"Missing CIS_ROOT"}core/"
|
||||
|
||||
|
||||
|
||||
function checkPathsAreAvaiable() {
|
||||
grep --version &> /dev/null \
|
||||
&& [ "$(echo ${PATH} | tr ':' '\n' | grep -c /usr/local/sbin)" -ge 1 ] \
|
||||
@@ -51,7 +47,7 @@ function checkPreconditions() {
|
||||
! [ -z "${_DOMAIN}" ] \
|
||||
&& checkPathsAreAvaiable \
|
||||
&& checkGitIsAvailable \
|
||||
&& git -C "${_CIS_ROOT:?"Missing CIS_ROOT"}" pull &> /dev/null \
|
||||
&& git -C "${CIS[ROOT]:?"Missing CIS_ROOT"}" pull &> /dev/null \
|
||||
&& return 0
|
||||
|
||||
echo
|
||||
@@ -75,9 +71,9 @@ function checkPreconditions() {
|
||||
|
||||
function getOrSetDomain() {
|
||||
local _CURRENT_DOMAIN _GIVEN_DOMAIN _OVERRIDE_DOMAIN_FILE
|
||||
_CURRENT_DOMAIN="$("${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}printOwnDomain.sh")"
|
||||
_CURRENT_DOMAIN="${CIS[DOMAIN]:?"Missing CIS_DOMAIN"}"
|
||||
_GIVEN_DOMAIN="${1}" # Optional parameter DOMAIN
|
||||
_OVERRIDE_DOMAIN_FILE="${_CIS_ROOT:?"Missing CIS_ROOT"}overrideOwnDomain"
|
||||
_OVERRIDE_DOMAIN_FILE="${CIS[ROOT]:?"Missing CIS_ROOT"}overrideOwnDomain"
|
||||
readonly _CURRENT_DOMAIN _GIVEN_DOMAIN _OVERRIDE_DOMAIN_FILE
|
||||
|
||||
! [ -z "${_CURRENT_DOMAIN}" ] \
|
||||
@@ -109,8 +105,10 @@ function getOrSetDomain() {
|
||||
}
|
||||
|
||||
function getRemoteRepositoryPath() {
|
||||
_REPOSITORY="$(git -C "${_CIS_ROOT:?"Missing CIS_ROOT"}" config --get remote.origin.url 2> /dev/null | grep -i 'git@')"
|
||||
_PATH="${_REPOSITORY%/*}" #Removes shortest matching pattern '/*' from the end
|
||||
local _REPOSITORY="$(git -C "${CIS[ROOT]:?"Missing CIS_ROOT"}" config --get remote.origin.url 2> /dev/null | grep -i 'git@')"
|
||||
local _PATH="${_REPOSITORY%/*}" #Removes shortest matching pattern '/*' from the end
|
||||
readonly _REPOSITORY _PATH
|
||||
|
||||
! [ -z "${_PATH}" ] \
|
||||
&& echo "${_PATH}/" \
|
||||
&& return 0
|
||||
@@ -119,22 +117,21 @@ function getRemoteRepositoryPath() {
|
||||
}
|
||||
|
||||
function addDefinition(){
|
||||
local _DEFINITIONS _REPOSITORY
|
||||
_DEFINITIONS="${1:?"Missing first parameter DEFINITIONS"}"
|
||||
_REPOSITORY="$(getRemoteRepositoryPath)cis-definition-${2:?"Missing second parameter DOMAIN"}.git"
|
||||
readonly _DEFINITIONS _REPOSITORY
|
||||
local _REPOSITORY
|
||||
_REPOSITORY="$(getRemoteRepositoryPath)cis-definition-${CIS[DOMAIN]}.git"
|
||||
readonly _REPOSITORY
|
||||
|
||||
[ "$(id -u)" == "0" ] \
|
||||
&& echo \
|
||||
&& echo "Running setup as 'root' trying to add definition repository:" \
|
||||
&& "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}addAndCheckGitRepository.sh" "${_DEFINITIONS}" readonly "${_REPOSITORY}" \
|
||||
&& "${CIS[COREROOT]:?"Missing CORE_SCRIPTS"}addAndCheckGitRepository.sh" "${CIS[DOMAINDEFINITIONS]}" readonly "${_REPOSITORY}" \
|
||||
&& echo " - definitions are usable for this host." \
|
||||
&& return 0
|
||||
|
||||
[ "$(id -u)" != "0" ] \
|
||||
&& echo \
|
||||
&& echo "Running setup as 'user' trying to add definition repository:" \
|
||||
&& "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}addAndCheckGitRepository.sh" "${_DEFINITIONS}" writable "${_REPOSITORY}" \
|
||||
&& "${CIS[COREROOT]:?"Missing CORE_SCRIPTS"}addAndCheckGitRepository.sh" "${CIS[DOMAINDEFINITIONS]}" writable "${_REPOSITORY}" \
|
||||
&& echo " - definitions are usable, as working copy." \
|
||||
&& return 0
|
||||
|
||||
@@ -142,22 +139,21 @@ function addDefinition(){
|
||||
}
|
||||
|
||||
function addState() {
|
||||
local _STATES _REPOSITORY
|
||||
_STATES="${1:?"Missing first parameter STATES"}"
|
||||
_REPOSITORY="$(getRemoteRepositoryPath)cis-state-${2:?"Missing second parameter DOMAIN"}.git"
|
||||
readonly _STATES _REPOSITORY
|
||||
local _REPOSITORY
|
||||
_REPOSITORY="$(getRemoteRepositoryPath)cis-state-${CIS[DOMAIN]}.git"
|
||||
readonly _REPOSITORY
|
||||
|
||||
[ "$(id -u)" == "0" ] \
|
||||
&& echo \
|
||||
&& echo "Running setup as 'root' trying to add state repository:" \
|
||||
&& "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}addAndCheckGitRepository.sh" "${_STATES}" writable "${_REPOSITORY}" \
|
||||
&& "${CIS[COREROOT]:?"Missing CORE_SCRIPTS"}addAndCheckGitRepository.sh" "${CIS[DOMAINSTATES]}" writable "${_REPOSITORY}" \
|
||||
&& echo " - states are usable for this host." \
|
||||
&& return 0
|
||||
|
||||
[ "$(id -u)" != "0" ] \
|
||||
&& echo \
|
||||
&& echo "Running setup as 'user' trying to add state repository:" \
|
||||
&& "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}addAndCheckGitRepository.sh" "${_STATES}" writable "${_REPOSITORY}" \
|
||||
&& "${CIS[COREROOT]:?"Missing CORE_SCRIPTS"}addAndCheckGitRepository.sh" "${CIS[DOMAINSTATES]}" writable "${_REPOSITORY}" \
|
||||
&& echo " - states are usable, as working copy." \
|
||||
&& return 0
|
||||
|
||||
@@ -165,10 +161,9 @@ function addState() {
|
||||
}
|
||||
|
||||
function setupCoreFunctionality() {
|
||||
local _DEFINITIONS _MINUTE_FROM_OWN_IP
|
||||
_DEFINITIONS="${1:?"Missing DEFINITIONS: 'ROOT/definitions/DOMAIN'"}"
|
||||
local _MINUTE_FROM_OWN_IP
|
||||
_MINUTE_FROM_OWN_IP="$(hostname -I | xargs -n 1 | grep -F '.' | head -n 1 | cut -d. -f4 || echo 0)" #uses last value from first own ipv4 or 0 as minute value
|
||||
readonly _DEFINITIONS _MINUTE_FROM_OWN_IP
|
||||
readonly _MINUTE_FROM_OWN_IP
|
||||
|
||||
[ "$(id -u)" != "0" ] \
|
||||
&& echo \
|
||||
@@ -177,38 +172,34 @@ function setupCoreFunctionality() {
|
||||
|
||||
[ "$(id -u)" == "0" ] \
|
||||
&& echo \
|
||||
&& echo "Using definitions: '${_DEFINITIONS:?"Missing DEFINITIONS"}' ..." \
|
||||
&& echo "Using definitions: '${CIS[DOMAINDEFINITIONS]:?"Missing DEFINITIONS"}' ..." \
|
||||
&& echo \
|
||||
&& "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}defineAuthorizedKeysOfUser.sh" "${_DEFINITIONS}" root \
|
||||
&& "${CIS[COREROOT]:?"Missing CORE_SCRIPTS"}defineAuthorizedKeysOfUser.sh" "${CIS[DOMAINDEFINITIONS]}" root \
|
||||
&& echo \
|
||||
&& "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}ensureUsageOfDefinitions.sh" "${_DEFINITIONS}" /etc/adduser.conf \
|
||||
&& "${CIS[COREROOT]:?"Missing CORE_SCRIPTS"}ensureUsageOfDefinitions.sh" "${CIS[DOMAINDEFINITIONS]}" /etc/adduser.conf \
|
||||
&& echo \
|
||||
&& "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}addNormalUser.sh" jenkins \
|
||||
&& "${CIS[COREROOT]:?"Missing CORE_SCRIPTS"}addNormalUser.sh" jenkins \
|
||||
&& echo \
|
||||
&& "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}defineAuthorizedKeysOfUser.sh" "${_DEFINITIONS}" jenkins \
|
||||
&& "${CIS[COREROOT]:?"Missing CORE_SCRIPTS"}defineAuthorizedKeysOfUser.sh" "${CIS[DOMAINDEFINITIONS]}" jenkins \
|
||||
&& echo \
|
||||
&& "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}ensureUsageOfDefinitions.sh" "${_DEFINITIONS}" /etc/sudoers.d/allow-jenkins-updateRepositories \
|
||||
&& "${CIS[COREROOT]:?"Missing CORE_SCRIPTS"}ensureUsageOfDefinitions.sh" "${CIS[DOMAINDEFINITIONS]}" /etc/sudoers.d/allow-jenkins-updateRepositories \
|
||||
&& echo \
|
||||
&& "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}addToCrontabEveryHour.sh" "${_SETUP:?"Missing SETUP"}" "${_MINUTE_FROM_OWN_IP}" \
|
||||
&& "${CIS[COREROOT]:?"Missing CORE_SCRIPTS"}addToCrontabEveryHour.sh" "${CIS[FULLSCRIPTNAME]:?"Missing FULLSCRIPTNAME"}" "${_MINUTE_FROM_OWN_IP}" \
|
||||
&& return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function setup() {
|
||||
local _DEFINITIONS _DOMAIN _STATES
|
||||
_DOMAIN="$(getOrSetDomain "${1}")"
|
||||
local _DOMAIN="$(getOrSetDomain "${1}")"
|
||||
readonly _DOMAIN
|
||||
|
||||
! checkPreconditions "${_DOMAIN}" \
|
||||
&& return 1
|
||||
|
||||
_DEFINITIONS="${_CIS_ROOT:?"Missing CIS_ROOT"}definitions/${_DOMAIN:?"Missing DOMAIN"}"
|
||||
_STATES="${_CIS_ROOT:?"Missing CIS_ROOT"}states/${_DOMAIN:?"Missing DOMAIN"}"
|
||||
readonly _DEFINITIONS _DOMAIN _STATES
|
||||
|
||||
addDefinition "${_DEFINITIONS:?"Missing DEFINITIONS"}" "${_DOMAIN:?"Missing DOMAIN"}" \
|
||||
&& addState "${_STATES:?"Missing STATES"}" "${_DOMAIN:?"Missing DOMAIN"}" \
|
||||
&& setupCoreFunctionality "${_DEFINITIONS:?"Missing DEFINITIONS"}" \
|
||||
addDefinition \
|
||||
&& addState \
|
||||
&& setupCoreFunctionality \
|
||||
&& return 0
|
||||
|
||||
echo "FAIL: setup is incomplete: ("$(readlink -f ${0})")" >&2
|
||||
@@ -216,27 +207,11 @@ function setup() {
|
||||
return 1
|
||||
}
|
||||
|
||||
function isValid() {
|
||||
# printf '%s'
|
||||
# - always treats the contents of ${1} as pure plain text.
|
||||
# grep -qE: checks RegExp, but quiet
|
||||
printf '%s' "${1}" | grep -qE "${2:?"isValid(): Missing REGEXP"}"
|
||||
}
|
||||
|
||||
function isValidOptional() {
|
||||
[ -z "${1}" ] || isValid "${1}" "${2}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Parameter 1: Only alphanumeric characters allowed and [.-] if not leading (due to: -oProxyCommand=...).
|
||||
if isValidOptional "${1}" '^[a-zA-Z0-9][a-zA-Z0-9.-]*$'
|
||||
then
|
||||
setup "${1}" \
|
||||
&& exit 0
|
||||
else
|
||||
echo "Failure: At least one parameter is invalid" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Parameter 1: is optional '()?' and only alphanumeric characters are allowed and [.-] if not leading (due to: -oProxyCommand=...).
|
||||
base.set DOMAIN "${1}" '^([a-zA-Z0-9][a-zA-Z0-9.-]*)?$' || exit 1
|
||||
setup "${DOMAIN}" \
|
||||
&& exit 0
|
||||
|
||||
exit 1
|
||||
|
||||
+26
-45
@@ -1,4 +1,7 @@
|
||||
#!/bin/bash
|
||||
source /cis/core/base.module.sh
|
||||
|
||||
|
||||
|
||||
# No write permission, but terminal => restart as root using sudo, user jenkins can do this without password
|
||||
! [ -w "${0}" ] \
|
||||
@@ -14,58 +17,52 @@
|
||||
|
||||
# Still no write permission => was not called as root
|
||||
! [ -w "${0}" ] \
|
||||
&& echo "Host $HOSTNAME: insufficient rights." \
|
||||
&& echo "Host ${CIS[HOST]:?"Missing HOST"}: insufficient rights." \
|
||||
&& exit 1
|
||||
|
||||
|
||||
|
||||
function update_repositories() {
|
||||
local _CIS_ROOT _DEFINITIONS _DOMAIN _MODE _STATES _UPDATE_REPOSITORIES
|
||||
_UPDATE_REPOSITORIES="$(readlink -f "${0}" 2> /dev/null)"
|
||||
_CIS_ROOT="${_UPDATE_REPOSITORIES%/updateRepositories.sh}/" #Removes shortest matching pattern '/updateRepositories.sh' from the end
|
||||
_MODE="${1:-"--core"}"
|
||||
_DOMAIN="$(${_CIS_ROOT:?"Missing CIS_ROOT"}core/printOwnDomain.sh)"
|
||||
_DEFINITIONS="${_CIS_ROOT}definitions/${_DOMAIN:?"Missing DOMAIN from file: ${_CIS_ROOT}domainOfHostOwner"}/"
|
||||
_STATES="${_CIS_ROOT}states/${_DOMAIN:?"Missing DOMAIN from file: ${_CIS_ROOT}domainOfHostOwner"}/"
|
||||
readonly _CIS_ROOT _DEFINITIONS _DOMAIN _MODE _STATES _UPDATE_REPOSITORIES
|
||||
local _MODE="${1:-"--core"}"
|
||||
readonly _MODE
|
||||
|
||||
[ "${_MODE}" == "--repair" ] \
|
||||
&& (git -C "${_CIS_ROOT}" reset --hard origin/main; \
|
||||
git -C "${_DEFINITIONS}" reset --hard origin/main; \
|
||||
git -C "${_STATES}" reset --hard origin/main; \
|
||||
&& (git -C "${CIS[ROOT]:?"Missing CISROOT"}" reset --hard origin/main; \
|
||||
git -C "${CIS[DOMAINDEFINITIONS]:?"Missing DEFINITIONS"}" reset --hard origin/main; \
|
||||
git -C "${CIS[DOMAINSTATES]:?"Missing STATES"}" reset --hard origin/main; \
|
||||
echo "Run repairs") \
|
||||
&& return 0
|
||||
|
||||
[ "${_MODE}" == "--test" ] \
|
||||
&& git -C "${_CIS_ROOT}" pull \
|
||||
&& git -C "${_DEFINITIONS}" pull \
|
||||
&& git -C "${_STATES}" pull \
|
||||
&& git -C "${CIS[ROOT]:?"Missing CISROOT"}" pull \
|
||||
&& git -C "${CIS[DOMAINDEFINITIONS]:?"Missing DEFINITIONS"}" pull \
|
||||
&& git -C "${CIS[DOMAINSTATES]:?"Missing STATES"}" pull \
|
||||
&& echo "Run in testMode successfully." \
|
||||
&& return 0
|
||||
|
||||
[ "${_MODE}" == "--scripts" ] \
|
||||
&& printf "Host $HOSTNAME updating scripts: ${_CIS_ROOT} ... " \
|
||||
&& (git -C "${_CIS_ROOT}" pull &> /dev/null) \
|
||||
&& printf "Host $HOSTNAME updating scripts: ${CIS[ROOT]:?"Missing CISROOT"} ... " \
|
||||
&& (git -C "${CIS[ROOT]:?"Missing CISROOT"}" pull &> /dev/null) \
|
||||
&& echo "(done)" \
|
||||
&& return 0
|
||||
|
||||
[ "${_MODE}" == "--definitions" ] \
|
||||
&& echo "Host ${HOSTNAME} updating definitions: ${_DEFINITIONS} ... " \
|
||||
&& (git -C "${_DEFINITIONS}" pull &> /dev/null) \
|
||||
&& printf "Host ${HOSTNAME} updating definitions: ${CIS[DOMAINDEFINITIONS]:?"Missing DEFINITIONS"} ... " \
|
||||
&& (git -C "${CIS[DOMAINDEFINITIONS]:?"Missing DEFINITIONS"}" pull &> /dev/null) \
|
||||
&& echo "(done)" \
|
||||
&& return 0
|
||||
|
||||
[ "${_MODE}" == "--states" ] \
|
||||
&& echo "Host ${HOSTNAME} updating states: ${_STATES} ... " \
|
||||
&& (git -C "${_STATES}" pull &> /dev/null) \
|
||||
&& printf "Host ${HOSTNAME} updating states: ${CIS[DOMAINSTATES]:?"Missing STATES"} ... " \
|
||||
&& (git -C "${CIS[DOMAINSTATES]:?"Missing STATES"}" pull &> /dev/null) \
|
||||
&& echo "(done)" \
|
||||
&& return 0
|
||||
|
||||
[ "${_MODE}" == "--core" ] \
|
||||
&& echo "Host ${HOSTNAME} updating core including scripts, definitions and states: ${_STATES} ... " \
|
||||
&& (git -C "${_CIS_ROOT}" pull &> /dev/null) \
|
||||
&& (git -C "${_DEFINITIONS}" pull &> /dev/null) \
|
||||
&& (git -C "${_STATES}" pull &> /dev/null) \
|
||||
&& printf "Host ${HOSTNAME} updating core including scripts, definitions and states ... " \
|
||||
&& (git -C "${CIS[ROOT]:?"Missing CISROOT"}" pull &> /dev/null) \
|
||||
&& (git -C "${CIS[DOMAINDEFINITIONS]:?"Missing DEFINITIONS"}" pull &> /dev/null) \
|
||||
&& (git -C "${CIS[DOMAINSTATES]:?"Missing STATES"}" pull &> /dev/null) \
|
||||
&& echo "(done)" \
|
||||
&& return 0
|
||||
|
||||
@@ -73,27 +70,11 @@ function update_repositories() {
|
||||
return 1
|
||||
}
|
||||
|
||||
function isValid() {
|
||||
# printf '%s'
|
||||
# - always treats the contents of ${1} as pure plain text.
|
||||
# grep -qE: checks RegExp, but quiet
|
||||
printf '%s' "${1}" | grep -qE "${2:?"isValid(): Missing REGEXP"}"
|
||||
}
|
||||
|
||||
function isValidOptional() {
|
||||
[ -z "${1}" ] || isValid "${1}" "${2}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Parameter 1: Only one of these values are allowed (--core, --definitions, --repair, --scripts, --states, --test)
|
||||
if isValidOptional "${1}" '^(--core|--definitions|--repair|--scripts|--states|--test)$'
|
||||
then
|
||||
update_repositories "${1}" \
|
||||
&& exit 0
|
||||
else
|
||||
echo "Failure: At least one parameter is invalid" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Parameter 1: Only one of these values are allowed, or empty (--core, --definitions, --repair, --scripts, --states, --test)?
|
||||
base.set MODE "${1}" '^(--core|--definitions|--repair|--scripts|--states|--test)?$' || exit 1
|
||||
update_repositories "${MODE}" \
|
||||
&& exit 0
|
||||
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user