update
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
action="${1:-}"
|
action="${1:-}"
|
||||||
FOLDER='/opt/idssys/ta-proxmenu'
|
FOLDER='/opt/idssys/ta-proxmenu'
|
||||||
VERS='2026.7.25-55'
|
VERS='2026.7.25-57'
|
||||||
|
|
||||||
noupdate=' '
|
noupdate=' '
|
||||||
|
|
||||||
|
|||||||
+89
-9
@@ -117,7 +117,7 @@ if not isinstance(agent, dict) or not str(agent.get("id", "")).strip():
|
|||||||
}
|
}
|
||||||
|
|
||||||
TAPM_PULSE_AGENT_TOKEN_REQUEST_JSON() {
|
TAPM_PULSE_AGENT_TOKEN_REQUEST_JSON() {
|
||||||
printf '%s\n' '{"type":"pve","enableCommands":false}'
|
printf '%s\n' '{"type":"host","enableCommands":false}'
|
||||||
}
|
}
|
||||||
|
|
||||||
TAPM_PULSE_ONLINE_NODES_FROM_JSON() {
|
TAPM_PULSE_ONLINE_NODES_FROM_JSON() {
|
||||||
@@ -205,6 +205,58 @@ TAPM_PULSE_PROMPT_UNTIL_VALID() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAPM_PULSE_VALID_ADMIN_PASSWORD() {
|
||||||
|
local password="${1:-}"
|
||||||
|
|
||||||
|
TAPM_PULSE_PASSWORD="$password" python3 -c '
|
||||||
|
import os
|
||||||
|
password = os.environ["TAPM_PULSE_PASSWORD"]
|
||||||
|
raise SystemExit(
|
||||||
|
0 if len(password) >= 12 and len(password.encode("utf-8")) <= 72 else 1
|
||||||
|
)
|
||||||
|
' 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
TAPM_PULSE_SELECT_ADMIN_PASSWORD() {
|
||||||
|
local output_variable="$1"
|
||||||
|
local mode_variable="$2"
|
||||||
|
local selection candidate confirmation
|
||||||
|
local -a labels=(
|
||||||
|
"Generate a strong random password (recommended)"
|
||||||
|
"Enter a custom password"
|
||||||
|
)
|
||||||
|
local -a values=("generated" "custom")
|
||||||
|
|
||||||
|
SELECT_MENU "Pulse administrator password" labels values 0
|
||||||
|
selection="$MENU_SELECTION"
|
||||||
|
if [[ "$selection" == 'generated' ]]; then
|
||||||
|
printf -v "$output_variable" '%s' ''
|
||||||
|
printf -v "$mode_variable" '%s' 'Generated'
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
echo
|
||||||
|
read -r -s -p " Enter custom Pulse admin password (12+ characters): " candidate
|
||||||
|
echo
|
||||||
|
if ! TAPM_PULSE_VALID_ADMIN_PASSWORD "$candidate"; then
|
||||||
|
TAPM_PULSE_FAIL \
|
||||||
|
"The password must be at least 12 characters and no more than 72 bytes."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
read -r -s -p " Confirm custom Pulse admin password: " confirmation
|
||||||
|
echo
|
||||||
|
if [[ "$candidate" != "$confirmation" ]]; then
|
||||||
|
TAPM_PULSE_FAIL "The passwords did not match. Please try again."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
printf -v "$output_variable" '%s' "$candidate"
|
||||||
|
printf -v "$mode_variable" '%s' 'Custom'
|
||||||
|
unset candidate confirmation
|
||||||
|
return 0
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
TAPM_PULSE_FAIL() {
|
TAPM_PULSE_FAIL() {
|
||||||
echo -e "\n${idsCL[LightRed]}$1${idsCL[Default]}"
|
echo -e "\n${idsCL[LightRed]}$1${idsCL[Default]}"
|
||||||
return 1
|
return 1
|
||||||
@@ -223,7 +275,7 @@ TAPM_PULSE_CONFIRM_CREDENTIALS_SAVED() {
|
|||||||
echo
|
echo
|
||||||
echo -e "${idsCL[LightYellow]}============================================================================${idsCL[Default]}"
|
echo -e "${idsCL[LightYellow]}============================================================================${idsCL[Default]}"
|
||||||
echo -e "${idsCL[LightYellow]} IMPORTANT — SAVE THESE PULSE CREDENTIALS NOW${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]} They will not be displayed again by this installer.${idsCL[Default]}"
|
||||||
echo -e "${idsCL[LightYellow]}============================================================================${idsCL[Default]}"
|
echo -e "${idsCL[LightYellow]}============================================================================${idsCL[Default]}"
|
||||||
echo -e " Pulse URL: ${idsCL[LightCyan]}${pulse_url}${idsCL[Default]}"
|
echo -e " Pulse URL: ${idsCL[LightCyan]}${pulse_url}${idsCL[Default]}"
|
||||||
echo -e " Username: ${idsCL[White]}${admin_username}${idsCL[Default]}"
|
echo -e " Username: ${idsCL[White]}${admin_username}${idsCL[Default]}"
|
||||||
@@ -393,11 +445,16 @@ TAPM_PULSE_CONFIGURE_SECURITY() {
|
|||||||
local username_variable="$4"
|
local username_variable="$4"
|
||||||
local password_variable="$5"
|
local password_variable="$5"
|
||||||
local token_variable="$6"
|
local token_variable="$6"
|
||||||
|
local requested_password="${7:-}"
|
||||||
local bootstrap_output bootstrap_token generated_username generated_password generated_api_token
|
local bootstrap_output bootstrap_token generated_username generated_password generated_api_token
|
||||||
local request_file curl_config response security_ready='no' attempt
|
local request_file curl_config response security_ready='no' attempt
|
||||||
|
|
||||||
generated_username='admin'
|
generated_username='admin'
|
||||||
generated_password="Ta!9-$(openssl rand -hex 18)" || return 1
|
if [[ -n "$requested_password" ]]; then
|
||||||
|
generated_password="$requested_password"
|
||||||
|
else
|
||||||
|
generated_password="Ta!9-$(openssl rand -hex 18)" || return 1
|
||||||
|
fi
|
||||||
generated_api_token="$(openssl rand -hex 32)" || return 1
|
generated_api_token="$(openssl rand -hex 32)" || return 1
|
||||||
request_file="${temp_dir}/pulse-quick-setup.json"
|
request_file="${temp_dir}/pulse-quick-setup.json"
|
||||||
curl_config="${temp_dir}/pulse-quick-setup.curl"
|
curl_config="${temp_dir}/pulse-quick-setup.curl"
|
||||||
@@ -786,12 +843,19 @@ TAPM_PULSE_INSTALL_AGENT_LOCAL() {
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
if (( status == 0 )); then
|
if (( status == 0 )); then
|
||||||
|
if ! command -v sensors >/dev/null 2>&1; then
|
||||||
|
echo " Installing lm-sensors for Pulse host temperature telemetry..."
|
||||||
|
if ! DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||||
|
--no-install-recommends lm-sensors; then
|
||||||
|
echo " lm-sensors could not be installed; Pulse will continue without host temperature telemetry." >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
bash "$installer_file" \
|
bash "$installer_file" \
|
||||||
--url "$pulse_url" \
|
--url "$pulse_url" \
|
||||||
--token-file "$token_file" \
|
--token-file "$token_file" \
|
||||||
--hostname "$node" \
|
--hostname "$node" \
|
||||||
--enable-proxmox \
|
--enable-host \
|
||||||
--proxmox-type pve \
|
--disable-proxmox \
|
||||||
--non-interactive \
|
--non-interactive \
|
||||||
--insecure || status=$?
|
--insecure || status=$?
|
||||||
fi
|
fi
|
||||||
@@ -871,12 +935,20 @@ for artifact in \
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if ! command -v sensors >/dev/null 2>&1; then
|
||||||
|
echo " Installing lm-sensors for Pulse host temperature telemetry..."
|
||||||
|
if ! DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||||
|
--no-install-recommends lm-sensors; then
|
||||||
|
echo " lm-sensors could not be installed; Pulse will continue without host temperature telemetry." >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
bash "$installer_file" \
|
bash "$installer_file" \
|
||||||
--url "$pulse_url" \
|
--url "$pulse_url" \
|
||||||
--token-file "$token_file" \
|
--token-file "$token_file" \
|
||||||
--hostname "$node" \
|
--hostname "$node" \
|
||||||
--enable-proxmox \
|
--enable-host \
|
||||||
--proxmox-type pve \
|
--disable-proxmox \
|
||||||
--non-interactive \
|
--non-interactive \
|
||||||
--insecure
|
--insecure
|
||||||
systemctl is-active --quiet pulse-agent
|
systemctl is-active --quiet pulse-agent
|
||||||
@@ -948,7 +1020,8 @@ TAPM_DEPLOY_PULSE_LXC() {
|
|||||||
local arch archive_name base_url installer archive signature installer_signature
|
local arch archive_name base_url installer archive signature installer_signature
|
||||||
local memory disk cores cpulimit swap onboot firewall unprivileged nameserver startup
|
local memory disk cores cpulimit swap onboot firewall unprivileged nameserver startup
|
||||||
local network_config choice add_ha='no' auto_updates='yes' container_ip timezone temp_dir
|
local network_config choice add_ha='no' auto_updates='yes' container_ip timezone temp_dir
|
||||||
local default_bridge pulse_url admin_username admin_password primary_api_token
|
local default_bridge pulse_url admin_username admin_password admin_password_mode
|
||||||
|
local primary_api_token
|
||||||
local cluster_status='Registration failed'
|
local cluster_status='Registration failed'
|
||||||
local agent_status='Skipped because cluster registration failed'
|
local agent_status='Skipped because cluster registration failed'
|
||||||
local container_created=0
|
local container_created=0
|
||||||
@@ -1064,6 +1137,11 @@ TAPM_DEPLOY_PULSE_LXC() {
|
|||||||
TAPM_ISO_NFS_SELECT_STORAGE root_storage \
|
TAPM_ISO_NFS_SELECT_STORAGE root_storage \
|
||||||
"Pulse root filesystem storage" "$default_root_storage" || return 1
|
"Pulse root filesystem storage" "$default_root_storage" || return 1
|
||||||
|
|
||||||
|
admin_password=''
|
||||||
|
admin_password_mode='Generated'
|
||||||
|
TAPM_PULSE_SELECT_ADMIN_PASSWORD \
|
||||||
|
admin_password admin_password_mode || return 1
|
||||||
|
|
||||||
default_root_storage="$(
|
default_root_storage="$(
|
||||||
pvesm status --content vztmpl 2>/dev/null |
|
pvesm status --content vztmpl 2>/dev/null |
|
||||||
awk 'NR > 1 && $3 == "active" { print $1; exit }'
|
awk 'NR > 1 && $3 == "active" { print $1; exit }'
|
||||||
@@ -1097,6 +1175,7 @@ TAPM_DEPLOY_PULSE_LXC() {
|
|||||||
echo " Firewall: enabled"
|
echo " Firewall: enabled"
|
||||||
echo " Automatic update: ${auto_updates}"
|
echo " Automatic update: ${auto_updates}"
|
||||||
echo " Proxmox HA: ${add_ha}"
|
echo " Proxmox HA: ${add_ha}"
|
||||||
|
echo " Admin password: ${admin_password_mode}"
|
||||||
echo
|
echo
|
||||||
read -r -p " Create this Pulse container (type yes to continue)? " choice
|
read -r -p " Create this Pulse container (type yes to continue)? " choice
|
||||||
[[ "$choice" =~ ^[Yy][Ee][Ss]$ ]] || {
|
[[ "$choice" =~ ^[Yy][Ee][Ss]$ ]] || {
|
||||||
@@ -1249,7 +1328,8 @@ TAPM_DEPLOY_PULSE_LXC() {
|
|||||||
echo -e "\n${idsCL[LightCyan]}Configuring Pulse administrator security...${idsCL[Default]}"
|
echo -e "\n${idsCL[LightCyan]}Configuring Pulse administrator security...${idsCL[Default]}"
|
||||||
if ! TAPM_PULSE_CONFIGURE_SECURITY \
|
if ! TAPM_PULSE_CONFIGURE_SECURITY \
|
||||||
"$ctid" "$pulse_url" "$temp_dir" \
|
"$ctid" "$pulse_url" "$temp_dir" \
|
||||||
admin_username admin_password primary_api_token; then
|
admin_username admin_password primary_api_token \
|
||||||
|
"$admin_password"; then
|
||||||
pct exec "$ctid" -- rm -f \
|
pct exec "$ctid" -- rm -f \
|
||||||
/tmp/install.sh "/tmp/${archive_name}" "/tmp/${archive_name}.sshsig" || true
|
/tmp/install.sh "/tmp/${archive_name}" "/tmp/${archive_name}.sshsig" || true
|
||||||
TAPM_CLEAN_TEMP_DIR "$temp_dir"
|
TAPM_CLEAN_TEMP_DIR "$temp_dir"
|
||||||
|
|||||||
+15
-2
@@ -49,9 +49,9 @@ assert_success "registered Pulse agent response accepted" \
|
|||||||
'{"agent":{"id":"agent-123","hostname":"pve1"}}'
|
'{"agent":{"id":"agent-123","hostname":"pve1"}}'
|
||||||
assert_failure "missing Pulse agent ID rejected" \
|
assert_failure "missing Pulse agent ID rejected" \
|
||||||
TAPM_PULSE_AGENT_REGISTERED_FROM_RESPONSE '{"agent":{"hostname":"pve1"}}'
|
TAPM_PULSE_AGENT_REGISTERED_FROM_RESPONSE '{"agent":{"hostname":"pve1"}}'
|
||||||
assert_equal '{"type":"pve","enableCommands":false}' \
|
assert_equal '{"type":"host","enableCommands":false}' \
|
||||||
"$(TAPM_PULSE_AGENT_TOKEN_REQUEST_JSON)" \
|
"$(TAPM_PULSE_AGENT_TOKEN_REQUEST_JSON)" \
|
||||||
"Proxmox-specific agent enrollment requested with commands disabled"
|
"host telemetry enrollment requested with commands disabled"
|
||||||
|
|
||||||
setup_token='0123456789abcdef0123456789abcdef'
|
setup_token='0123456789abcdef0123456789abcdef'
|
||||||
setup_host='https://pve1.example.test:8006'
|
setup_host='https://pve1.example.test:8006'
|
||||||
@@ -147,6 +147,19 @@ assert_success "valid Pulse VLAN" TAPM_PULSE_VALID_OPTIONAL_VLAN 4094
|
|||||||
assert_failure "Pulse VLAN zero rejected" TAPM_PULSE_VALID_OPTIONAL_VLAN 0
|
assert_failure "Pulse VLAN zero rejected" TAPM_PULSE_VALID_OPTIONAL_VLAN 0
|
||||||
assert_success "blank Pulse VLAN accepted" TAPM_PULSE_VALID_OPTIONAL_VLAN ''
|
assert_success "blank Pulse VLAN accepted" TAPM_PULSE_VALID_OPTIONAL_VLAN ''
|
||||||
|
|
||||||
|
assert_success "12-character Pulse admin password accepted" \
|
||||||
|
TAPM_PULSE_VALID_ADMIN_PASSWORD '123456789012'
|
||||||
|
assert_success "72-byte Pulse admin password accepted" \
|
||||||
|
TAPM_PULSE_VALID_ADMIN_PASSWORD \
|
||||||
|
'123456789012345678901234567890123456789012345678901234567890123456789012'
|
||||||
|
assert_failure "short Pulse admin password rejected" \
|
||||||
|
TAPM_PULSE_VALID_ADMIN_PASSWORD '12345678901'
|
||||||
|
assert_failure "multibyte Pulse admin password still requires 12 characters" \
|
||||||
|
TAPM_PULSE_VALID_ADMIN_PASSWORD 'éééééé'
|
||||||
|
assert_failure "Pulse admin password above bcrypt limit rejected" \
|
||||||
|
TAPM_PULSE_VALID_ADMIN_PASSWORD \
|
||||||
|
'1234567890123456789012345678901234567890123456789012345678901234567890123'
|
||||||
|
|
||||||
resources='[
|
resources='[
|
||||||
{"type":"lxc","name":"pulse-a","tags":"tapm;pulse"},
|
{"type":"lxc","name":"pulse-a","tags":"tapm;pulse"},
|
||||||
{"type":"qemu","name":"unrelated"}
|
{"type":"qemu","name":"unrelated"}
|
||||||
|
|||||||
Reference in New Issue
Block a user