fix: show Removed Docker Hosts section in UI for re-enrollment
The 'Removed Docker Hosts' section was not appearing in Settings -> Agents even when hosts were blocked from re-enrolling. This prevented users from using the 'Allow re-enroll' button to unblock their Docker agents. Root cause: The WebSocket store was missing: 1. The 'removedDockerHosts' property in its initial state 2. A handler to process removedDockerHosts data from WebSocket messages This meant the backend was correctly sending the data, but the frontend was completely ignoring it. Changes: - Add removedDockerHosts to WebSocket store initial state and message handler - Add removedDockerHosts to App.tsx fallback state for consistency - Add missing BroadcastState call after AllowDockerHostReenroll succeeds Also includes previous fixes from this session: - Add PULSE_AGENT_URL as alias for PULSE_AGENT_CONNECT_URL (config.go) - Add runtime Docker/Podman auto-detection in pulse-agent (main.go) Fixes issue reported by darthrater78 in discussion #845
This commit is contained in:
parent
b4db8b160b
commit
97c851c16c
5 changed files with 47 additions and 0 deletions
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -146,6 +147,20 @@ func main() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Auto-detect Docker/Podman if not explicitly configured
|
||||||
|
if !cfg.EnableDocker && !cfg.DockerConfigured {
|
||||||
|
// Check for docker binary
|
||||||
|
if _, err := exec.LookPath("docker"); err == nil {
|
||||||
|
logger.Info().Msg("Auto-detected Docker binary, enabling Docker monitoring")
|
||||||
|
cfg.EnableDocker = true
|
||||||
|
} else if _, err := exec.LookPath("podman"); err == nil {
|
||||||
|
logger.Info().Msg("Auto-detected Podman binary, enabling Docker monitoring")
|
||||||
|
cfg.EnableDocker = true
|
||||||
|
} else {
|
||||||
|
logger.Debug().Msg("Docker/Podman not found, skipping Docker monitoring")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 9. Start Docker Agent (if enabled)
|
// 9. Start Docker Agent (if enabled)
|
||||||
var dockerAgent *dockeragent.Agent
|
var dockerAgent *dockeragent.Agent
|
||||||
if cfg.EnableDocker {
|
if cfg.EnableDocker {
|
||||||
|
|
@ -324,6 +339,7 @@ type Config struct {
|
||||||
// Module flags
|
// Module flags
|
||||||
EnableHost bool
|
EnableHost bool
|
||||||
EnableDocker bool
|
EnableDocker bool
|
||||||
|
DockerConfigured bool
|
||||||
EnableKubernetes bool
|
EnableKubernetes bool
|
||||||
EnableProxmox bool
|
EnableProxmox bool
|
||||||
ProxmoxType string // "pve", "pbs", or "" for auto-detect
|
ProxmoxType string // "pve", "pbs", or "" for auto-detect
|
||||||
|
|
@ -460,6 +476,16 @@ func loadConfig() Config {
|
||||||
kubeIncludeNamespaces := gatherCSV(envKubeIncludeNamespaces, kubeIncludeNamespaceFlags)
|
kubeIncludeNamespaces := gatherCSV(envKubeIncludeNamespaces, kubeIncludeNamespaceFlags)
|
||||||
kubeExcludeNamespaces := gatherCSV(envKubeExcludeNamespaces, kubeExcludeNamespaceFlags)
|
kubeExcludeNamespaces := gatherCSV(envKubeExcludeNamespaces, kubeExcludeNamespaceFlags)
|
||||||
|
|
||||||
|
// Check if Docker was explicitly configured via flag or env
|
||||||
|
dockerConfigured := envEnableDocker != ""
|
||||||
|
if !dockerConfigured {
|
||||||
|
flag.Visit(func(f *flag.Flag) {
|
||||||
|
if f.Name == "enable-docker" {
|
||||||
|
dockerConfigured = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return Config{
|
return Config{
|
||||||
PulseURL: pulseURL,
|
PulseURL: pulseURL,
|
||||||
APIToken: token,
|
APIToken: token,
|
||||||
|
|
@ -471,6 +497,7 @@ func loadConfig() Config {
|
||||||
LogLevel: logLevel,
|
LogLevel: logLevel,
|
||||||
EnableHost: *enableHostFlag,
|
EnableHost: *enableHostFlag,
|
||||||
EnableDocker: *enableDockerFlag,
|
EnableDocker: *enableDockerFlag,
|
||||||
|
DockerConfigured: dockerConfigured,
|
||||||
EnableKubernetes: *enableKubernetesFlag,
|
EnableKubernetes: *enableKubernetesFlag,
|
||||||
EnableProxmox: *enableProxmoxFlag,
|
EnableProxmox: *enableProxmoxFlag,
|
||||||
ProxmoxType: strings.TrimSpace(*proxmoxTypeFlag),
|
ProxmoxType: strings.TrimSpace(*proxmoxTypeFlag),
|
||||||
|
|
|
||||||
|
|
@ -268,6 +268,7 @@ function App() {
|
||||||
vms: [],
|
vms: [],
|
||||||
containers: [],
|
containers: [],
|
||||||
dockerHosts: [],
|
dockerHosts: [],
|
||||||
|
removedDockerHosts: [],
|
||||||
hosts: [],
|
hosts: [],
|
||||||
storage: [],
|
storage: [],
|
||||||
cephClusters: [],
|
cephClusters: [],
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import type {
|
||||||
DockerHost,
|
DockerHost,
|
||||||
Host,
|
Host,
|
||||||
KubernetesCluster,
|
KubernetesCluster,
|
||||||
|
RemovedDockerHost,
|
||||||
RemovedKubernetesCluster,
|
RemovedKubernetesCluster,
|
||||||
} from '@/types/api';
|
} from '@/types/api';
|
||||||
import type { ActivationState as ActivationStateType } from '@/types/alerts';
|
import type { ActivationState as ActivationStateType } from '@/types/alerts';
|
||||||
|
|
@ -32,6 +33,7 @@ export function createWebSocketStore(url: string) {
|
||||||
vms: [],
|
vms: [],
|
||||||
containers: [],
|
containers: [],
|
||||||
dockerHosts: [],
|
dockerHosts: [],
|
||||||
|
removedDockerHosts: [],
|
||||||
kubernetesClusters: [],
|
kubernetesClusters: [],
|
||||||
removedKubernetesClusters: [],
|
removedKubernetesClusters: [],
|
||||||
hosts: [],
|
hosts: [],
|
||||||
|
|
@ -579,6 +581,12 @@ export function createWebSocketStore(url: string) {
|
||||||
setState('hosts', reconcile(processedHosts, { key: 'id' }));
|
setState('hosts', reconcile(processedHosts, { key: 'id' }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (message.data.removedDockerHosts !== undefined) {
|
||||||
|
const removed = Array.isArray(message.data.removedDockerHosts)
|
||||||
|
? (message.data.removedDockerHosts as RemovedDockerHost[])
|
||||||
|
: [];
|
||||||
|
setState('removedDockerHosts', reconcile(removed, { key: 'id' }));
|
||||||
|
}
|
||||||
if (message.data.kubernetesClusters !== undefined) {
|
if (message.data.kubernetesClusters !== undefined) {
|
||||||
const clusters = Array.isArray(message.data.kubernetesClusters)
|
const clusters = Array.isArray(message.data.kubernetesClusters)
|
||||||
? (message.data.kubernetesClusters as KubernetesCluster[])
|
? (message.data.kubernetesClusters as KubernetesCluster[])
|
||||||
|
|
|
||||||
|
|
@ -338,6 +338,9 @@ func (h *DockerAgentHandlers) HandleAllowReenroll(w http.ResponseWriter, r *http
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcast updated state to ensure the frontend reflects the change
|
||||||
|
go h.wsHub.BroadcastState(h.monitor.GetState().ToFrontend())
|
||||||
|
|
||||||
if err := utils.WriteJSONResponse(w, map[string]any{
|
if err := utils.WriteJSONResponse(w, map[string]any{
|
||||||
"success": true,
|
"success": true,
|
||||||
"hostId": hostID,
|
"hostId": hostID,
|
||||||
|
|
|
||||||
|
|
@ -1230,6 +1230,14 @@ func Load() (*Config, error) {
|
||||||
log.Debug().Str("key_file", tlsKeyFile).Msg("TLS key file from env var")
|
log.Debug().Str("key_file", tlsKeyFile).Msg("TLS key file from env var")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Support PULSE_AGENT_URL as an alias for PULSE_AGENT_CONNECT_URL
|
||||||
|
// (Check this first so standard PULSE_AGENT_CONNECT_URL takes precedence if both set)
|
||||||
|
if agentURL := utils.GetenvTrim("PULSE_AGENT_URL"); agentURL != "" {
|
||||||
|
cfg.AgentConnectURL = agentURL
|
||||||
|
cfg.EnvOverrides["PULSE_AGENT_CONNECT_URL"] = true
|
||||||
|
log.Info().Str("url", agentURL).Msg("Using dedicated agent connect URL from PULSE_AGENT_URL")
|
||||||
|
}
|
||||||
|
|
||||||
if agentConnectURL := utils.GetenvTrim("PULSE_AGENT_CONNECT_URL"); agentConnectURL != "" {
|
if agentConnectURL := utils.GetenvTrim("PULSE_AGENT_CONNECT_URL"); agentConnectURL != "" {
|
||||||
cfg.AgentConnectURL = agentConnectURL
|
cfg.AgentConnectURL = agentConnectURL
|
||||||
cfg.EnvOverrides["PULSE_AGENT_CONNECT_URL"] = true
|
cfg.EnvOverrides["PULSE_AGENT_CONNECT_URL"] = true
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue