diff --git a/agents/patchmon_install.sh b/agents/patchmon_install.sh index 0950e37..1dd4944 100644 --- a/agents/patchmon_install.sh +++ b/agents/patchmon_install.sh @@ -109,14 +109,32 @@ cleanup_old_files() { # Run cleanup at start cleanup_old_files +# Generate or retrieve machine ID +get_machine_id() { + # Try multiple sources for machine ID + if [[ -f /etc/machine-id ]]; then + cat /etc/machine-id + elif [[ -f /var/lib/dbus/machine-id ]]; then + cat /var/lib/dbus/machine-id + else + # Fallback: generate from hardware info (less ideal but works) + echo "patchmon-$(cat /sys/class/dmi/id/product_uuid 2>/dev/null || cat /proc/sys/kernel/random/uuid)" + fi +} + # Parse arguments from environment (passed via HTTP headers) if [[ -z "$PATCHMON_URL" ]] || [[ -z "$API_ID" ]] || [[ -z "$API_KEY" ]]; then error "Missing required parameters. This script should be called via the PatchMon web interface." fi +# Get unique machine ID for this host +MACHINE_ID=$(get_machine_id) +export MACHINE_ID + info "๐Ÿš€ Starting PatchMon Agent Installation..." info "๐Ÿ“‹ Server: $PATCHMON_URL" info "๐Ÿ”‘ API ID: ${API_ID:0:16}..." +info "๐Ÿ†” Machine ID: ${MACHINE_ID:0:16}..." # Display diagnostic information echo "" @@ -261,6 +279,33 @@ if [[ -f "/var/log/patchmon-agent.log" ]]; then fi # Step 4: Test the configuration +# Check if this machine is already enrolled +info "๐Ÿ” Checking if machine is already enrolled..." +existing_check=$(curl $CURL_FLAGS -s -X POST \ + -H "X-API-ID: $API_ID" \ + -H "X-API-KEY: $API_KEY" \ + -H "Content-Type: application/json" \ + -d "{\"machine_id\": \"$MACHINE_ID\"}" \ + "$PATCHMON_URL/api/v1/hosts/check-machine-id" \ + -w "\n%{http_code}" 2>&1) + +http_code=$(echo "$existing_check" | tail -n 1) +response_body=$(echo "$existing_check" | sed '$d') + +if [[ "$http_code" == "200" ]]; then + already_enrolled=$(echo "$response_body" | jq -r '.exists' 2>/dev/null || echo "false") + if [[ "$already_enrolled" == "true" ]]; then + warning "โš ๏ธ This machine is already enrolled in PatchMon" + info "Machine ID: $MACHINE_ID" + info "Existing host: $(echo "$response_body" | jq -r '.host.friendly_name' 2>/dev/null)" + info "" + info "The agent will be reinstalled/updated with existing credentials." + echo "" + else + success "โœ… Machine not yet enrolled - proceeding with installation" + fi +fi + info "๐Ÿงช Testing API credentials and connectivity..." if /usr/local/bin/patchmon-agent.sh test; then success "โœ… TEST: API credentials are valid and server is reachable" diff --git a/agents/proxmox_auto_enroll.sh b/agents/proxmox_auto_enroll.sh index 6b5b613..ebfb20f 100755 --- a/agents/proxmox_auto_enroll.sh +++ b/agents/proxmox_auto_enroll.sh @@ -4,7 +4,7 @@ set -eo pipefail # Exit on error, pipe failures (removed -u as we handle unset # Trap to catch errors only (not normal exits) trap 'echo "[ERROR] Script failed at line $LINENO with exit code $?"' ERR -SCRIPT_VERSION="1.3.0" +SCRIPT_VERSION="2.0.0" echo "[DEBUG] Script Version: $SCRIPT_VERSION ($(date +%Y-%m-%d\ %H:%M:%S))" # ============================================================================= @@ -151,12 +151,16 @@ while IFS= read -r line; do hostname=$(timeout 5 pct exec "$vmid" -- hostname 2>/dev/null /dev/null /dev/null /dev/null || cat /var/lib/dbus/machine-id 2>/dev/null || echo 'proxmox-lxc-$vmid-'$(cat /proc/sys/kernel/random/uuid)" /dev/null || echo "proxmox-lxc-$vmid-unknown") friendly_name="${HOST_PREFIX}${hostname}" info " Hostname: $hostname" info " IP Address: $ip_address" info " OS: $os_info" + info " Machine ID: ${machine_id:0:16}..." if [[ "$DRY_RUN" == "true" ]]; then info " [DRY RUN] Would enroll: $friendly_name" @@ -174,6 +178,7 @@ while IFS= read -r line; do -H "Content-Type: application/json" \ -d "{ \"friendly_name\": \"$friendly_name\", + \"machine_id\": \"$machine_id\", \"metadata\": { \"vmid\": \"$vmid\", \"proxmox_node\": \"$(hostname)\", diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 5db7dcb..adca449 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -60,7 +60,8 @@ model host_repositories { model hosts { id String @id - friendly_name String @unique + machine_id String @unique + friendly_name String ip String? os_type String os_version String @@ -92,6 +93,10 @@ model hosts { host_repositories host_repositories[] host_groups host_groups? @relation(fields: [host_group_id], references: [id]) update_history update_history[] + + @@index([machine_id]) + @@index([friendly_name]) + @@index([hostname]) } model packages {