]> Frank Brehm's Git Trees - pixelpark/create-terraform.git/commitdiff
Adding postinstall script for finishing network installation on multihomed Linux...
authorFrank Brehm <frank.brehm@pixelpark.com>
Tue, 23 Apr 2024 15:07:19 +0000 (17:07 +0200)
committerFrank Brehm <frank.brehm@pixelpark.com>
Tue, 23 Apr 2024 15:07:19 +0000 (17:07 +0200)
misc/switch-to-new.dnsmaster.pp-dns.com.sh [new file with mode: 0755]
postinstall-scripts/finish-network.sh [new file with mode: 0755]
postinstall-scripts/network-data.csv [new file with mode: 0644]

diff --git a/misc/switch-to-new.dnsmaster.pp-dns.com.sh b/misc/switch-to-new.dnsmaster.pp-dns.com.sh
new file mode 100755 (executable)
index 0000000..7a94f0d
--- /dev/null
@@ -0,0 +1,291 @@
+#!/bin/bash
+
+set -e
+set -u
+
+BASE_NAME="$( basename ${0} )"
+MY_REAL_NAME=$( readlink -f $0 )
+BIN_DIR=$( dirname "${MY_REAL_NAME}" )
+
+RC_FILE='/usr/libexec/pixelpark/functions.rc'
+
+if [[ -f "${RC_FILE}" ]] ; then
+    . "${RC_FILE}"
+else
+    echo "Bash resource file '${RC_FILE}' not found" >&2
+    exit 5
+fi
+
+detect_color
+
+FILES_DIR="${BIN_DIR}/files"
+ERRORS=0
+
+DESCRIPTION=$( cat <<-EOF
+       Switching files to exchange the hostname and the IP addresses
+       on the next reboot
+
+       EOF
+)
+
+#------------------------------------------------------------------------------
+usage() {
+    cat <<-EOF
+       Usage: ${BASE_NAME} [Common Options]
+              ${BASE_NAME} [-h|--help]
+              ${BASE_NAME} [-V|--version]
+
+           Common Options:
+       ${STD_USAGE_MSG}
+       EOF
+
+}
+
+#------------------------------------------------------------------------------
+CP() {
+    local cmd="cp"
+    if [[ "${VERBOSE}" == "y" ]] ; then
+        cmd+=" --verbose"
+    fi
+    if [[ "${SIMULATE}" == "y" ]] ; then
+        info "Executing: ${cmd} $*"
+        return
+    fi
+    eval ${cmd} "$@"
+}
+
+#------------------------------------------------------------------------------
+get_options() {
+
+    local tmp=
+    local base_dir=
+
+    set +e
+    tmp=$( getopt -o ${STD_SHORT_OPTIONS} --long ${STD_LONG_OPTIONS} -n "${BASE_NAME}" -- "$@" )
+    if [[ $? != 0 ]] ; then
+        echo "" >&2
+        usage >&2
+        exit 1
+    fi
+    set -e
+
+    # Note the quotes around `$TEMP': they are essential!
+    eval set -- "${tmp}"
+    eval_common_options "$@"
+    if [[ "${DEBUG}" == 'y' ]] ; then
+        declare -p REMAINING_OPTS
+        declare -p REMAINING_ARGS
+    fi
+
+    if [[ "${#REMAINING_OPTS[@]}" -gt 0 ]] ; then
+        error "Unknown options: ${REMAINING_OPTS[*]}"
+        echo >&2
+        usage >&2
+        exit 2
+    fi
+
+    if [[ "${#REMAINING_ARGS[@]}" != "0" ]] ; then
+        error "Invalig arguments given: ${REMAINING_ARGS[*]}"
+        echo >&2
+        usage >&2
+        exit 2
+    fi
+
+    if [[ $(id -u -n) != "root" ]] ; then
+        error "You must ${RED}be root${NORMAL} to execute this script!" >&2
+        exit 1
+    fi
+
+    if [[ ! -d "${FILES_DIR}" ]] ; then
+        error "Directory '${RED}${FILES_DIR}${NORMAL}' not found."
+        exit 5
+    fi
+
+}
+
+#------------------------------------------------------------------------------
+do_filesync() {
+
+    info "Syncing from directory '${GREEN}${FILES_DIR}${NORMAL}' ..."
+    cd "${FILES_DIR}"
+
+    local oifs="${IFS}"
+    IFS="
+"
+
+    local -a files=()
+    local f=
+    local fdate=
+    local i=
+    local target=
+    local backup=
+    local fabs=
+
+    for f in $( find ./ -type f | sort ) ; do
+        f=$( echo ${f} | sed -e 's|^\./||' )
+        if [[ ! -e "${f}" ]] ; then
+            error "File '${f}' does not really exists."
+            ERRORS=$(( ERRORS + 1 ))
+            continue
+        fi
+
+        files+=( "${f}" )
+    done
+
+    IFS="${oifs}"
+
+    for f in "${files[@]}" ; do
+
+        empty_line
+        target="/${f}"
+        info "${CYAN}${target}${NORMAL}"
+        i=0
+        if [[ -e "${target}" ]] ; then
+            if [[ ! -f "${target}" ]] ; then
+                error "Target file '${RED}${target}${NORMAL}' exists, but is not a regular file."
+                ERRORS=$(( ERRORS + 1 ))
+                continue
+            fi
+
+            debug "Comparing source '${FILES_DIR}${f}' and target '${target}' ..."
+            if diff -q "${target}" "${f}" >/dev/null ; then
+                debug "Source '${f}' and target '${target}' are identic."
+                continue
+            fi
+
+            fdate=$( date -r "${target}" +'%Y-%m-%d_%H:%M:%S' )
+            backup=$( printf "%s.%s.%02d.bak" "${target}" "${fdate}" "$i" )
+            while [[ -e "${backup}" ]] ; do
+                i=$(( i + 1 ))
+                backup=$( printf "%s.%s.%02d.bak" "${target}" "${fdate}" "$i" )
+            done
+            debug "Copying '${CYAN}${target}${NORMAL}' => '${CYAN}${backup}${NORMAL}'"
+            CP -p "${target}" "${backup}"
+        fi
+
+        fabs="${FILES_DIR}/${f}"
+        debug "Copying '${CYAN}${fabs}${NORMAL}' => '${CYAN}${target}${NORMAL}'"
+        CP -p "${fabs}" "${target}"
+        if [[ "${VERBOSE}" == "y" ]] ; then
+            ls -l -d --color=auto "${fabs}" "${target}"* || true
+        fi
+
+    done
+
+}
+
+#------------------------------------------------------------------------------
+clean_puppet_certs() {
+
+    empty_line
+    info "Cleaning up Puppet certificates ..."
+    local f=
+
+    for f in /etc/puppetlabs/puppet/ssl/*/prd-dnsmaster*.pixelpark.com.pem \
+             /etc/puppetlabs/puppet/ssl/*/dnsmaster.pp-dns.com.pem \
+             /etc/puppetlabs/puppet/ssl/*/systemshare.pixelpark.com.pem ; do
+        if [[ ! -f "${f}" ]] ; then
+            continue
+        fi
+        RM "${f}"
+    done
+    empty_line
+
+}
+
+#------------------------------------------------------------------------------
+clean_ssh_host_keys() {
+
+    empty_line
+    info "Cleaning up SSH host keys ..."
+    local f=
+    local fdate=
+    local backup=
+    local i=
+
+    for f in /etc/ssh/ssh_host_* ; do
+        if [[ ! -f "${f}" ]] ; then
+            continue
+        fi
+        i=0
+        fdate=$( date -r "${f}" +'%Y-%m-%d_%H:%M:%S' )
+        backup=$( printf "%s.%s.%02d.bak" "${f}" "${fdate}" "$i" )
+        while [[ -e "${backup}" ]] ; do
+            i=$(( i + 1 ))
+            backup=$( printf "%s.%s.%02d.bak" "${f}" "${fdate}" "$i" )
+        done
+        debug "Moving '${CYAN}${f}${NORMAL}' => '${CYAN}${backup}${NORMAL}'"
+        MV "${f}" "${backup}"
+    done
+
+}
+
+
+#------------------------------------------------------------------------------
+exec_nmcli() {
+
+    local params="$1"
+    local cmd="nmcli connection ${params}"
+
+    if [[ "${SIMULATE}" == "y" ]] ; then
+        info "Executing: ${cmd}"
+    else
+        debug "Executing: ${cmd}"
+        eval ${cmd}
+    fi
+}
+
+#------------------------------------------------------------------------------
+do_nwm() {
+
+    empty_line
+    info "Changing ${CYAN}network configuration${NORMAL} ..."
+
+    empty_line
+    info "${CYAN}eth0${NORMAL}"
+    exec_nmcli "modify eth0 ipv4.addresses '217.66.53.86/24,217.66.53.87/24,217.66.53.97/24'"
+
+    empty_line
+    info "${CYAN}eth1${NORMAL}"
+    exec_nmcli "modify eth1 ipv4.addresses '217.66.51.125/24'"
+
+    empty_line
+    info "${CYAN}eth2${NORMAL}"
+    exec_nmcli "modify eth2 ipv4.addresses '77.74.232.20/28'"
+
+    empty_line
+    info "${CYAN}eth3${NORMAL}"
+    exec_nmcli "modify eth3 ipv4.addresses '93.188.104.80/25'"
+
+    empty_line
+    info "${CYAN}eth4${NORMAL}"
+    exec_nmcli "modify eth4 ipv4.addresses '93.188.109.5/28,93.188.109.6/28'"
+
+}
+
+#------------------------------------------------------------------------------
+main() {
+
+    get_options "$@"
+    umask 0022
+    clean_puppet_certs
+    clean_ssh_host_keys
+    do_filesync
+    do_nwm
+
+    empty_line
+    warn "Don't forget to execute '${CYAN}ssh-keygen -A${NORMAL}' after reboot!"
+
+}
+
+main "$@"
+if [[ "${ERRORS}" != "0" ]] ; then
+    empty_line
+    error "There were ${RED}${ERRORS}${NORMAL} errors during execution."
+    ERRORS=$(( ERRORS + 1 ))
+    exit "${ERRORS}"
+fi
+
+exit 0
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list
diff --git a/postinstall-scripts/finish-network.sh b/postinstall-scripts/finish-network.sh
new file mode 100755 (executable)
index 0000000..2e69e4e
--- /dev/null
@@ -0,0 +1,219 @@
+#!/bin/bash
+
+set -e
+set -u
+
+BASE_NAME="$( basename ${0} )"
+MY_REAL_NAME=$( readlink -f $0 )
+BIN_DIR=$( dirname "${MY_REAL_NAME}" )
+BASE_DIR=$( dirname "${BIN_DIR}" )
+
+if [[ -f "${BIN_DIR}/functions.rc" ]] ; then
+    . "${BIN_DIR}/functions.rc"
+else
+    echo "Bash resource file '${BIN_DIR}/functions.rc' not found" >&2
+    exit 5
+fi
+
+FQDN=$( hostname -f )
+
+DATA_FILE="${BIN_DIR}/network-data.csv"
+if [[ ! -f "${DATA_FILE}" ]]; then
+    echo "Data file '${DATA_FILE}' not found" >&2
+    exit 5
+fi
+
+declare -a INTERFACE=()
+
+detect_color
+
+#------------------------------------------------------------------------------
+DESCRIPTION=$( cat <<-EOF
+       Finishing network settings on prd-ns4.pixelpark.com.
+
+       EOF
+)
+
+#------------------------------------------------------------------------------
+usage() {
+
+    cat <<-EOF
+       Usage: ${BASE_NAME} ${STD_USAGE}
+              ${BASE_NAME} [-h|--help]
+              ${BASE_NAME} [-V|--version]
+
+           Options:
+       EOF
+
+       echo "${STD_USAGE_MSG}"
+}
+
+#------------------------------------------------------------------------------
+get_options() {
+
+    local tmp=
+    local short_options="${STD_SHORT_OPTIONS}"
+    local long_options="${STD_LONG_OPTIONS}"
+
+    set +e
+    tmp=$( getopt -o "${short_options}" --long "${long_options}" -n "${BASE_NAME}" -- "$@" )
+    if [[ $? != 0 ]] ; then
+        echo "" >&2
+        usage >&2
+        exit 1
+    fi
+    set -e
+
+    # Note the quotes around `$TEMP': they are essential!
+    eval set -- "${tmp}"
+    eval_common_options "$@"
+    if [[ "${DEBUG}" == 'y' ]] ; then
+        declare -p REMAINING_OPTS
+        declare -p REMAINING_ARGS
+    fi
+
+    local len="${#REMAINING_OPTS[*]}"
+    local i="0"
+    local j=
+    local arg=
+    while [[ "$i" -lt "${len}" ]] ; do
+
+        arg="${REMAINING_OPTS[$i]}"
+
+        case "${arg}" in
+            *)  echo -e "Internal error - option '${RED}${arg}${NORMAL} was wrong!"
+                exit 1
+                ;;
+        esac
+    done
+
+}
+
+#------------------------------------------------------------------------------
+exec_nmcli() {
+
+    local params="$1"
+    local cmd="nmcli connection ${params}"
+
+    if [[ "${SIMULATE}" == "y" ]] ; then
+        info "Executing: ${cmd}"
+    else
+        debug "Executing: ${cmd}"
+        eval ${cmd}
+    fi
+}
+
+#------------------------------------------------------------------------------
+detect_necessary_interfaces() {
+
+    debug "Detecting all Network interfaces to manage ..."
+    echo "Interfaces to manage:"
+
+    local iface=
+
+    for iface in $(cat "${DATA_FILE}" | grep -P "^${FQDN}\\s" | awk '{print $2}' | sort -u); do
+        echo " * ${iface}"
+        INTRERFACES+=( "${iface}" )
+    done
+
+}
+
+#------------------------------------------------------------------------------
+get_connection() {
+
+    local iface="$1"
+
+    nmcli --terse connection show | grep -P ":${iface}\$" | awk -F: '{print $1}'
+
+}
+
+#------------------------------------------------------------------------------
+ensure_settings_dev() {
+
+    local iface="$1"
+    local conn=
+    local setting=
+    local property=
+
+    local -a settings=()
+    local cmd="nmcli connection"
+
+    empty_line
+
+    for setting in $(cat "${DATA_FILE}" | grep -P "^${FQDN}\\s+${iface}\\s" | awk '{print $3}' ); do
+        settings+=( "${setting}" )
+    done
+
+    conn=$( get_connection "${iface}" )
+    local msg=
+
+    if [[ -z "${conn}" ]] ; then
+        if ip -oneline link show | grep -P "^\\d+:\\s+${iface}:" >/dev/null ; then
+            :
+        else
+            error "Did not found Network device '${RED}${iface}${NORMAL}'."
+            return 5
+        fi
+
+        cmd+=" add type ethernet autoconnect yes ifname ${iface}"
+        msg="${CYAN}Creating NetworkManager connection for device '${GREEN}${iface}${CYAN}' ...${NORMAL}"
+
+    else
+        cmd+=" modify '${conn}'"
+        msg="${CYAN}Modifying NetworkManager connection '${GREEN}${conn}${CYAN}' for device '${GREEN}${iface}${CYAN}' ...${NORMAL}"
+    fi
+
+    for setting in "${settings[@]}" ; do
+        property=$(cat "${DATA_FILE}" | \
+                   grep -P "^${FQDN}\\s+${iface}\\s+${setting}\\s" | \
+                   sed -e "s/^${FQDN}[         ]*${iface}[     ]*${setting}[   ]*//" )
+        cmd+=" ${setting} '$property'"
+    done
+
+    info "${msg}"
+    if [[ "${SIMULATE}" == "y" ]] ; then
+        info "Should execute: ${cmd}"
+    else
+        info "Executing: ${cmd}"
+        eval ${cmd}
+    fi
+
+}
+
+#------------------------------------------------------------------------------
+ensure_all_settings() {
+
+    local iface=
+
+    for iface in "${INTRERFACES[@]}" ; do
+        ensure_settings_dev "${iface}"
+    done
+
+}
+
+################################################################################
+##
+## Main
+##
+################################################################################
+
+#------------------------------------------------------------------------------
+main() {
+
+    get_options "$@"
+    set_locale "en_US.utf8"
+
+    empty_line
+    info "Trying to ${CYAN}finish network configuration${NORMAL} ..."
+    empty_line
+
+    detect_necessary_interfaces
+    ensure_all_settings
+
+}
+
+main "$@"
+
+exit 0
+
+# vim: list
diff --git a/postinstall-scripts/network-data.csv b/postinstall-scripts/network-data.csv
new file mode 100644 (file)
index 0000000..11f4a68
--- /dev/null
@@ -0,0 +1,75 @@
+# Host                         Device  Setting                 Property
+
+# prd-ns1.pixelpark.com
+prd-ns1.pixelpark.com          ens160  ipv4.method             manual
+prd-ns1.pixelpark.com          ens160  ipv4.addresses          93.188.110.60/28
+prd-ns1.pixelpark.com          ens160  ipv4.gateway            93.188.110.49
+prd-ns1.pixelpark.com          ens160  ipv4.dns                77.74.232.24,217.66.52.10,77.74.232.25
+prd-ns1.pixelpark.com          ens160  ipv4.dns-search         pixelpark.com,pp-dns.com,pixelpark.net
+prd-ns1.pixelpark.com          ens160  ipv4.dns-options        timeout:1,attempts:1
+prd-ns1.pixelpark.com          ens160  ipv6.method             ignore
+
+prd-ns1.pixelpark.com          ens192  ipv4.method             manual
+prd-ns1.pixelpark.com          ens192  ipv4.addresses          217.66.51.53/24
+prd-ns1.pixelpark.com          ens192  ipv4.routes             217.66.51.0/24 table=100, 0.0.0.0/0 217.66.51.1 table=100
+prd-ns1.pixelpark.com          ens192  ipv4.routing-rules      priority 5 from 217.66.51.0/24 table 100, priority 6 to 217.66.51.0/24 table 100
+prd-ns1.pixelpark.com          ens192  ipv6.method             ignore
+
+prd-ns1.pixelpark.com          ens224  ipv4.method             manual
+prd-ns1.pixelpark.com          ens224  ipv4.addresses          93.188.104.87/25
+prd-ns1.pixelpark.com          ens224  ipv4.routes             93.188.104.0/25 table=200, 0.0.0.0/0 93.188.104.1 table=200
+prd-ns1.pixelpark.com          ens224  ipv4.routing-rules      priority 7 from 93.188.104.0/25 table 200, priority 8 to 93.188.104.0/25 table 200
+prd-ns1.pixelpark.com          ens224  ipv6.method             ignore
+
+# prd-ns1-new.pixelpark.com
+prd-ns1-new.pixelpark.com      ens160  ipv4.method             manual
+prd-ns1-new.pixelpark.com      ens160  ipv4.addresses          93.188.110.51/28
+prd-ns1-new.pixelpark.com      ens160  ipv4.gateway            93.188.110.49
+prd-ns1-new.pixelpark.com      ens160  ipv4.dns                77.74.232.24,217.66.52.10,77.74.232.25
+prd-ns1-new.pixelpark.com      ens160  ipv4.dns-search         pixelpark.com,pp-dns.com,pixelpark.net
+prd-ns1-new.pixelpark.com      ens160  ipv4.dns-options        timeout:1,attempts:1
+prd-ns1-new.pixelpark.com      ens160  ipv6.method             ignore
+
+prd-ns1-new.pixelpark.com      ens192  ipv4.method             manual
+prd-ns1-new.pixelpark.com      ens192  ipv4.addresses          217.66.51.29/24
+prd-ns1-new.pixelpark.com      ens192  ipv4.routes             217.66.51.0/24 table=100, 0.0.0.0/0 217.66.51.1 table=100
+prd-ns1-new.pixelpark.com      ens192  ipv4.routing-rules      priority 5 from 217.66.51.0/24 table 100, priority 6 to 217.66.51.0/24 table 100
+prd-ns1-new.pixelpark.com      ens192  ipv6.method             ignore
+
+prd-ns1-new.pixelpark.com      ens224  ipv4.method             manual
+prd-ns1-new.pixelpark.com      ens224  ipv4.addresses          93.188.104.6/25
+prd-ns1-new.pixelpark.com      ens224  ipv4.routes             93.188.104.0/25 table=200, 0.0.0.0/0 93.188.104.1 table=200
+prd-ns1-new.pixelpark.com      ens224  ipv4.routing-rules      priority 7 from 93.188.104.0/25 table 200, priority 8 to 93.188.104.0/25 table 200
+prd-ns1-new.pixelpark.com      ens224  ipv6.method             ignore
+
+# prd-ns4.pixelpark.com
+prd-ns4.pixelpark.com          ens160  ipv4.method             manual
+prd-ns4.pixelpark.com          ens160  ipv4.addresses          77.74.232.21/28
+prd-ns4.pixelpark.com          ens160  ipv4.gateway            77.74.232.17
+prd-ns4.pixelpark.com          ens160  ipv4.dns                77.74.232.24,77.74.232.25,93.188.104.82
+prd-ns4.pixelpark.com          ens160  ipv4.dns-search         pixelpark.com,pp-dns.com,pixelpark.net
+prd-ns4.pixelpark.com          ens160  ipv4.dns-options        timeout:1,attempts:1
+prd-ns4.pixelpark.com          ens160  ipv6.method             ignore
+
+prd-ns4.pixelpark.com          ens192  ipv4.method             manual
+prd-ns4.pixelpark.com          ens192  ipv4.addresses          93.188.104.81/25
+prd-ns4.pixelpark.com          ens192  ipv4.routes             93.188.104.0/25 table=100, 0.0.0.0/0 93.188.104.1 table=100
+prd-ns4.pixelpark.com          ens192  ipv4.routing-rules      priority 5 from 93.188.104.0/25 table 100, priority 6 to 93.188.104.0/25 table 100
+prd-ns4.pixelpark.com          ens192  ipv6.method             ignore
+
+# prd-ns4-new.pixelpark.com
+prd-ns4-new.pixelpark.com      ens160  ipv4.method             manual
+prd-ns4-new.pixelpark.com      ens160  ipv4.addresses          77.74.232.19/28
+prd-ns4-new.pixelpark.com      ens160  ipv4.gateway            77.74.232.17
+prd-ns4-new.pixelpark.com      ens160  ipv4.dns                77.74.232.24,77.74.232.25,93.188.104.82
+prd-ns4-new.pixelpark.com      ens160  ipv4.dns-search         pixelpark.com,pp-dns.com,pixelpark.net
+prd-ns4-new.pixelpark.com      ens160  ipv4.dns-options        timeout:1,attempts:1
+prd-ns4-new.pixelpark.com      ens160  ipv6.method             ignore
+
+prd-ns4-new.pixelpark.com      ens192  ipv4.method             manual
+prd-ns4-new.pixelpark.com      ens192  ipv4.addresses          93.188.104.4/25
+prd-ns4-new.pixelpark.com      ens192  ipv4.routes             93.188.104.0/25 table=100, 0.0.0.0/0 93.188.104.1 table=100
+prd-ns4-new.pixelpark.com      ens192  ipv4.routing-rules      priority 5 from 93.188.104.0/25 table 100, priority 6 to 93.188.104.0/25 table 100
+prd-ns4-new.pixelpark.com      ens192  ipv6.method             ignore
+
+# vim: list