This commit is contained in:
David Schroeder
2026-07-25 21:09:23 -05:00
parent bb44ca81f7
commit 2b8b2c8f6f
3 changed files with 120 additions and 47 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
action="${1:-}"
FOLDER='/opt/idssys/ta-proxmenu'
VERS='2026.7.25-49'
VERS='2026.7.25-50'
noupdate=' '
+109 -46
View File
@@ -26,6 +26,10 @@ TAPM_PULSE_VALID_POSITIVE_INTEGER() {
[[ "${1:-}" =~ ^[1-9][0-9]*$ ]]
}
TAPM_PULSE_VALID_NONNEGATIVE_INTEGER() {
[[ "${1:-}" =~ ^[0-9]+$ ]]
}
TAPM_PULSE_VALID_PORT() {
[[ "${1:-}" =~ ^[0-9]+$ ]] && (( 10#$1 >= 1 && 10#$1 <= 65535 ))
}
@@ -46,6 +50,23 @@ TAPM_PULSE_VALID_IPV4_CIDR() {
done
}
TAPM_PULSE_VALID_IPV4() {
local value="${1:-}"
[[ "$value" != */* ]] && TAPM_PULSE_VALID_IPV4_CIDR "${value}/32"
}
TAPM_PULSE_VALID_OPTIONAL_IPV4_CIDR() {
[[ -z "${1:-}" ]] || TAPM_PULSE_VALID_IPV4_CIDR "$1"
}
TAPM_PULSE_VALID_OPTIONAL_VLAN() {
local value="${1:-}"
[[ -z "$value" ]] ||
{ [[ "$value" =~ ^[0-9]+$ ]] && (( 10#$value >= 1 && 10#$value <= 4094 )); }
}
TAPM_PULSE_ARCH() {
case "${1:-}" in
x86_64|amd64) printf 'amd64\n';;
@@ -147,11 +168,57 @@ TAPM_PULSE_PROMPT() {
fi
}
TAPM_PULSE_PROMPT_UNTIL_VALID() {
local variable="$1"
local label="$2"
local default_value="$3"
local validator="$4"
local error_message="$5"
local candidate
while true; do
TAPM_PULSE_PROMPT candidate "$label" "$default_value"
if "$validator" "$candidate"; then
printf -v "$variable" '%s' "$candidate"
return 0
fi
TAPM_PULSE_FAIL "$error_message"
done
}
TAPM_PULSE_FAIL() {
echo -e "\n${idsCL[LightRed]}$1${idsCL[Default]}"
return 1
}
TAPM_PULSE_CONFIRM_CREDENTIALS_SAVED() {
local pulse_url="$1"
local admin_username="$2"
local admin_password="$3"
local primary_api_token="$4"
local installed="$5"
local failed="$6"
local acknowledgement
while true; do
echo
echo -e "${idsCL[LightYellow]}============================================================================${idsCL[Default]}"
echo -e "${idsCL[LightYellow]} IMPORTANT — SAVE THESE PULSE CREDENTIALS NOW${idsCL[Default]}"
echo -e "${idsCL[LightYellow]} They are generated for this installation and will not be displayed again.${idsCL[Default]}"
echo -e "${idsCL[LightYellow]}============================================================================${idsCL[Default]}"
echo -e " Pulse URL: ${idsCL[LightCyan]}${pulse_url}${idsCL[Default]}"
echo -e " Username: ${idsCL[White]}${admin_username}${idsCL[Default]}"
echo -e " Password: ${idsCL[LightGreen]}${admin_password}${idsCL[Default]}"
echo -e " API token: ${idsCL[LightGreen]}${primary_api_token}${idsCL[Default]}"
echo " Agents: ${installed} installed, ${failed} failed or offline"
echo -e "${idsCL[LightYellow]}============================================================================${idsCL[Default]}"
echo
read -r -p " Type saved after recording the password and API token: " acknowledgement
[[ "$acknowledgement" =~ ^[Ss][Aa][Vv][Ee][Dd]$ ]] && return 0
echo -e "\n${idsCL[LightYellow]}The credentials remain above. Save them before continuing.${idsCL[Default]}"
done
}
TAPM_PULSE_SET_BRIDGE_FROM_SELECTION() {
local variable="$1"
local selection="${2:-}"
@@ -632,35 +699,38 @@ TAPM_DEPLOY_PULSE_LXC() {
{ TAPM_PULSE_FAIL "Configured Pulse port '${pulse_port}' is invalid."; return 1; }
default_ctid="$(pvesh get /cluster/nextid 2>/dev/null || true)"
TAPM_PULSE_PROMPT ctid "Container ID" "$default_ctid"
TAPM_PULSE_VALID_CTID "$ctid" ||
{ TAPM_PULSE_FAIL "The container ID is invalid."; return 1; }
if pct status "$ctid" >/dev/null 2>&1; then
TAPM_PULSE_FAIL "Container ${ctid} already exists; no changes were made."
return 1
fi
while true; do
TAPM_PULSE_PROMPT_UNTIL_VALID ctid "Container ID" "$default_ctid" \
TAPM_PULSE_VALID_CTID "The container ID must be a whole number of at least three digits."
if ! pct status "$ctid" >/dev/null 2>&1; then
break
fi
TAPM_PULSE_FAIL "Container ${ctid} already exists. Choose another container ID."
default_ctid="$(pvesh get /cluster/nextid 2>/dev/null || true)"
done
TAPM_PULSE_PROMPT hostname "Container hostname" "Pulse-Monitor"
TAPM_PULSE_VALID_HOSTNAME "$hostname" ||
{ TAPM_PULSE_FAIL "The hostname is invalid."; return 1; }
TAPM_PULSE_PROMPT_UNTIL_VALID hostname "Container hostname" "Pulse-Monitor" \
TAPM_PULSE_VALID_HOSTNAME \
"The hostname must contain only letters, numbers, periods, and hyphens."
read -r -p " Customize CPU, memory, disk, or swap? [y/N] " choice
while true; do
read -r -p " Customize CPU, memory, disk, or swap? [y/N] " choice
[[ -z "$choice" || "$choice" =~ ^[YyNn]$ ]] && break
TAPM_PULSE_FAIL "Enter y or n."
done
if [[ "$choice" =~ ^[Yy]$ ]]; then
TAPM_PULSE_PROMPT memory "Memory in MiB" "$memory"
TAPM_PULSE_VALID_POSITIVE_INTEGER "$memory" ||
{ TAPM_PULSE_FAIL "Memory must be a positive whole number."; return 1; }
TAPM_PULSE_PROMPT disk "Root disk size in GiB" "$disk"
TAPM_PULSE_VALID_POSITIVE_INTEGER "$disk" ||
{ TAPM_PULSE_FAIL "Disk size must be a positive whole number."; return 1; }
TAPM_PULSE_PROMPT cores "CPU cores" "$cores"
TAPM_PULSE_VALID_POSITIVE_INTEGER "$cores" ||
{ TAPM_PULSE_FAIL "CPU cores must be a positive whole number."; return 1; }
TAPM_PULSE_PROMPT cpulimit "CPU limit (0 for unlimited)" "$cpulimit"
[[ "$cpulimit" =~ ^[0-9]+$ ]] ||
{ TAPM_PULSE_FAIL "CPU limit must be zero or a positive whole number."; return 1; }
TAPM_PULSE_PROMPT swap "Swap in MiB" "$swap"
[[ "$swap" =~ ^[0-9]+$ ]] ||
{ TAPM_PULSE_FAIL "Swap must be zero or a positive whole number."; return 1; }
TAPM_PULSE_PROMPT_UNTIL_VALID memory "Memory in MiB" "$memory" \
TAPM_PULSE_VALID_POSITIVE_INTEGER "Memory must be a positive whole number."
TAPM_PULSE_PROMPT_UNTIL_VALID disk "Root disk size in GiB" "$disk" \
TAPM_PULSE_VALID_POSITIVE_INTEGER "Disk size must be a positive whole number."
TAPM_PULSE_PROMPT_UNTIL_VALID cores "CPU cores" "$cores" \
TAPM_PULSE_VALID_POSITIVE_INTEGER "CPU cores must be a positive whole number."
TAPM_PULSE_PROMPT_UNTIL_VALID cpulimit "CPU limit (0 for unlimited)" "$cpulimit" \
TAPM_PULSE_VALID_NONNEGATIVE_INTEGER \
"CPU limit must be zero or a positive whole number."
TAPM_PULSE_PROMPT_UNTIL_VALID swap "Swap in MiB" "$swap" \
TAPM_PULSE_VALID_NONNEGATIVE_INTEGER \
"Swap must be zero or a positive whole number."
fi
echo
@@ -670,23 +740,20 @@ TAPM_DEPLOY_PULSE_LXC() {
)"
[[ -n "$default_bridge" ]] || default_bridge='vmbr0'
TAPM_PULSE_SELECT_BRIDGE bridge "$default_bridge" || return 1
TAPM_PULSE_PROMPT address_cidr \
"Static IPv4 address with prefix (leave blank for DHCP)"
TAPM_PULSE_PROMPT_UNTIL_VALID address_cidr \
"Static IPv4 address with prefix (leave blank for DHCP)" '' \
TAPM_PULSE_VALID_OPTIONAL_IPV4_CIDR \
"Enter a valid IPv4 CIDR such as 10.10.2.30/16, or leave it blank for DHCP."
if [[ -n "$address_cidr" ]]; then
TAPM_PULSE_VALID_IPV4_CIDR "$address_cidr" ||
{ TAPM_PULSE_FAIL "The static IPv4 address is invalid."; return 1; }
TAPM_PULSE_PROMPT gateway "IPv4 gateway"
TAPM_PULSE_VALID_IPV4_CIDR "${gateway}/32" ||
{ TAPM_PULSE_FAIL "The IPv4 gateway is invalid."; return 1; }
TAPM_PULSE_PROMPT_UNTIL_VALID gateway "IPv4 gateway" '' \
TAPM_PULSE_VALID_IPV4 "Enter a valid IPv4 gateway."
fi
TAPM_PULSE_PROMPT nameserver \
"DNS servers, space-separated (leave blank to inherit host settings)"
TAPM_PULSE_PROMPT vlan_id "VLAN ID (leave blank for untagged)"
if [[ -n "$vlan_id" ]] &&
{ [[ ! "$vlan_id" =~ ^[0-9]+$ ]] || (( vlan_id < 1 || vlan_id > 4094 )); }; then
TAPM_PULSE_FAIL "The VLAN ID must be between 1 and 4094."
return 1
fi
TAPM_PULSE_PROMPT_UNTIL_VALID vlan_id \
"VLAN ID (leave blank for untagged)" '' \
TAPM_PULSE_VALID_OPTIONAL_VLAN \
"The VLAN ID must be between 1 and 4094, or blank for untagged."
TAPM_PULSE_CLUSTER_HA_ENABLED && add_ha='yes'
@@ -930,11 +997,7 @@ TAPM_DEPLOY_PULSE_LXC() {
echo
echo -e "${idsCL[Green]}Pulse ${release} was installed and its service is active.${idsCL[Default]}"
echo -e " Open: ${idsCL[LightCyan]}${pulse_url}${idsCL[Default]}"
echo " Username: ${admin_username}"
echo " Password: ${admin_password}"
echo " API token: ${primary_api_token}"
echo " Agents: ${TAPM_PULSE_AGENTS_INSTALLED} installed, ${TAPM_PULSE_AGENTS_FAILED} failed or offline"
echo
echo -e "${idsCL[LightYellow]}Save the generated password and API token now; they are only shown once.${idsCL[Default]}"
TAPM_PULSE_CONFIRM_CREDENTIALS_SAVED \
"$pulse_url" "$admin_username" "$admin_password" "$primary_api_token" \
"$TAPM_PULSE_AGENTS_INSTALLED" "$TAPM_PULSE_AGENTS_FAILED"
}
+10
View File
@@ -63,10 +63,20 @@ assert_success "valid Pulse hostname" TAPM_PULSE_VALID_HOSTNAME pulse-monitor
assert_failure "invalid Pulse hostname" TAPM_PULSE_VALID_HOSTNAME 'pulse monitor'
assert_success "valid positive integer" TAPM_PULSE_VALID_POSITIVE_INTEGER 1024
assert_failure "zero is not positive" TAPM_PULSE_VALID_POSITIVE_INTEGER 0
assert_success "zero is a valid nonnegative integer" \
TAPM_PULSE_VALID_NONNEGATIVE_INTEGER 0
assert_failure "negative integer rejected" TAPM_PULSE_VALID_NONNEGATIVE_INTEGER -1
assert_success "valid Pulse port" TAPM_PULSE_VALID_PORT 7655
assert_failure "Pulse port too high" TAPM_PULSE_VALID_PORT 65536
assert_success "valid Pulse IPv4 CIDR" TAPM_PULSE_VALID_IPV4_CIDR 10.10.1.50/24
assert_failure "invalid Pulse IPv4 CIDR" TAPM_PULSE_VALID_IPV4_CIDR 10.10.1.500/24
assert_success "valid Pulse gateway" TAPM_PULSE_VALID_IPV4 10.10.0.1
assert_failure "gateway CIDR rejected" TAPM_PULSE_VALID_IPV4 10.10.0.1/16
assert_success "blank optional Pulse address accepted" \
TAPM_PULSE_VALID_OPTIONAL_IPV4_CIDR ''
assert_success "valid Pulse VLAN" TAPM_PULSE_VALID_OPTIONAL_VLAN 4094
assert_failure "Pulse VLAN zero rejected" TAPM_PULSE_VALID_OPTIONAL_VLAN 0
assert_success "blank Pulse VLAN accepted" TAPM_PULSE_VALID_OPTIONAL_VLAN ''
resources='[
{"type":"lxc","name":"pulse-a","tags":"tapm;pulse"},