Add PatchMon enrollment helper
This commit is contained in:
@@ -61,6 +61,41 @@ chmod +x install-docker.sh
|
||||
|
||||
The old `Docker-Install.sh` filename still exists as a compatibility wrapper.
|
||||
|
||||
## PatchMon enrollment
|
||||
|
||||
Enroll a Linux host into PatchMon. By default this uses the PatchMon LXC at `http://192.168.20.232:3000` and the `direct-host` enrollment type.
|
||||
|
||||
Recommended interactive one-liner. It prompts for the PatchMon auto-enrollment token key and secret:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://gitea.wheelytho.com/Wheelz/Docker-Install/raw/branch/main/patchmon-enroll.sh | sudo bash
|
||||
```
|
||||
|
||||
Non-interactive direct-host enrollment:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://gitea.wheelytho.com/Wheelz/Docker-Install/raw/branch/main/patchmon-enroll.sh | sudo bash -s -- --token-key '<key>' --token-secret '<secret>' --type direct-host -y
|
||||
```
|
||||
|
||||
Proxmox LXC enrollment:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://gitea.wheelytho.com/Wheelz/Docker-Install/raw/branch/main/patchmon-enroll.sh | sudo bash -s -- --token-key '<key>' --token-secret '<secret>' --type proxmox-lxc -y
|
||||
```
|
||||
|
||||
Useful options:
|
||||
|
||||
```text
|
||||
--server URL PatchMon base URL. Default: http://192.168.20.232:3000
|
||||
--type TYPE direct-host or proxmox-lxc. Default: direct-host
|
||||
--friendly-name NAME Friendly name to report to PatchMon
|
||||
--force Ask PatchMon's generated installer to force/reinstall when supported
|
||||
--print-script Download and print the generated PatchMon script instead of running it
|
||||
-y, --yes Non-interactive mode
|
||||
```
|
||||
|
||||
Token note: keep the token secret out of Git. Store it in a password manager or a local `.env` and paste/use it at enrollment time only.
|
||||
|
||||
## Options
|
||||
|
||||
```text
|
||||
|
||||
Executable
+189
@@ -0,0 +1,189 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
SCRIPT_NAME="$(basename "$0")"
|
||||
PATCHMON_SERVER="${PATCHMON_SERVER:-http://192.168.20.232:3000}"
|
||||
ENROLL_TYPE="${PATCHMON_ENROLL_TYPE:-direct-host}"
|
||||
TOKEN_KEY="${PATCHMON_AUTO_ENROLL_KEY:-}"
|
||||
TOKEN_SECRET="${PATCHMON_AUTO_ENROLL_SECRET:-}"
|
||||
FRIENDLY_NAME_VALUE="${FRIENDLY_NAME:-}"
|
||||
FORCE_INSTALL="false"
|
||||
PRINT_ONLY="false"
|
||||
YES="false"
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Enroll this Linux host into PatchMon using PatchMon's auto-enrollment script.
|
||||
|
||||
Usage:
|
||||
./patchmon-enroll.sh [options]
|
||||
curl -fsSL https://gitea.wheelytho.com/Wheelz/Docker-Install/raw/branch/main/patchmon-enroll.sh | sudo bash -s -- [options]
|
||||
|
||||
Options:
|
||||
--server URL PatchMon base URL. Default: http://192.168.20.232:3000
|
||||
--type TYPE Enrollment type: direct-host or proxmox-lxc. Default: direct-host
|
||||
--token-key KEY PatchMon auto-enrollment token key. Can also use PATCHMON_AUTO_ENROLL_KEY.
|
||||
--token-secret SECRET PatchMon auto-enrollment token secret. Can also use PATCHMON_AUTO_ENROLL_SECRET.
|
||||
--friendly-name NAME Friendly name to report to PatchMon.
|
||||
--force Ask PatchMon's generated installer to force/reinstall when supported.
|
||||
--print-script Download and print the generated PatchMon script instead of running it.
|
||||
-y, --yes Non-interactive. Fail if token values are missing instead of prompting.
|
||||
-h, --help Show this help.
|
||||
|
||||
Recommended one-liner, prompts for token if env vars are not set:
|
||||
curl -fsSL https://gitea.wheelytho.com/Wheelz/Docker-Install/raw/branch/main/patchmon-enroll.sh | sudo bash
|
||||
|
||||
Non-interactive one-liner:
|
||||
PATCHMON_AUTO_ENROLL_KEY='<key>' PATCHMON_AUTO_ENROLL_SECRET='<secret>' curl -fsSL https://gitea.wheelytho.com/Wheelz/Docker-Install/raw/branch/main/patchmon-enroll.sh | sudo -E bash -s -- --type direct-host -y
|
||||
USAGE
|
||||
}
|
||||
|
||||
log() { printf '\n[PatchMon-Enroll] %s\n' "$*"; }
|
||||
warn() { printf '\n[PatchMon-Enroll WARNING] %s\n' "$*" >&2; }
|
||||
fail() { printf '\n[PatchMon-Enroll ERROR] %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
need_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || fail "Required command not found: $1"
|
||||
}
|
||||
|
||||
urlencode() {
|
||||
# POSIX-ish URL encoding via Python, which is present on the supported Ubuntu/Debian hosts.
|
||||
python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$1"
|
||||
}
|
||||
|
||||
prompt_secret() {
|
||||
local prompt="$1"
|
||||
local value=""
|
||||
if [[ "$YES" == "true" ]]; then
|
||||
fail "$prompt is required. Provide it with --token-key/--token-secret or PATCHMON_AUTO_ENROLL_KEY/PATCHMON_AUTO_ENROLL_SECRET."
|
||||
fi
|
||||
if [[ -t 0 ]]; then
|
||||
read -r -s -p "$prompt: " value
|
||||
printf '\n' >&2
|
||||
else
|
||||
if [[ -r /dev/tty ]]; then
|
||||
read -r -s -p "$prompt: " value </dev/tty
|
||||
printf '\n' >&2
|
||||
else
|
||||
fail "$prompt is required, and no TTY is available for prompting."
|
||||
fi
|
||||
fi
|
||||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--server)
|
||||
[[ $# -ge 2 ]] || fail "--server requires a URL"
|
||||
PATCHMON_SERVER="$2"
|
||||
shift 2
|
||||
;;
|
||||
--type)
|
||||
[[ $# -ge 2 ]] || fail "--type requires direct-host or proxmox-lxc"
|
||||
ENROLL_TYPE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--token-key)
|
||||
[[ $# -ge 2 ]] || fail "--token-key requires a value"
|
||||
TOKEN_KEY="$2"
|
||||
shift 2
|
||||
;;
|
||||
--token-secret)
|
||||
[[ $# -ge 2 ]] || fail "--token-secret requires a value"
|
||||
TOKEN_SECRET="$2"
|
||||
shift 2
|
||||
;;
|
||||
--friendly-name)
|
||||
[[ $# -ge 2 ]] || fail "--friendly-name requires a value"
|
||||
FRIENDLY_NAME_VALUE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--force)
|
||||
FORCE_INSTALL="true"
|
||||
shift
|
||||
;;
|
||||
--print-script)
|
||||
PRINT_ONLY="true"
|
||||
shift
|
||||
;;
|
||||
-y|--yes)
|
||||
YES="true"
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
fail "Unknown option: $1"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "$ENROLL_TYPE" in
|
||||
direct-host|proxmox-lxc) ;;
|
||||
*) fail "--type must be direct-host or proxmox-lxc. Got: $ENROLL_TYPE" ;;
|
||||
esac
|
||||
|
||||
PATCHMON_SERVER="${PATCHMON_SERVER%/}"
|
||||
[[ "$PATCHMON_SERVER" =~ ^https?:// ]] || fail "--server must start with http:// or https://"
|
||||
|
||||
need_cmd curl
|
||||
need_cmd python3
|
||||
need_cmd mktemp
|
||||
|
||||
if [[ -z "$TOKEN_KEY" ]]; then
|
||||
TOKEN_KEY="$(prompt_secret 'PatchMon auto-enrollment token key')"
|
||||
fi
|
||||
if [[ -z "$TOKEN_SECRET" ]]; then
|
||||
TOKEN_SECRET="$(prompt_secret 'PatchMon auto-enrollment token secret')"
|
||||
fi
|
||||
[[ -n "$TOKEN_KEY" ]] || fail "Token key cannot be empty"
|
||||
[[ -n "$TOKEN_SECRET" ]] || fail "Token secret cannot be empty"
|
||||
|
||||
if [[ "$PRINT_ONLY" != "true" && "$(id -u)" -ne 0 ]]; then
|
||||
fail "This script must be run as root because PatchMon's generated installer installs a system agent. Use sudo."
|
||||
fi
|
||||
|
||||
query="type=$(urlencode "$ENROLL_TYPE")&force=$(urlencode "$FORCE_INSTALL")&token_key=$(urlencode "$TOKEN_KEY")&token_secret=$(urlencode "$TOKEN_SECRET")"
|
||||
script_url="${PATCHMON_SERVER}/api/v1/auto-enrollment/script?${query}"
|
||||
tmp_script="$(mktemp /tmp/patchmon-enroll.XXXXXX.sh)"
|
||||
cleanup() { rm -f "$tmp_script"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
log "Downloading PatchMon generated enrollment script"
|
||||
if ! curl -fsSL "$script_url" -o "$tmp_script"; then
|
||||
fail "Failed to download PatchMon enrollment script. Check server URL, token, allowed IP range, and network access."
|
||||
fi
|
||||
|
||||
if ! head -n 1 "$tmp_script" | grep -q '^#!'; then
|
||||
warn "PatchMon did not return a shell script. First lines follow:"
|
||||
sed -n '1,10p' "$tmp_script" >&2
|
||||
fail "Unexpected response from PatchMon enrollment endpoint"
|
||||
fi
|
||||
chmod 700 "$tmp_script"
|
||||
|
||||
if [[ "$PRINT_ONLY" == "true" ]]; then
|
||||
sed -e "s/${TOKEN_SECRET//\//\\/}/<redacted>/g" -e "s/${TOKEN_KEY//\//\\/}/<redacted>/g" "$tmp_script"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "Running PatchMon enrollment script as type: $ENROLL_TYPE"
|
||||
if [[ -n "$FRIENDLY_NAME_VALUE" ]]; then
|
||||
FRIENDLY_NAME="$FRIENDLY_NAME_VALUE" sh "$tmp_script"
|
||||
else
|
||||
sh "$tmp_script"
|
||||
fi
|
||||
|
||||
log "Verifying local PatchMon agent service"
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
if systemctl list-unit-files 'patchmon*' --no-legend 2>/dev/null | grep -q .; then
|
||||
systemctl --no-pager --full status 'patchmon*' || true
|
||||
else
|
||||
warn "No patchmon systemd unit was found. Check the installer output above."
|
||||
fi
|
||||
else
|
||||
warn "systemctl not available; skipping service verification."
|
||||
fi
|
||||
|
||||
log "Enrollment wrapper completed"
|
||||
Reference in New Issue
Block a user