summaryrefslogtreecommitdiffstats
path: root/contrib/linux-agent-installer/Icinga2Agent.bash
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--contrib/linux-agent-installer/Icinga2Agent.bash318
1 files changed, 318 insertions, 0 deletions
diff --git a/contrib/linux-agent-installer/Icinga2Agent.bash b/contrib/linux-agent-installer/Icinga2Agent.bash
new file mode 100644
index 0000000..546ed0e
--- /dev/null
+++ b/contrib/linux-agent-installer/Icinga2Agent.bash
@@ -0,0 +1,318 @@
+#!/bin/bash
+
+# This generates and signs your required certificates. Please do not
+# forget to install the Icinga 2 package and your desired monitoring
+# plugins first.
+
+# Config from Director
+#ICINGA2_NODENAME='@ICINGA2_NODENAME@'
+#ICINGA2_CA_TICKET='@ICINGA2_CA_TICKET@'
+#ICINGA2_PARENT_ZONE='@ICINGA2_PARENT_ZONE@'
+#ICINGA2_PARENT_ENDPOINTS='@ICINGA2_PARENT_ENDPOINTS@'
+#ICINGA2_CA_NODE='@ICINGA2_CA_NODE@'
+#ICINGA2_GLOBAL_ZONES='@ICINGA2_GLOBAL_ZONES@'
+
+# Internal defaults
+: "${ICINGA2_OSFAMILY:=}"
+: "${ICINGA2_HOSTNAME:="$(hostname -f)"}"
+: "${ICINGA2_NODENAME:="${ICINGA2_HOSTNAME}"}"
+: "${ICINGA2_CA_NODE:=}"
+: "${ICINGA2_CA_PORT:=5665}"
+: "${ICINGA2_CA_TICKET:=}"
+: "${ICINGA2_PARENT_ZONE:=master}"
+: "${ICINGA2_PARENT_ENDPOINTS:=()}"
+: "${ICINGA2_GLOBAL_ZONES:=director-global}"
+: "${ICINGA2_DRYRUN:=}"
+: "${ICINGA2_UPDATE_CONFIG:=}"
+
+# Helper functions
+fail() {
+ echo "ERROR: $1" >&2
+ exit 1
+}
+
+warn() {
+ echo "WARNING: $1" >&2
+}
+
+info() {
+ echo "INFO: $1" >&2
+}
+
+check_command() {
+ command -v "$@" &>/dev/null
+}
+
+install_config() {
+ if [ -e "$1" ] && [ ! -e "${1}.orig" ]; then
+ info "Creating a backup at ${1}.orig"
+ cp "$1" "${1}.orig"
+ fi
+ echo "Writing config to ${1}"
+ echo "$2" > "${1}"
+}
+
+[ "$BASH_VERSION" ] || fail "This is a Bash script"
+
+errors=
+for key in NODENAME CA_NODE CA_PORT CA_TICKET PARENT_ZONE PARENT_ENDPOINTS; do
+ var="ICINGA2_${key}"
+ if [ -z "${!var}" ]; then
+ warn "The variable $var needs to be configured!"
+ errors+=1
+ fi
+done
+[ -z "$errors" ] || exit 1
+
+# Detect osfamily
+if [ -n "$ICINGA2_OSFAMILY" ]; then
+ info "Assuming supplied osfamily $ICINGA2_OSFAMILY"
+elif check_command rpm && ! check_command dpkg; then
+ info "This should be a RedHat system"
+ if [ -e /etc/sysconfig/icinga2 ]; then
+ # shellcheck disable=SC1091
+ . /etc/sysconfig/icinga2
+ fi
+ ICINGA2_OSFAMILY=redhat
+elif check_command dpkg; then
+ info "This should be a Debian system"
+ if [ -e /etc/default/icinga2 ]; then
+ # shellcheck disable=SC1091
+ . /etc/default/icinga2
+ fi
+ ICINGA2_OSFAMILY=debian
+elif check_command apk; then
+ info "This should be a Alpine system"
+ if [ -e /etc/icinga2/icinga2.sysconfig ]; then
+ # shellcheck disable=SC1091
+ . /etc/icinga2/icinga2.sysconfig
+ fi
+ ICINGA2_OSFAMILY=alpine
+else
+ fail "Could not determine your os type!"
+fi
+
+# internal defaults
+: "${ICINGA2_CONFIG_FILE:=/etc/icinga2/icinga2.conf}"
+: "${ICINGA2_CONFIGDIR:="$(dirname "$ICINGA2_CONFIG_FILE")"}"
+: "${ICINGA2_DATADIR:=/var/lib/icinga2}"
+: "${ICINGA2_SSLDIR_OLD:="${ICINGA2_CONFIGDIR}"/pki}"
+: "${ICINGA2_SSLDIR_NEW:="${ICINGA2_DATADIR}"/certs}"
+: "${ICINGA2_SSLDIR:=}"
+: "${ICINGA2_BIN:=icinga2}"
+
+case "$ICINGA2_OSFAMILY" in
+debian)
+ : "${ICINGA2_USER:=nagios}"
+ : "${ICINGA2_GROUP:=nagios}"
+ ;;
+redhat)
+ : "${ICINGA2_USER:=icinga}"
+ : "${ICINGA2_GROUP:=icinga}"
+ ;;
+alpine)
+ : "${ICINGA2_USER:=icinga}"
+ : "${ICINGA2_GROUP:=icinga}"
+ ;;
+*)
+ fail "Unknown osfamily '$ICINGA2_OSFAMILY'!"
+ ;;
+esac
+
+icinga_version() {
+ "$ICINGA2_BIN" --version 2>/dev/null | grep -oPi '\(version: [rv]?\K\d+\.\d+\.\d+[^\)]*'
+}
+
+version() {
+ echo "$@" | awk -F. '{ printf("%03d%03d%03d\n", $1,$2,$3); }'
+}
+
+# Make sure icinga2 is installed and running
+echo -n "check: icinga2 installed - "
+if version=$(icinga_version); then
+ echo "OK: $version"
+else
+ fail "You need to install icinga2!"
+fi
+
+if [ -z "${ICINGA2_SSLDIR}" ]; then
+ if [ -f "${ICINGA2_SSLDIR_OLD}/${ICINGA2_NODENAME}.crt" ]; then
+ info "Using old SSL directory: ${ICINGA2_SSLDIR_OLD}"
+ info "Because you already have a certificate in ${ICINGA2_SSLDIR_OLD}/${ICINGA2_NODENAME}.crt"
+ ICINGA2_SSLDIR="${ICINGA2_SSLDIR_OLD}"
+ elif [ $(version $version) -gt $(version 2.8) ]; then
+ info "Using new SSL directory: ${ICINGA2_SSLDIR_NEW}"
+ ICINGA2_SSLDIR="${ICINGA2_SSLDIR_NEW}"
+ else
+ info "Using old SSL directory: ${ICINGA2_SSLDIR_OLD}"
+ ICINGA2_SSLDIR="${ICINGA2_SSLDIR_OLD}"
+ fi
+fi
+
+if [ ! -d "$ICINGA2_SSLDIR" ]; then
+ mkdir "$ICINGA2_SSLDIR"
+ chown "$ICINGA2_USER.$ICINGA2_GROUP" "$ICINGA2_SSLDIR"
+fi
+
+if [ -f "${ICINGA2_SSLDIR}/${ICINGA2_NODENAME}.crt" ]; then
+ warn "ERROR: a certificate for '${ICINGA2_NODENAME}' already exists"
+ warn "Please remove ${ICINGA2_SSLDIR}/${ICINGA2_NODENAME}.??? in case you want a"
+ warn "new certificate to be generated and signed by ${ICINGA2_CA_NODE}"
+
+ if [ -z "${ICINGA2_UPDATE_CONFIG}" ] && [ -z "${ICINGA2_DRYRUN}" ]; then
+ warn "Aborting here, you can can call the script like this to just update config:"
+ info " ICINGA2_UPDATE_CONFIG=1 $0"
+ exit 1
+ fi
+elif [ -z "${ICINGA2_DRYRUN}" ]; then
+ if ! "$ICINGA2_BIN" pki new-cert --cn "${ICINGA2_NODENAME}" \
+ --cert "${ICINGA2_SSLDIR}/${ICINGA2_NODENAME}.crt" \
+ --csr "${ICINGA2_SSLDIR}/${ICINGA2_NODENAME}.csr" \
+ --key "${ICINGA2_SSLDIR}/${ICINGA2_NODENAME}.key"
+ then fail "Could not create self signed certificate!"
+ fi
+
+ if ! "$ICINGA2_BIN" pki save-cert \
+ --host "${ICINGA2_CA_NODE}" \
+ --port "${ICINGA2_CA_PORT}" \
+ --key "${ICINGA2_SSLDIR}/${ICINGA2_NODENAME}.key" \
+ --trustedcert "${ICINGA2_SSLDIR}/trusted-master.crt"
+ then fail "Could not retrieve trusted certificate from host ${ICINGA2_CA_NODE}"
+ fi
+
+ if ! "$ICINGA2_BIN" pki request \
+ --host "${ICINGA2_CA_NODE}" \
+ --port "${ICINGA2_CA_PORT}" \
+ --ticket "${ICINGA2_CA_TICKET}" \
+ --key "${ICINGA2_SSLDIR}/${ICINGA2_NODENAME}.key" \
+ --cert "${ICINGA2_SSLDIR}/${ICINGA2_NODENAME}.crt" \
+ --trustedcert "${ICINGA2_SSLDIR}/trusted-master.crt" \
+ --ca "${ICINGA2_SSLDIR}/ca.crt"
+ then fail "Could not retrieve final certificate from host ${ICINGA2_CA_NODE}"
+ fi
+else
+ info "Would create certificates under ${ICINGA2_SSLDIR}, but in dry-run!"
+fi
+
+# Prepare Config Files
+content_config=$(cat << EOF
+/** Icinga 2 Config - proposed by Icinga Director */
+
+include "constants.conf"
+
+$([ "${ICINGA2_HOSTNAME}" != "${ICINGA2_NODENAME}" ] || echo '// ')const NodeName = "${ICINGA2_NODENAME}"
+
+include "zones.conf"
+include "features-enabled/*.conf"
+
+include <itl>
+include <plugins>
+include <plugins-contrib>
+include <manubulon>
+include <windows-plugins>
+include <nscp>
+EOF
+)
+
+endpoint_list=''
+for item in "${ICINGA2_PARENT_ENDPOINTS[@]}"; do
+ endpoint=$(echo "$item" | cut -d, -f1)
+ endpoint_list+="\"${endpoint}\", "
+done
+
+content_zones=$(cat << EOF
+/** Icinga 2 Config - proposed by Icinga Director */
+
+object Endpoint "${ICINGA2_NODENAME}" {}
+
+object Zone "${ICINGA2_NODENAME}" {
+ parent = "${ICINGA2_PARENT_ZONE}"
+ endpoints = [ "${ICINGA2_NODENAME}" ]
+}
+
+object Zone "${ICINGA2_PARENT_ZONE}" {
+ endpoints = [ ${endpoint_list%, } ]
+}
+EOF
+)
+
+for item in "${ICINGA2_PARENT_ENDPOINTS[@]}"; do
+ endpoint=$(echo "$item" | cut -d, -f1)
+ host=$(echo "$item" | cut -s -d, -f2)
+
+ content_zones+=$(cat << EOF
+
+object Endpoint "${endpoint}" {
+$([ -n "$host" ] && echo " host = \"${host}\"" || echo " //host = \"${endpoint}\"")
+}
+EOF
+)
+done
+
+for zone in "${ICINGA2_GLOBAL_ZONES[@]}"; do
+ content_zones+=$(cat << EOF
+
+object Zone "${zone}" {
+ global = true
+}
+EOF
+)
+done
+
+content_api="/** Icinga 2 Config - proposed by Icinga Director */
+
+object ApiListener \"api\" {"
+
+if [ "${ICINGA2_SSLDIR}" = "${ICINGA2_SSLDIR_OLD}" ]; then
+content_api+="
+ cert_path = SysconfDir + \"/icinga2/pki/${ICINGA2_NODENAME}.crt\"
+ key_path = SysconfDir + \"/icinga2/pki/${ICINGA2_NODENAME}.key\"
+ ca_path = SysconfDir + \"/icinga2/pki/ca.crt\"
+"
+fi
+content_api+="
+ accept_commands = true
+ accept_config = true
+}
+"
+
+if [ -z "${ICINGA2_DRYRUN}" ]; then
+ install_config "$ICINGA2_CONFIGDIR"/icinga2.conf "$content_config"
+ install_config "$ICINGA2_CONFIGDIR"/zones.conf "$content_zones"
+ install_config "$ICINGA2_CONFIGDIR"/features-available/api.conf "$content_api"
+
+ "$ICINGA2_BIN" feature enable api
+
+ "$ICINGA2_BIN" daemon -C
+
+ echo "Please restart icinga2:"
+ case "$ICINGA2_OSFAMILY" in
+ debian)
+ echo " systemctl restart icinga2"
+ ;;
+ redhat)
+ echo " systemctl restart icinga2"
+ ;;
+ alpine)
+ echo " rc-service icinga2 restart"
+ ;;
+ *)
+ fail "Unknown osfamily '$ICINGA2_OSFAMILY'!"
+ ;;
+ esac
+else
+ output_code() {
+ sed 's/^/ /m' <<<"$1"
+ }
+ echo "### $ICINGA2_CONFIGDIR"/icinga2.conf
+ echo
+ output_code "$content_config"
+ echo
+ echo "### $ICINGA2_CONFIGDIR"/zones.conf
+ echo
+ output_code "$content_zones"
+ echo
+ echo "### $ICINGA2_CONFIGDIR"/features-available/api.conf
+ echo
+ output_code "$content_api"
+fi