diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34a2b94 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Ignore the file '/domainOfHostOwner' because this is per host individually. +/domainOfHostOwner + +# Ignore the subfolders only, because their content are other git repositories. +# But 'definitions and 'states' should be prepared by cloning this repository. +/definitions/*/ +/states/*/ + +# Ignore environment files +.env diff --git a/README.md b/README.md index 5eb5fea..8b6d0f9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -Infrastructure System (ISS) -=========================== +Core Infrastructure System (CIS) +================================ Setup a new host ---------------- @@ -52,20 +52,20 @@ We use the modern ed25519 keys, so the public key of root is stored at this loca ### Register public host key This is an example for `example.net` as domain of the host owner. -1. Repository `iss`, allow __readonly__ access only. -2. Repository `iss-definition-example.net`, allow __readonly__ access only. -3. Repository `iss-state-example.net`, allow __writable__ access. +1. Repository `cis`, allow __readonly__ access only. +2. Repository `cis-definition-example.net`, allow __readonly__ access only. +3. Repository `cis-state-example.net`, allow __writable__ access. -### Clone the Infrastructure System (iss) repository +### Clone the Infrastructure System (cis) repository After you registered the printed root's public key of this host you can clone the repository and execute the setup script: ```sh -# Note the tailing '/iss', because we want to clone the repository to that folder -git clone ssh://git@git.example.dev:22448/iss.git /iss +# Note the tailing '/cis', because we want to clone the repository to that folder +git clone ssh://git@git.example.dev:22448/cis.git /cis # Execute the setup script -/iss/setupCoreOntoThisHost.sh +/cis/setupCoreOntoThisHost.sh ```
@@ -74,7 +74,7 @@ git clone ssh://git@git.example.dev:22448/iss.git /iss How it works ------------ -We add a webhook to each gitea repository that belongs to ISS: +We add a webhook to each gitea repository that belongs to CIS: - __Taget URL:__ https://YOUR.JENKINS.DOMAIN/generic-webhook-trigger/invoke?token=YOUR_TOKEN - __HTTP-Method:__ POST - __Trigger On:__ Push Events @@ -98,7 +98,7 @@ cat "${JENKINS_HOME}/.ssh/id_ed25519.pub" \ && cat "${JENKINS_HOME}/.ssh/id_ed25519.pub") # add your host here, note the tailing '&' to run it in parallel -ssh -o StrictHostKeyChecking=no jenkins@192.168.X.Y /iss/update_repositories.sh ( --scripts | --definitions | --states ) & +ssh -o StrictHostKeyChecking=no jenkins@192.168.X.Y /cis/update_repositories.sh ( --scripts | --definitions | --states ) & #wait for all background processes to complete wait diff --git a/core/addAndCheckGitRepository.sh b/core/addAndCheckGitRepository.sh index 8c5ab80..007beed 100755 --- a/core/addAndCheckGitRepository.sh +++ b/core/addAndCheckGitRepository.sh @@ -73,7 +73,7 @@ function cloneOrPull { function addAndCheckGitRepository() { local _FOLDER _REPOSITORY _FOLDER="${1:?"Missing first parameter FOLDER"}" - _REPOSITORY="${2:?"Missing second parameter REPOSITORY: e.g. ssh://git@your.domain.com/iss.git "}" + _REPOSITORY="${2:?"Missing second parameter REPOSITORY: e.g. ssh://git@your.domain.com/cis.git "}" _RIGHTS="${3:?"Missing third parameter RIGHTS: (readonly, writable) "}" readonly _FOLDER _REPOSITORY @@ -98,4 +98,6 @@ addAndCheckGitRepository \ "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ "$(echo ${2} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ "$(echo ${3} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ - && exit 0 || exit 1 + && exit 0 + +exit 1 diff --git a/core/addNormalUser.sh b/core/addNormalUser.sh index 04716c1..aed58d9 100755 --- a/core/addNormalUser.sh +++ b/core/addNormalUser.sh @@ -34,6 +34,7 @@ function addNormalUser() { } # sanitizes all parameters -addNormalUser \ - "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ - && exit 0 || exit 1 +addNormalUser "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ + && exit 0 + +exit 1 diff --git a/core/addToCrontabEveryHour.sh b/core/addToCrontabEveryHour.sh index 492ad14..cb6832a 100755 --- a/core/addToCrontabEveryHour.sh +++ b/core/addToCrontabEveryHour.sh @@ -8,11 +8,11 @@ # Note that an unprivileged user can use this script successfully, # if no user has to be added to the host because it already exists. function addToCrontabEveryHour() { - local _ROOT _MINUTE_VALUE _STRING - _ROOT="${0%%/core/*}/" #Removes longest matching pattern '/core/*' from the end + local _CIS_ROOT _MINUTE_VALUE _STRING + _CIS_ROOT="${0%%/core/*}/" #Removes longest matching pattern '/core/*' from the end ! [ -z "${2##*[!0-9]*}" ] && _MINUTE_VALUE=$((${2}%60)) # if second parameter is integer then (minute-value % 60) as safe guard _STRING="${_MINUTE_VALUE:?"Missing MINUTE_VALUE"} * * * * ${1:?"Missing first parameter COMMAND"} > /dev/null 2>&1" - readonly _ROOT _MINUTE_VALUE _STRING + readonly _CIS_ROOT _MINUTE_VALUE _STRING [ "$(id -u)" == "0" ] \ && crontab -l | grep -qF "${_STRING:?"Missing CRON_STRING"}" \ @@ -21,11 +21,11 @@ function addToCrontabEveryHour() { && return 0 [ "$(id -u)" == "0" ] \ - && echo "${_ROOT:?"Missing ROOT"}" | grep "home" &> /dev/null \ + && echo "${_CIS_ROOT:?"Missing CIS_ROOT"}" | grep "home" &> /dev/null \ && echo "SUCCESS: Although the entry will be skipped: ("$(readlink -f ${0})")" \ && echo " - '${_STRING}'" \ && echo " that is because the current environment is:" \ - && echo " - ${_ROOT}" \ + && echo " - ${_CIS_ROOT}" \ && return 0 [ "$(id -u)" == "0" ] \ @@ -47,4 +47,6 @@ function addToCrontabEveryHour() { addToCrontabEveryHour \ "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ "$(echo ${2} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ - && exit 0 || exit 1 + && exit 0 + +exit 1 diff --git a/core/defineAuthorizedKeysOfUser.sh b/core/defineAuthorizedKeysOfUser.sh index 68b318e..16705e7 100755 --- a/core/defineAuthorizedKeysOfUser.sh +++ b/core/defineAuthorizedKeysOfUser.sh @@ -51,17 +51,17 @@ function prepareFolder() { } function defineAuthorizedKeysOfUser() { - local _ROOT _CORE_SCRIPTS _DOMAIN _DEFINITIONS _USER + local _CIS_ROOT _CORE_SCRIPTS _DOMAIN _DEFINITIONS _USER _DEFINITIONS="$(realpath -s "${1:?"Missing first parameter DEFINITIONS: 'ROOT/definitions/DOMAIN'"}")" - _ROOT="${_DEFINITIONS%%/definitions/*}/" #Removes longest matching pattern '/definitions/*' from the end - _DOMAIN="${_DEFINITIONS##*/definitions/}" #Removes longest matching pattern '*/definitions/' from the begin - _DOMAIN="${_DOMAIN%/}" #Removes shortest matching pattern '/' from the end + _CIS_ROOT="${_DEFINITIONS%%/definitions/*}/" #Removes longest matching pattern '/definitions/*' from the end + _DOMAIN="${_DEFINITIONS##*/definitions/}" #Removes longest matching pattern '*/definitions/' from the begin + _DOMAIN="${_DOMAIN%/}" #Removes shortest matching pattern '/' from the end #Build from components for safety - _DEFINITIONS="${_ROOT:?"Missing ROOT"}definitions/${_DOMAIN:?"Missing DOMAIN"}" + _DEFINITIONS="${_CIS_ROOT:?"Missing ROOT"}definitions/${_DOMAIN:?"Missing DOMAIN"}" _USER="${2:?"Missing second parameter USER"}" - _CORE_SCRIPTS="${_ROOT:?"Missing ROOT"}core/" - readonly _ROOT _CORE_SCRIPTS _DOMAIN _DEFINITIONS _USER + _CORE_SCRIPTS="${_CIS_ROOT:?"Missing ROOT"}core/" + readonly _CIS_ROOT _CORE_SCRIPTS _DOMAIN _DEFINITIONS _USER case "${_USER:?"Missing USER"}" in root) @@ -83,4 +83,6 @@ function defineAuthorizedKeysOfUser() { defineAuthorizedKeysOfUser \ "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ "$(echo ${2} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ - && exit 0 || exit 1 + && exit 0 + +exit 1 diff --git a/core/ensureUsageOfDefinitions.sh b/core/ensureUsageOfDefinitions.sh index f9b53b1..535c6ba 100755 --- a/core/ensureUsageOfDefinitions.sh +++ b/core/ensureUsageOfDefinitions.sh @@ -24,6 +24,28 @@ function isCoreDefinition() { return 1 } +function filterInvalidAuthorizedKeysFilesOfRoot() { + local _FILE_DEFINED + _FILE_DEFINED="${1:?"Missing DEFINITION FILE"}" + readonly _FILE_DEFINED + + #If the full filename contains 'root/.ssh/authorized_keys' then check the content. + #Skip lines starting with '#' and if at least one remaining line contains 'ssh' and '@' then print the filename. + echo "${_FILE_DEFINED}" | grep -F 'root/.ssh/authorized_keys' &> /dev/null \ + && grep -vE '^[[:blank:]]*#' "${_FILE_DEFINED}" | grep -F 'ssh' | grep -F '@' &> /dev/null \ + && echo "${_FILE_DEFINED}" \ + && return 0 + + #If the full filename contains 'root/.ssh/authorized_keys' print nothing because the file has to be invalid. + echo "${_FILE_DEFINED}" | grep -F 'root/.ssh/authorized_keys' &> /dev/null \ + && echo \ + && return 0 + + #Print the full filename because it does not contain 'root/.ssh/authorized_keys' + echo "${_FILE_DEFINED}" + return 0 +} + function printSelectedDefinition() { local _CORE_FILE_DEFINED_ALL_HOSTS _CORE_FILE_DEFINED_THIS_HOST _FILE_DEFINED_ALL_HOSTS _FILE_DEFINED_THIS_HOST _CORE_FILE_DEFINED_ALL_HOSTS="${1:?"Missing DEFINITIONS"}/core/all${2:?"Missing CURRENT_FULLFILE"}" @@ -36,13 +58,13 @@ function printSelectedDefinition() { #Try this host first because it should be priorized. isCoreDefinition "${2:?"Missing CURRENT_FULLFILE"}" \ && [ -s "${_CORE_FILE_DEFINED_THIS_HOST}" ] \ - && echo "${_CORE_FILE_DEFINED_THIS_HOST}" \ + && filterInvalidAuthorizedKeysFiles "${_CORE_FILE_DEFINED_THIS_HOST}" \ && return 0 #The following are special definitions that affect the core functionality. isCoreDefinition "${2:?"Missing CURRENT_FULLFILE"}" \ && [ -s "${_CORE_FILE_DEFINED_ALL_HOSTS}" ] \ - && echo "${_CORE_FILE_DEFINED_ALL_HOSTS}" \ + && filterInvalidAuthorizedKeysFiles "${_CORE_FILE_DEFINED_ALL_HOSTS}" \ && return 0 #Try this host first because it should be priorized. @@ -71,11 +93,6 @@ function createSymlinkToDefinition() { && [ "$(sha256sum "${_DEFINED_FULLFILE}" | cut -d' ' -f1)" == "$(sha256sum "${_CURRENT_FULLFILE}" | cut -d' ' -f1)" ] \ && echo "The content of the current file already matches the definition, but it will be replaced by a symlink..." - [ -f "${_CURRENT_FULLFILE}" ] \ - && [ "$(sha256sum "${_DEFINED_FULLFILE}" | cut -d' ' -f1)" == "$(sha256sum "${_CURRENT_FULLFILE}" | cut -d' ' -f1)" ] \ - && echo "The content of the current file already matches the definition, but it will be replaced by a symlink..." - - [ -f "${_CURRENT_FULLFILE}" ] \ && mv "${_CURRENT_FULLFILE:?"Missing CURRENT_FULLFILE"}" "${_SAVED_FULLFILE:?"Missing SAVED_FULLFILE"}" \ && echo "Current file has been backed up to: '${_SAVED_FULLFILE}'" @@ -92,13 +109,13 @@ function createSymlinkToDefinition() { } function ensureUsageOfDefinitions() { - local _ROOT _CURRENT_FILE _CURRENT_FOLDER _CURRENT_FULLFILE _DEFINITIONS _DOMAIN _DEFINED_FULLFILE _NOW _SAVED_FULLFILE + local _CIS_ROOT _CURRENT_FILE _CURRENT_FOLDER _CURRENT_FULLFILE _DEFINITIONS _DOMAIN _DEFINED_FULLFILE _NOW _SAVED_FULLFILE _DEFINITIONS="$(realpath -s "${1:?"Missing first parameter DEFINITIONS: 'ROOT/definitions/DOMAIN'"}")" - _ROOT="${_DEFINITIONS%%/definitions/*}/" #Removes longest matching pattern '/definitions/*' from the end - _DOMAIN="${_DEFINITIONS##*/definitions/}" #Removes longest matching pattern '*/definitions/' from the begin - _DOMAIN="${_DOMAIN%/}" #Removes shortest matching pattern '/' from the end + _CIS_ROOT="${_DEFINITIONS%%/definitions/*}/" #Removes longest matching pattern '/definitions/*' from the end + _DOMAIN="${_DEFINITIONS##*/definitions/}" #Removes longest matching pattern '*/definitions/' from the begin + _DOMAIN="${_DOMAIN%/}" #Removes shortest matching pattern '/' from the end #Build from components for safety - _DEFINITIONS="$(printIfEqual "${_DEFINITIONS}" "${_ROOT:?"Missing ROOT"}definitions/${_DOMAIN:?"Missing DOMAIN"}")" + _DEFINITIONS="$(printIfEqual "${_DEFINITIONS}" "${_CIS_ROOT:?"Missing ROOT"}definitions/${_DOMAIN:?"Missing DOMAIN"}")" _CURRENT_FOLDER="$(dirname "${2:?"Missing second parameter CURRENT_FULLFILE"}")" @@ -121,7 +138,13 @@ function ensureUsageOfDefinitions() { _DEFINED_FULLFILE="$(printSelectedDefinition "${_DEFINITIONS}" "${_CURRENT_FULLFILE}")" _NOW="$(date +%Y%m%d_%H%M)" _SAVED_FULLFILE="${_CURRENT_FULLFILE}-backup@${_NOW:?"Missing NOW"}" - readonly _ROOT _CURRENT_FILE _CURRENT_FOLDER _CURRENT_FULLFILE _DEFINITIONS _DOMAIN _DEFINED_FULLFILE _NOW _SAVED_FULLFILE + readonly _CIS_ROOT _CURRENT_FILE _CURRENT_FOLDER _CURRENT_FULLFILE _DEFINITIONS _DOMAIN _DEFINED_FULLFILE _NOW _SAVED_FULLFILE + + [ -z "${_DEFINED_FULLFILE}" ] \ + && echo \ + && echo "URGENT WARNING: If an 'authorized_keys' file of root is replaced by an invalid version," \ + && echo " you may lose access to this host!" \ + && echo ! [ -f "${_DEFINED_FULLFILE}" ] \ && echo "FAIL: No definition available for this file: ("$(readlink -f ${0})")" \ @@ -138,11 +161,11 @@ function ensureUsageOfDefinitions() { && echo " - '${_DEFINED_FULLFILE}'" \ && return 0 - echo "${_ROOT:?"Missing ROOT"}" | grep "home" &> /dev/null \ + echo "${_CIS_ROOT:?"Missing CIS_ROOT"}" | grep "home" &> /dev/null \ && echo "SUCCESS: Although this definition will be skipped: ("$(readlink -f ${0})")" \ && echo " - '${_DEFINED_FULLFILE}'" \ && echo " that is because the current environment is:" \ - && echo " - ${_ROOT}" \ + && echo " - ${_CIS_ROOT}" \ && echo " following file is in use:" \ && echo " - $(readlink -f "${_CURRENT_FULLFILE}")" \ && return 0 @@ -174,4 +197,6 @@ function ensureUsageOfDefinitions() { ensureUsageOfDefinitions \ "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ "$(echo ${2} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ - && exit 0 || exit 1 + && exit 0 + +exit 1 diff --git a/prepareDefinitionsRepository.sh b/prepareDefinitionsRepository.sh new file mode 100644 index 0000000..f0c6a94 --- /dev/null +++ b/prepareDefinitionsRepository.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +[ "$(id -u)" == "0" ] \ + && echo "This script prepares the content of the repository for the definitions." \ + && echo "You have run it as root, please run it with a user who has write access to the Git server." \ + && echo \ + && echo "Do not use the SSH key of root for this." \ + && echo \ + && exit 1 + +_BOOT_HOSTNAME="$(hostname -b)" +_BOOT_DOMAIN="${_BOOT_HOSTNAME#*.}" #Removes shortest matching pattern '*.' from the begin to get the domain + +[ -z "${_BOOT_DOMAIN}" ] \ + && echo "It was impossible to find out the domain of this host, please prepare this host first." \ + && exit 1 + +_REOPSITORY_NAME="cis-definition-${_BOOT_DOMAIN}" + + + +#Generate file 'README.md' +mkdir -p /tmp/skeleton/definition +cat << EOF > /tmp/skeleton/definition/README.md +#$_REOPSITORY_NAME + +Central Infrastructure System's definition of domain $_BOOT_DOMAIN +EOF + + + +#Generate sudoers file 'allow-jenkins-updateRepositories' +mkdir -p /tmp/skeleton/definition/core/all/etc/sudoers.d +cat << EOF > /tmp/skeleton/definition/core/all/etc/sudoers.d/allow-jenkins-updateRepositories +Cmnd_Alias C_JENKINS = \\ + /cis/updateRepositories.sh --core, \\ + /cis/updateRepositories.sh --scripts, \\ + /cis/updateRepositories.sh --definitions, \\ + /cis/updateRepositories.sh --states +jenkins ALL = (root) NOPASSWD: C_JENKINS +EOF + + + +#Generate file 'authorized_keys' for user jenkins +mkdir -p /tmp/skeleton/definition/core/all/home/jenkins/.ssh +cat << EOF > /tmp/skeleton/definition/core/all/home/jenkins/.ssh/authorized_keys +#------------------------------------------------------ +# Enter the public ssh key of your jenkins server here. +#------------------------------------------------------ +EOF + + + +#Use current file 'authorized_keys' of root as definition +mkdir -p /tmp/skeleton/definition/core/all/root/.ssh +cp /root/.ssh/authorized_keys /tmp/skeleton/definition/core/all/root/.ssh/authorized_keys + + + +cat << EOF + +The first content for your repository for the definitions of the '$_BOOT_DOMAIN' domain has been created. + +Please create a definition repository. +To follow the naming convention name it '$_REOPSITORY_NAME' + +Go to folder '/tmp/skeleton/definition' and check the content of all 'authorized_keys' files, +correct them if required to prevent losing access to your hosts. + +The public ssh key of your jenkins server has to be added. + +Only now follow the instructions as our git server shows. +For example: + + git init + git checkout -b main + git add . + git commit -m "first core definitions" + git remote add origin ssh://git@git.example.dev:22448/$_REOPSITORY_NAME.git + git push -u origin main + +EOF diff --git a/prepareStatesRepository.sh b/prepareStatesRepository.sh new file mode 100644 index 0000000..622b0fd --- /dev/null +++ b/prepareStatesRepository.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +[ "$(id -u)" == "0" ] \ + && echo "This script prepares the content of the repository for the definitions." \ + && echo "You have run it as root, please run it with a user who has write access to the Git server." \ + && echo \ + && echo "Do not use the SSH key of root for this." \ + && echo \ + && exit 1 + +_BOOT_HOSTNAME="$(hostname -b)" +_BOOT_DOMAIN="${_BOOT_HOSTNAME#*.}" #Removes shortest matching pattern '*.' from the begin to get the domain + +[ -z "${_BOOT_DOMAIN}" ] \ + && echo "It was impossible to find out the domain of this host, please prepare this host first." \ + && exit 1 + +_REOPSITORY_NAME="cis-state-${_BOOT_DOMAIN}" + + + +#Generate README.md +mkdir -p /tmp/skeleton/state +cat << EOF > /tmp/skeleton/state/README.md +#$_REOPSITORY_NAME + +Central Infrastructure System's state of domain $_BOOT_DOMAIN +EOF + + + +cat << EOF + +The first content for your repository for the state of the '$_BOOT_DOMAIN' domain has been created. + +Please create a states repository. +To follow the naming convention name it '$_REOPSITORY_NAME' + +Then go to folder '/tmp/skeleton/state' and follow the instructions as your git server shows. +For example: + + git init + git checkout -b main + git add . + git commit -m "first state" + git remote add origin ssh://git@git.example.dev:22448/$_REOPSITORY_NAME.git + git push -u origin main + +EOF diff --git a/preparationBeforeCloning.sh b/prepareThisHostBeforeCloning.sh old mode 100755 new mode 100644 similarity index 53% rename from preparationBeforeCloning.sh rename to prepareThisHostBeforeCloning.sh index 74d60b4..addeebf --- a/preparationBeforeCloning.sh +++ b/prepareThisHostBeforeCloning.sh @@ -12,42 +12,62 @@ function setNeededHostnameOrExit() { && hostnamectl set-hostname "${_FQDN}" \ && return 0 - echo "FAILED: setting full qualified domain name, given value was:" - echo " - ${_FQDN}" + echo "FAILED: setting full qualified domain name does not contain a domain," + echo " given value was: ${_FQDN}" exit 1 } -function prepare() { +function prepareThisHost() { git --version > /dev/null || (apt update; apt upgrade -y; apt install git) echo echo "Public SSH-Key for root@$(hostname -b):" + cat "/root/.ssh/id_ed25519.pub" \ + && return 0 + # -t type of the key pair # -f defines the filenames (we use the standard for the selected type here) # -q quiet, no output or interaction # -N "" means the private key will not be secured by a passphrase # -C defines a comment + ssh-keygen \ + -t ed25519 \ + -f "/root/.ssh/id_ed25519" -q -N "" \ + -C "$(date +%Y%m%d):root@$(hostname -b)" + cat "/root/.ssh/id_ed25519.pub" \ - || (ssh-keygen \ - -t ed25519 \ - -f "/root/.ssh/id_ed25519" -q -N "" \ - -C "$(date +%Y%m%d)-root@$(hostname -b)" \ - && cat "/root/.ssh/id_ed25519.pub") + && return 0 echo - echo "Now you have to register the public ssh-key from above into your git-server to grant these access rights:" + echo "FAILED: somthing went wrong during the generation the ssh keys." + echo " These keys are mandantory. You can try to restart this script." + echo +} + +function showFurtherSteps() {} + echo + echo "IMPORTANT: It is assumed that repositories for definitions and states already exist" + echo " and comply with the naming convention." + echo " Otherwise, these repositories must be created first!" + echo + echo "To grant the correct access rights, you have to register the above-mentioned ssh key," + echo "as deploy key in these repositories of the Git server:" echo " - scripts repository (allow readonly access only)," echo " - definitions repository (allow readonly access only)," echo " - states repository (allow writable access)." echo - echo "After all access rights are granted you can clone the Infrastructure System:" - echo " e.g.: git clone ssh://git@git.example.dev:22448/iss.git /iss" + echo "After all access rights are granted you can clone the Core Infrastructure System:" + echo " e.g.: git clone ssh://git@git.example.dev:22448/cis.git /cis" echo - echo "Finally call 'setupCoreOntoThisHost.sh' from the root directory of the repository:" - echo " e.g.: /iss/setupCoreOntoThisHost.sh" + echo "Finally call 'setupCoreOntoThisHost.sh' from the root directory:" + echo " e.g.: /cis/setupCoreOntoThisHost.sh" echo } # sanitizes all parameters setNeededHostnameOrExit "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ - && prepare + && prepareThisHost \ + && showFurtherSteps \ + && exit 0 + +exit 1 diff --git a/setupCoreOntoThisHost.sh b/setupCoreOntoThisHost.sh index f745839..b0b9876 100755 --- a/setupCoreOntoThisHost.sh +++ b/setupCoreOntoThisHost.sh @@ -31,10 +31,10 @@ function checkGitIsAvailable() { } function checkPreconditions() { - local _ROOT _DOMAIN - _ROOT="${1:?"Missing parameter ROOT"}" + local _CIS_ROOT _DOMAIN + _CIS_ROOT="${1:?"Missing parameter CIS_ROOT"}" _DOMAIN="${2}" # Optional parameter DOMAIN - readonly _ROOT _DOMAIN + readonly _CIS_ROOT _DOMAIN ! [ -z "${_DOMAIN}" ] \ && [ "$(hostname -d)" != "${_DOMAIN}" ] \ @@ -46,7 +46,7 @@ function checkPreconditions() { ! [ -z "${_DOMAIN}" ] \ && checkPathsAreAvaiable \ && checkGitIsAvailable \ - && git -C "${_ROOT}" pull &> /dev/null \ + && git -C "${_CIS_ROOT}" pull &> /dev/null \ && return 0 echo @@ -69,11 +69,11 @@ function checkPreconditions() { } function getOrSetDomain() { - local _ROOT _DOMAIN_FILE _GIVEN_DOMAIN - _ROOT="${1:?"Missing parameter ROOT"}" - _DOMAIN_FILE="${_ROOT:?"Missing ROOT"}domainOfHostOwner" + local _CIS_ROOT _DOMAIN_FILE _GIVEN_DOMAIN + _CIS_ROOT="${1:?"Missing parameter CIS_ROOT"}" + _DOMAIN_FILE="${_CIS_ROOT:?"Missing CIS_ROOT"}domainOfHostOwner" _GIVEN_DOMAIN="${2}" # Optional parameter DOMAIN - readonly _ROOT _DOMAIN_FILE _GIVEN_DOMAIN + readonly _CIS_ROOT _DOMAIN_FILE _GIVEN_DOMAIN # Wenn DOMAIN_FILE enhält lesbare Daten grep '[^[:space:]]' "${_DOMAIN_FILE:?"Missing DOMAIN_FILE"}" &> /dev/null \ @@ -99,11 +99,11 @@ function getOrSetDomain() { } function getRemoteRepositoryPath() { - local _ROOT - _ROOT="${1:?"Missing parameter ROOT"}" - readonly _ROOT + local _CIS_ROOT + _CIS_ROOT="${1:?"Missing parameter CIS_ROOT"}" + readonly _CIS_ROOT - _RESULT="$(git -C "${_ROOT:?"Missing ROOT"}" remote show origin | grep -i 'fetch' | xargs -n 1 | grep -i 'ssh://')" + _RESULT="$(git -C "${_CIS_ROOT:?"Missing CIS_ROOT"}" remote show origin | grep -i 'fetch' | xargs -n 1 | grep -i 'ssh://')" _RESULT="${_RESULT%/*}" #Removes shortest matching pattern '/*' from the end ! [ -z "${_RESULT}" ] \ && echo "${_RESULT}" \ @@ -113,12 +113,12 @@ function getRemoteRepositoryPath() { } function addDefinition(){ - local _ROOT _CORE_SCRIPTS _DEFINITIONS _REPOSITORY + local _CIS_ROOT _CORE_SCRIPTS _DEFINITIONS _REPOSITORY _DEFINITIONS="${1:?"Missing parameter DEFINITIONS"}" _REPOSITORY="${2:?"Missing parameter REPOSITORY"}" - _ROOT="${_DEFINITIONS%%/definitions/*}/" #Removes longest matching pattern '/definitions/*' from the end - _CORE_SCRIPTS="${_ROOT:?"Missing ROOT"}core/" - readonly _ROOT _CORE_SCRIPTS _DEFINITIONS _REPOSITORY + _CIS_ROOT="${_DEFINITIONS%%/definitions/*}/" #Removes longest matching pattern '/definitions/*' from the end + _CORE_SCRIPTS="${_CIS_ROOT:?"Missing CIS_ROOT"}core/" + readonly _CIS_ROOT _CORE_SCRIPTS _DEFINITIONS _REPOSITORY [ "$(id -u)" == "0" ] \ && "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}addAndCheckGitRepository.sh" "${_DEFINITIONS}" "${_REPOSITORY}" readonly \ && echo " - definitions are usable for this host." \ @@ -133,12 +133,12 @@ function addDefinition(){ } function addState() { - local _ROOT _CORE_SCRIPTS _STATES _REPOSITORY + local _CIS_ROOT _CORE_SCRIPTS _STATES _REPOSITORY _STATES="${1:?"Missing parameter STATES"}" _REPOSITORY="${2:?"Missing parameter REPOSITORY"}" - _ROOT="${_STATES%%/states/*}/" #Removes longest matching pattern '/states/*' from the end - _CORE_SCRIPTS="${_ROOT:?"Missing ROOT"}core/" - readonly _ROOT _CORE_SCRIPTS _STATES _REPOSITORY + _CIS_ROOT="${_STATES%%/states/*}/" #Removes longest matching pattern '/states/*' from the end + _CORE_SCRIPTS="${_CIS_ROOT:?"Missing CIS_ROOT"}core/" + readonly _CIS_ROOT _CORE_SCRIPTS _STATES _REPOSITORY [ "$(id -u)" == "0" ] \ && "${_CORE_SCRIPTS:?"Missing CORE_SCRIPTS"}addAndCheckGitRepository.sh" "${_STATES}" "${_REPOSITORY}" writable \ @@ -154,13 +154,13 @@ function addState() { } function setupCoreFunctionality() { - local _ROOT _CORE_SCRIPTS _DEFINITIONS _MINUTE_FROM_OWN_IP _SETUP + local _CIS_ROOT _CORE_SCRIPTS _DEFINITIONS _MINUTE_FROM_OWN_IP _SETUP _DEFINITIONS="${1:?"Missing DEFINITIONS: 'ROOT/definitions/DOMAIN'"}" - _ROOT="${_DEFINITIONS%%/definitions/*}/" #Removes longest matching pattern '/definitions/*' from the end - _CORE_SCRIPTS="${_ROOT:?"Missing ROOT"}core/" + _CIS_ROOT="${_DEFINITIONS%%/definitions/*}/" #Removes longest matching pattern '/definitions/*' from the end + _CORE_SCRIPTS="${_CIS_ROOT:?"Missing CIS_ROOT"}core/" _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 _SETUP="${2:?"Missing SETUP"}" - readonly _ROOT _CORE_SCRIPTS _DEFINITIONS _MINUTE_FROM_OWN_IP _SETUP + readonly _CIS_ROOT _CORE_SCRIPTS _DEFINITIONS _MINUTE_FROM_OWN_IP _SETUP [ "$(id -u)" != "0" ] \ && echo "Configuration of host skipped because of insufficient rights." \ @@ -183,20 +183,20 @@ function setupCoreFunctionality() { } function setup() { - local _ROOT _DEFINITIONS _DEFINITIONS_REPOSITORY _DOMAIN _REPOSITORY_PATH _SETUP _STATES _STATES_REPOSITORY + local _CIS_ROOT _DEFINITIONS _DEFINITIONS_REPOSITORY _DOMAIN _REPOSITORY_PATH _SETUP _STATES _STATES_REPOSITORY _SETUP="$(readlink -f "${0}" 2> /dev/null)" - _ROOT="$(dirname ${_SETUP:?"Missing SETUP"} 2> /dev/null || echo "/iss")/" - _DOMAIN="$(getOrSetDomain "${_ROOT:?"Missing ROOT"}" "${1}")" - _REPOSITORY_PATH="$(getRemoteRepositoryPath "${_ROOT:?"Missing ROOT"}")" + _CIS_ROOT="$(dirname ${_SETUP:?"Missing SETUP"} 2> /dev/null || echo "/cis")/" + _DOMAIN="$(getOrSetDomain "${_CIS_ROOT:?"Missing CIS_ROOT"}" "${1}")" + _REPOSITORY_PATH="$(getRemoteRepositoryPath "${_CIS_ROOT:?"Missing CIS_ROOT"}")" - ! checkPreconditions "${_ROOT:?"Missing ROOT"}" "${_DOMAIN}" \ + ! checkPreconditions "${_CIS_ROOT:?"Missing CIS_ROOT"}" "${_DOMAIN}" \ && return 1 - _DEFINITIONS="${_ROOT:?"Missing ROOT"}definitions/${_DOMAIN:?"Missing DOMAIN"}" - _DEFINITIONS_REPOSITORY="${_REPOSITORY_PATH:?"Missing REPOSITORY_PATH"}/iss-definition-${_DOMAIN:?"Missing DOMAIN"}.git" - _STATES="${_ROOT:?"Missing ROOT"}states/${_DOMAIN:?"Missing DOMAIN"}" - _STATES_REPOSITORY="${_REPOSITORY_PATH:?"Missing REPOSITORY_PATH"}/iss-state-${_DOMAIN:?"Missing DOMAIN"}.git" - readonly _ROOT _DEFINITIONS _DEFINITIONS_REPOSITORY _DOMAIN _REPOSITORY_PATH _SETUP _STATES _STATES_REPOSITORY + _DEFINITIONS="${_CIS_ROOT:?"Missing CIS_ROOT"}definitions/${_DOMAIN:?"Missing DOMAIN"}" + _DEFINITIONS_REPOSITORY="${_REPOSITORY_PATH:?"Missing REPOSITORY_PATH"}/cis-definition-${_DOMAIN:?"Missing DOMAIN"}.git" + _STATES="${_CIS_ROOT:?"Missing CIS_ROOT"}states/${_DOMAIN:?"Missing DOMAIN"}" + _STATES_REPOSITORY="${_REPOSITORY_PATH:?"Missing REPOSITORY_PATH"}/cis-state-${_DOMAIN:?"Missing DOMAIN"}.git" + readonly _CIS_ROOT _DEFINITIONS _DEFINITIONS_REPOSITORY _DOMAIN _REPOSITORY_PATH _SETUP _STATES _STATES_REPOSITORY echo \ && echo "Running setup using repositories of: '${_REPOSITORY_PATH:?"Missing REPOSITORY_PATH"}' ..." \ @@ -215,6 +215,7 @@ function setup() { } # sanitizes all parameters -setup \ - "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ - && exit 0 || exit 1 +setup "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ + && exit 0 + +exit 1 diff --git a/updateRepositories.sh b/updateRepositories.sh index cf6c13e..033fda2 100755 --- a/updateRepositories.sh +++ b/updateRepositories.sh @@ -20,32 +20,32 @@ function update_repositories() { - local _ROOT _DEFINITIONS _DOMAIN _MODE _STATES _UPDATE_REPOSITORIES + local _CIS_ROOT _DEFINITIONS _DOMAIN _MODE _STATES _UPDATE_REPOSITORIES _UPDATE_REPOSITORIES="$(readlink -f "${0}" 2> /dev/null)" - _MODE="${1:-"all"}" - _ROOT="$(dirname ${_UPDATE_REPOSITORIES:?"Missing UPDATE_REPOSITORIES"} 2> /dev/null || echo "/iss")/" - _DOMAIN="$(cat ${_ROOT:?"Missing ROOT"}domainOfHostOwner)" - _DEFINITIONS="${_ROOT}definitions/${_DOMAIN:?"Missing DOMAIN from file: ${_ROOT}domainOfHostOwner"}/" - _STATES="${_ROOT}states/${_DOMAIN:?"Missing DOMAIN from file: ${_ROOT}domainOfHostOwner"}/" - readonly _ROOT _DEFINITIONS _DOMAIN _MODE _STATES _UPDATE_REPOSITORIES + _MODE="${1:-"--core"}" + _CIS_ROOT="$(dirname ${_UPDATE_REPOSITORIES:?"Missing UPDATE_REPOSITORIES"} 2> /dev/null || echo "/cis")/" + _DOMAIN="$(cat ${_CIS_ROOT:?"Missing CIS_ROOT"}domainOfHostOwner)" + _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 [ "${_MODE}" == "--repair" ] \ - && (git -C "${_ROOT}" reset --hard origin/master; \ - git -C "${_DEFINITIONS}" reset --hard origin/master; \ - git -C "${_STATES}" reset --hard origin/master; \ + && (git -C "${_CIS_ROOT}" reset --hard origin/main; \ + git -C "${_DEFINITIONS}" reset --hard origin/main; \ + git -C "${_STATES}" reset --hard origin/main; \ echo "Run repairs") \ && return 0 [ "${_MODE}" == "--test" ] \ - && git -C "${_ROOT}" pull \ + && git -C "${_CIS_ROOT}" pull \ && git -C "${_DEFINITIONS}" pull \ && git -C "${_STATES}" pull \ && echo "Run in testMode successfully." \ && return 0 [ "${_MODE}" == "--scripts" ] \ - && echo "Host $HOSTNAME updating scripts: ${_ROOT} ..." \ - && (git -C "${_ROOT}" pull &> /dev/null &) \ + && echo "Host $HOSTNAME updating scripts: ${_CIS_ROOT} ..." \ + && (git -C "${_CIS_ROOT}" pull &> /dev/null &) \ && return 0 [ "${_MODE}" == "--definitions" ] \ @@ -58,16 +58,19 @@ function update_repositories() { && (git -C "${_STATES}" pull &> /dev/null &) \ && return 0 - echo "Host ${HOSTNAME} updating ${_MODE}:" \ - && echo " - ${_ROOT}" \ - && echo " - ${_DEFINITIONS}" \ - && echo " - ${_STATES}" - git -C "${_ROOT}" pull &> /dev/null - git -C "${_DEFINITIONS}" pull &> /dev/null - git -C "${_STATES}" pull &> /dev/null + [ "${_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 &) \ + && return 0 + + echo "FAILED: an error occurred during an update." + return 1 } # sanitizes all parameters -update_repositories \ - "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ - && exit 0 || exit 1 +update_repositories "$(echo ${1} | sed -E 's|[^a-zA-Z0-9/:@._-]*||g')" \ + && exit 0 + +exit 1