mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-11-02 21:13:45 +00:00
Update PatchMon version to 1.2.7
- Updated agent script version to 1.2.7 - Updated all package.json files to version 1.2.7 - Updated backend version references - Updated setup script version references - Fixed agent file path issues in API endpoints - Fixed linting issues (Node.js imports, unused variables, accessibility) - Created comprehensive version update guide in patchmon-admin/READMEs/
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
# PatchMon Agent Script v1.2.6
|
||||
# PatchMon Agent Script v1.2.7
|
||||
# This script sends package update information to the PatchMon server using API credentials
|
||||
|
||||
# Configuration
|
||||
PATCHMON_SERVER="${PATCHMON_SERVER:-http://localhost:3001}"
|
||||
API_VERSION="v1"
|
||||
AGENT_VERSION="1.2.6"
|
||||
AGENT_VERSION="1.2.7"
|
||||
CONFIG_FILE="/etc/patchmon/agent.conf"
|
||||
CREDENTIALS_FILE="/etc/patchmon/credentials"
|
||||
LOG_FILE="/var/log/patchmon-agent.log"
|
||||
@@ -144,7 +144,7 @@ EOF
|
||||
test_credentials() {
|
||||
load_credentials
|
||||
|
||||
local response=$(curl -ksv -X POST \
|
||||
local response=$(curl -ks -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-ID: $API_ID" \
|
||||
-H "X-API-KEY: $API_KEY" \
|
||||
@@ -809,7 +809,7 @@ EOF
|
||||
local payload=$(echo "$base_payload $merged_json" | jq -s '.[0] * .[1]')
|
||||
|
||||
|
||||
local response=$(curl -ksv -X POST \
|
||||
local response=$(curl -ks -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-ID: $API_ID" \
|
||||
-H "X-API-KEY: $API_KEY" \
|
||||
@@ -821,25 +821,18 @@ EOF
|
||||
success "Update sent successfully"
|
||||
echo "$response" | grep -o '"packagesProcessed":[0-9]*' | cut -d':' -f2 | xargs -I {} info "Processed {} packages"
|
||||
|
||||
# Check for PatchMon agent update instructions (this updates the agent script, not system packages)
|
||||
if echo "$response" | grep -q '"autoUpdate":{'; then
|
||||
local auto_update_section=$(echo "$response" | grep -o '"autoUpdate":{[^}]*}')
|
||||
local should_update=$(echo "$auto_update_section" | grep -o '"shouldUpdate":true' | cut -d':' -f2)
|
||||
if [[ "$should_update" == "true" ]]; then
|
||||
local latest_version=$(echo "$auto_update_section" | grep -o '"latestVersion":"[^"]*' | cut -d'"' -f4)
|
||||
local current_version=$(echo "$auto_update_section" | grep -o '"currentVersion":"[^"]*' | cut -d'"' -f4)
|
||||
local update_message=$(echo "$auto_update_section" | grep -o '"message":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
info "PatchMon agent update detected: $update_message"
|
||||
info "Current version: $current_version, Latest version: $latest_version"
|
||||
|
||||
# Automatically run update-agent command to update the PatchMon agent script
|
||||
info "Automatically updating PatchMon agent to latest version..."
|
||||
# Check if auto-update is enabled and check for agent updates locally
|
||||
if check_auto_update_enabled; then
|
||||
info "Auto-update is enabled, checking for agent updates..."
|
||||
if check_agent_update_needed; then
|
||||
info "Agent update available, automatically updating..."
|
||||
if "$0" update-agent; then
|
||||
success "PatchMon agent update completed successfully"
|
||||
else
|
||||
warning "PatchMon agent update failed, but data was sent successfully"
|
||||
fi
|
||||
else
|
||||
info "Agent is up to date"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -877,7 +870,7 @@ EOF
|
||||
ping_server() {
|
||||
load_credentials
|
||||
|
||||
local response=$(curl -ksv -X POST \
|
||||
local response=$(curl -ks -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-ID: $API_ID" \
|
||||
-H "X-API-KEY: $API_KEY" \
|
||||
@@ -920,7 +913,7 @@ check_version() {
|
||||
|
||||
info "Checking for agent updates..."
|
||||
|
||||
local response=$(curl -ksv -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/version")
|
||||
local response=$(curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/version")
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
local current_version=$(echo "$response" | grep -o '"currentVersion":"[^"]*' | cut -d'"' -f4)
|
||||
@@ -949,59 +942,147 @@ check_version() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if auto-update is enabled (both globally and for this host)
|
||||
check_auto_update_enabled() {
|
||||
# Get settings from server using API credentials
|
||||
local response=$(curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/settings" 2>/dev/null)
|
||||
if [[ $? -ne 0 ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if both global and host auto-update are enabled
|
||||
local global_auto_update=$(echo "$response" | grep -o '"auto_update":true' | cut -d':' -f2)
|
||||
local host_auto_update=$(echo "$response" | grep -o '"host_auto_update":true' | cut -d':' -f2)
|
||||
|
||||
if [[ "$global_auto_update" == "true" && "$host_auto_update" == "true" ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if agent update is needed (internal function for auto-update)
|
||||
check_agent_update_needed() {
|
||||
# Get current agent timestamp
|
||||
local current_timestamp=0
|
||||
if [[ -f "$0" ]]; then
|
||||
current_timestamp=$(stat -c %Y "$0" 2>/dev/null || stat -f %m "$0" 2>/dev/null || echo "0")
|
||||
fi
|
||||
|
||||
# Get server agent info using API credentials
|
||||
local response=$(curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/timestamp" 2>/dev/null)
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
local server_version=$(echo "$response" | grep -o '"version":"[^"]*' | cut -d'"' -f4)
|
||||
local server_timestamp=$(echo "$response" | grep -o '"timestamp":[0-9]*' | cut -d':' -f2)
|
||||
local server_exists=$(echo "$response" | grep -o '"exists":true' | cut -d':' -f2)
|
||||
|
||||
if [[ "$server_exists" != "true" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if update is needed
|
||||
if [[ "$server_version" != "$AGENT_VERSION" ]]; then
|
||||
return 0 # Update needed due to version mismatch
|
||||
elif [[ "$server_timestamp" -gt "$current_timestamp" ]]; then
|
||||
return 0 # Update needed due to newer timestamp
|
||||
else
|
||||
return 1 # No update needed
|
||||
fi
|
||||
else
|
||||
return 1 # Failed to check
|
||||
fi
|
||||
}
|
||||
|
||||
# Check for agent updates based on version and timestamp (interactive command)
|
||||
check_agent_update() {
|
||||
load_credentials
|
||||
|
||||
info "Checking for agent updates..."
|
||||
|
||||
# Get current agent timestamp
|
||||
local current_timestamp=0
|
||||
if [[ -f "$0" ]]; then
|
||||
current_timestamp=$(stat -c %Y "$0" 2>/dev/null || stat -f %m "$0" 2>/dev/null || echo "0")
|
||||
fi
|
||||
|
||||
# Get server agent info using API credentials
|
||||
local response=$(curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/timestamp")
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
local server_version=$(echo "$response" | grep -o '"version":"[^"]*' | cut -d'"' -f4)
|
||||
local server_timestamp=$(echo "$response" | grep -o '"timestamp":[0-9]*' | cut -d':' -f2)
|
||||
local server_exists=$(echo "$response" | grep -o '"exists":true' | cut -d':' -f2)
|
||||
|
||||
if [[ "$server_exists" != "true" ]]; then
|
||||
warning "No agent script found on server"
|
||||
return 1
|
||||
fi
|
||||
|
||||
info "Current agent version: $AGENT_VERSION (timestamp: $current_timestamp)"
|
||||
info "Server agent version: $server_version (timestamp: $server_timestamp)"
|
||||
|
||||
# Check if update is needed
|
||||
if [[ "$server_version" != "$AGENT_VERSION" ]]; then
|
||||
info "Version mismatch detected - update needed"
|
||||
return 0
|
||||
elif [[ "$server_timestamp" -gt "$current_timestamp" ]]; then
|
||||
info "Server script is newer - update needed"
|
||||
return 0
|
||||
else
|
||||
info "Agent is up to date"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
error "Failed to check agent timestamp from server"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Update agent script
|
||||
update_agent() {
|
||||
load_credentials
|
||||
|
||||
info "Updating agent script..."
|
||||
|
||||
local response=$(curl -ksv -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/version")
|
||||
local download_url="$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/download"
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
local download_url=$(echo "$response" | grep -o '"downloadUrl":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
if [[ -z "$download_url" ]]; then
|
||||
download_url="$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/download"
|
||||
elif [[ "$download_url" =~ ^/ ]]; then
|
||||
# If download_url is relative, prepend the server URL
|
||||
download_url="$PATCHMON_SERVER$download_url"
|
||||
fi
|
||||
|
||||
info "Downloading latest agent from: $download_url"
|
||||
|
||||
# Create backup of current script
|
||||
cp "$0" "$0.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
# Download new version
|
||||
if curl -ksv -o "/tmp/patchmon-agent-new.sh" "$download_url"; then
|
||||
# Verify the downloaded script is valid
|
||||
if bash -n "/tmp/patchmon-agent-new.sh" 2>/dev/null; then
|
||||
# Replace current script
|
||||
mv "/tmp/patchmon-agent-new.sh" "$0"
|
||||
chmod +x "$0"
|
||||
success "Agent updated successfully"
|
||||
info "Backup saved as: $0.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
# Get the new version number
|
||||
local new_version=$(grep '^AGENT_VERSION=' "$0" | cut -d'"' -f2)
|
||||
info "Updated to version: $new_version"
|
||||
|
||||
# Automatically run update to send new information to PatchMon
|
||||
info "Sending updated information to PatchMon..."
|
||||
if "$0" update; then
|
||||
success "Successfully sent updated information to PatchMon"
|
||||
else
|
||||
warning "Failed to send updated information to PatchMon (this is not critical)"
|
||||
fi
|
||||
info "Downloading latest agent from: $download_url"
|
||||
|
||||
# Clean up old backups (keep only last 3)
|
||||
ls -t "$0.backup."* 2>/dev/null | tail -n +4 | xargs -r rm -f
|
||||
|
||||
# Create backup of current script
|
||||
local backup_file="$0.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
cp "$0" "$backup_file"
|
||||
|
||||
# Download new version using API credentials
|
||||
if curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -o "/tmp/patchmon-agent-new.sh" "$download_url"; then
|
||||
# Verify the downloaded script is valid
|
||||
if bash -n "/tmp/patchmon-agent-new.sh" 2>/dev/null; then
|
||||
# Replace current script
|
||||
mv "/tmp/patchmon-agent-new.sh" "$0"
|
||||
chmod +x "$0"
|
||||
success "Agent updated successfully"
|
||||
info "Backup saved as: $backup_file"
|
||||
|
||||
# Get the new version number
|
||||
local new_version=$(grep '^AGENT_VERSION=' "$0" | cut -d'"' -f2)
|
||||
info "Updated to version: $new_version"
|
||||
|
||||
# Automatically run update to send new information to PatchMon
|
||||
info "Sending updated information to PatchMon..."
|
||||
if "$0" update; then
|
||||
success "Successfully sent updated information to PatchMon"
|
||||
else
|
||||
error "Downloaded script is invalid"
|
||||
rm -f "/tmp/patchmon-agent-new.sh"
|
||||
warning "Failed to send updated information to PatchMon (this is not critical)"
|
||||
fi
|
||||
else
|
||||
error "Failed to download new agent script"
|
||||
error "Downloaded script is invalid"
|
||||
rm -f "/tmp/patchmon-agent-new.sh"
|
||||
fi
|
||||
else
|
||||
error "Failed to get update information"
|
||||
error "Failed to download new agent script"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1009,7 +1090,7 @@ update_agent() {
|
||||
update_crontab() {
|
||||
load_credentials
|
||||
info "Updating crontab with current policy..."
|
||||
local response=$(curl -ksv -X GET "$PATCHMON_SERVER/api/$API_VERSION/settings/update-interval")
|
||||
local response=$(curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -X GET "$PATCHMON_SERVER/api/$API_VERSION/settings/update-interval")
|
||||
if [[ $? -eq 0 ]]; then
|
||||
local update_interval=$(echo "$response" | grep -o '"updateInterval":[0-9]*' | cut -d':' -f2)
|
||||
if [[ -n "$update_interval" ]]; then
|
||||
@@ -1024,18 +1105,27 @@ update_crontab() {
|
||||
expected_crontab="*/$update_interval * * * * /usr/local/bin/patchmon-agent.sh update >/dev/null 2>&1"
|
||||
fi
|
||||
|
||||
# Get current crontab
|
||||
local current_crontab=$(crontab -l 2>/dev/null | grep "patchmon-agent.sh update" | head -1)
|
||||
# Get current crontab (without patchmon entries)
|
||||
local current_crontab_without_patchmon=$(crontab -l 2>/dev/null | grep -v "/usr/local/bin/patchmon-agent.sh update" || true)
|
||||
local current_patchmon_entry=$(crontab -l 2>/dev/null | grep "/usr/local/bin/patchmon-agent.sh update" | head -1)
|
||||
|
||||
# Check if crontab needs updating
|
||||
if [[ "$current_crontab" == "$expected_crontab" ]]; then
|
||||
if [[ "$current_patchmon_entry" == "$expected_crontab" ]]; then
|
||||
info "Crontab is already up to date (interval: $update_interval minutes)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
info "Setting update interval to $update_interval minutes"
|
||||
echo "$expected_crontab" | crontab -
|
||||
success "Crontab updated successfully"
|
||||
|
||||
# Combine existing cron (without patchmon entries) + new patchmon entry
|
||||
{
|
||||
if [[ -n "$current_crontab_without_patchmon" ]]; then
|
||||
echo "$current_crontab_without_patchmon"
|
||||
fi
|
||||
echo "$expected_crontab"
|
||||
} | crontab -
|
||||
|
||||
success "Crontab updated successfully (duplicates removed)"
|
||||
else
|
||||
error "Could not determine update interval from server"
|
||||
fi
|
||||
@@ -1147,7 +1237,7 @@ main() {
|
||||
check_root
|
||||
setup_directories
|
||||
load_config
|
||||
configure_credentials "$2" "$3"
|
||||
configure_credentials "$2" "$3" "$4"
|
||||
;;
|
||||
"test")
|
||||
check_root
|
||||
@@ -1178,6 +1268,11 @@ main() {
|
||||
load_config
|
||||
check_version
|
||||
;;
|
||||
"check-agent-update")
|
||||
setup_directories
|
||||
load_config
|
||||
check_agent_update
|
||||
;;
|
||||
"update-agent")
|
||||
check_root
|
||||
setup_directories
|
||||
@@ -1195,22 +1290,23 @@ main() {
|
||||
;;
|
||||
*)
|
||||
echo "PatchMon Agent v$AGENT_VERSION - API Credential Based"
|
||||
echo "Usage: $0 {configure|test|update|ping|config|check-version|update-agent|update-crontab|diagnostics}"
|
||||
echo "Usage: $0 {configure|test|update|ping|config|check-version|check-agent-update|update-agent|update-crontab|diagnostics}"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " configure <API_ID> <API_KEY> - Configure API credentials for this host"
|
||||
echo " configure <API_ID> <API_KEY> [SERVER_URL] - Configure API credentials for this host"
|
||||
echo " test - Test API credentials connectivity"
|
||||
echo " update - Send package update information to server"
|
||||
echo " ping - Test connectivity to server"
|
||||
echo " config - Show current configuration"
|
||||
echo " check-version - Check for agent updates"
|
||||
echo " check-agent-update - Check for agent updates using timestamp comparison"
|
||||
echo " update-agent - Update agent to latest version"
|
||||
echo " update-crontab - Update crontab with current policy"
|
||||
echo " diagnostics - Show detailed system diagnostics"
|
||||
echo ""
|
||||
echo "Setup Process:"
|
||||
echo " 1. Contact your PatchMon administrator to create a host entry"
|
||||
echo " 2. Run: $0 configure <API_ID> <API_KEY> (provided by admin)"
|
||||
echo " 2. Run: $0 configure <API_ID> <API_KEY> [SERVER_URL] (provided by admin)"
|
||||
echo " 3. Run: $0 test (to verify connection)"
|
||||
echo " 4. Run: $0 update (to send initial package data)"
|
||||
echo ""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# PatchMon Agent Installation Script
|
||||
# Usage: curl -ksSL {PATCHMON_URL}/api/v1/hosts/install | bash -s -- {PATCHMON_URL} {API_ID} {API_KEY}
|
||||
# Usage: curl -ks {PATCHMON_URL}/api/v1/hosts/install -H "X-API-ID: {API_ID}" -H "X-API-KEY: {API_KEY}" | bash
|
||||
|
||||
set -e
|
||||
|
||||
@@ -35,10 +35,34 @@ if [[ $EUID -ne 0 ]]; then
|
||||
error "This script must be run as root (use sudo)"
|
||||
fi
|
||||
|
||||
# Clean up old files (keep only last 3 of each type)
|
||||
cleanup_old_files() {
|
||||
# Clean up old credential backups
|
||||
ls -t /etc/patchmon/credentials.backup.* 2>/dev/null | tail -n +4 | xargs -r rm -f
|
||||
|
||||
# Clean up old agent backups
|
||||
ls -t /usr/local/bin/patchmon-agent.sh.backup.* 2>/dev/null | tail -n +4 | xargs -r rm -f
|
||||
|
||||
# Clean up old log files
|
||||
ls -t /var/log/patchmon-agent.log.old.* 2>/dev/null | tail -n +4 | xargs -r rm -f
|
||||
}
|
||||
|
||||
# Run cleanup at start
|
||||
cleanup_old_files
|
||||
|
||||
# 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
|
||||
|
||||
info "🚀 Starting PatchMon Agent Installation..."
|
||||
info "📋 Server: $PATCHMON_URL"
|
||||
info "🔑 API ID: ${API_ID:0:16}..."
|
||||
|
||||
# Install required dependencies
|
||||
info "📦 Installing required dependencies..."
|
||||
|
||||
# Detect package manager and install jq
|
||||
# Detect package manager and install jq and curl
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
# Debian/Ubuntu
|
||||
apt-get update >/dev/null 2>&1
|
||||
@@ -62,76 +86,40 @@ else
|
||||
warning "Could not detect package manager. Please ensure 'jq' and 'curl' are installed manually."
|
||||
fi
|
||||
|
||||
# Verify jq installation
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
error "Failed to install 'jq'. Please install it manually: https://stedolan.github.io/jq/download/"
|
||||
# Step 1: Handle existing configuration directory
|
||||
info "📁 Setting up configuration directory..."
|
||||
|
||||
# Check if configuration directory already exists
|
||||
if [[ -d "/etc/patchmon" ]]; then
|
||||
warning "⚠️ Configuration directory already exists at /etc/patchmon"
|
||||
warning "⚠️ Preserving existing configuration files"
|
||||
|
||||
# List existing files for user awareness
|
||||
info "📋 Existing files in /etc/patchmon:"
|
||||
ls -la /etc/patchmon/ 2>/dev/null | grep -v "^total" | while read -r line; do
|
||||
echo " $line"
|
||||
done
|
||||
else
|
||||
info "📁 Creating new configuration directory..."
|
||||
mkdir -p /etc/patchmon
|
||||
fi
|
||||
|
||||
success "Dependencies installed successfully!"
|
||||
# Step 2: Create credentials file
|
||||
info "🔐 Creating API credentials file..."
|
||||
|
||||
# Default server URL (will be replaced by backend with configured URL)
|
||||
PATCHMON_URL="http://localhost:3001"
|
||||
|
||||
# Parse arguments
|
||||
if [[ $# -ne 3 ]]; then
|
||||
echo "Usage: curl -ksSL {PATCHMON_URL}/api/v1/hosts/install | bash -s -- {PATCHMON_URL} {API_ID} {API_KEY}"
|
||||
echo ""
|
||||
echo "Example:"
|
||||
echo "curl -ksSL http://patchmon.example.com/api/v1/hosts/install | bash -s -- http://patchmon.example.com patchmon_1a2b3c4d abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
|
||||
echo ""
|
||||
echo "Contact your PatchMon administrator to get your API credentials."
|
||||
exit 1
|
||||
# Check if credentials file already exists
|
||||
if [[ -f "/etc/patchmon/credentials" ]]; then
|
||||
warning "⚠️ Credentials file already exists at /etc/patchmon/credentials"
|
||||
warning "⚠️ Moving existing file out of the way for fresh installation"
|
||||
|
||||
# Clean up old credential backups (keep only last 3)
|
||||
ls -t /etc/patchmon/credentials.backup.* 2>/dev/null | tail -n +4 | xargs -r rm -f
|
||||
|
||||
# Move existing file out of the way
|
||||
mv /etc/patchmon/credentials /etc/patchmon/credentials.backup.$(date +%Y%m%d_%H%M%S)
|
||||
info "📋 Moved existing credentials to: /etc/patchmon/credentials.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
fi
|
||||
|
||||
PATCHMON_URL="$1"
|
||||
API_ID="$2"
|
||||
API_KEY="$3"
|
||||
|
||||
# Validate inputs
|
||||
if [[ ! "$PATCHMON_URL" =~ ^https?:// ]]; then
|
||||
error "Invalid URL format. Must start with http:// or https://"
|
||||
fi
|
||||
|
||||
if [[ ! "$API_ID" =~ ^patchmon_[a-f0-9]{16}$ ]]; then
|
||||
error "Invalid API ID format. API ID should be in format: patchmon_xxxxxxxxxxxxxxxx"
|
||||
fi
|
||||
|
||||
if [[ ! "$API_KEY" =~ ^[a-f0-9]{64}$ ]]; then
|
||||
error "Invalid API Key format. API Key should be 64 hexadecimal characters."
|
||||
fi
|
||||
|
||||
info "🚀 Installing PatchMon Agent..."
|
||||
info " Server: $PATCHMON_URL"
|
||||
info " API ID: $API_ID"
|
||||
|
||||
# Create patchmon directory
|
||||
info "📁 Creating configuration directory..."
|
||||
mkdir -p /etc/patchmon
|
||||
|
||||
# Download the agent script
|
||||
info "📥 Downloading PatchMon agent script..."
|
||||
curl -ksSL "$PATCHMON_URL/api/v1/hosts/agent/download" -o /usr/local/bin/patchmon-agent.sh
|
||||
chmod +x /usr/local/bin/patchmon-agent.sh
|
||||
|
||||
# Get the agent version from the downloaded script
|
||||
AGENT_VERSION=$(grep '^AGENT_VERSION=' /usr/local/bin/patchmon-agent.sh | cut -d'"' -f2)
|
||||
info "📋 Agent version: $AGENT_VERSION"
|
||||
|
||||
# Get expected agent version from server
|
||||
EXPECTED_VERSION=$(curl -ksv "$PATCHMON_URL/api/v1/hosts/agent/version" | grep -o '"currentVersion":"[^"]*' | cut -d'"' -f4 2>/dev/null || echo "Unknown")
|
||||
if [[ "$EXPECTED_VERSION" != "Unknown" ]]; then
|
||||
info "📋 Expected version: $EXPECTED_VERSION"
|
||||
if [[ "$AGENT_VERSION" != "$EXPECTED_VERSION" ]]; then
|
||||
warning "⚠️ Agent version mismatch! Installed: $AGENT_VERSION, Expected: $EXPECTED_VERSION"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Get update interval policy from server
|
||||
UPDATE_INTERVAL=$(curl -ksv "$PATCHMON_URL/api/v1/settings/update-interval" | grep -o '"updateInterval":[0-9]*' | cut -d':' -f2 2>/dev/null || echo "60")
|
||||
info "📋 Update interval: $UPDATE_INTERVAL minutes"
|
||||
|
||||
# Create credentials file
|
||||
info "🔐 Setting up API credentials..."
|
||||
cat > /etc/patchmon/credentials << EOF
|
||||
# PatchMon API Credentials
|
||||
# Generated on $(date)
|
||||
@@ -139,63 +127,141 @@ PATCHMON_URL="$PATCHMON_URL"
|
||||
API_ID="$API_ID"
|
||||
API_KEY="$API_KEY"
|
||||
EOF
|
||||
|
||||
chmod 600 /etc/patchmon/credentials
|
||||
|
||||
# Test the configuration
|
||||
info "🧪 Testing configuration..."
|
||||
# Step 3: Download the agent script using API credentials
|
||||
info "📥 Downloading PatchMon agent script..."
|
||||
|
||||
# Check if agent script already exists
|
||||
if [[ -f "/usr/local/bin/patchmon-agent.sh" ]]; then
|
||||
warning "⚠️ Agent script already exists at /usr/local/bin/patchmon-agent.sh"
|
||||
warning "⚠️ Moving existing file out of the way for fresh installation"
|
||||
|
||||
# Clean up old agent backups (keep only last 3)
|
||||
ls -t /usr/local/bin/patchmon-agent.sh.backup.* 2>/dev/null | tail -n +4 | xargs -r rm -f
|
||||
|
||||
# Move existing file out of the way
|
||||
mv /usr/local/bin/patchmon-agent.sh /usr/local/bin/patchmon-agent.sh.backup.$(date +%Y%m%d_%H%M%S)
|
||||
info "📋 Moved existing agent to: /usr/local/bin/patchmon-agent.sh.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
fi
|
||||
|
||||
curl -ks \
|
||||
-H "X-API-ID: $API_ID" \
|
||||
-H "X-API-KEY: $API_KEY" \
|
||||
"$PATCHMON_URL/api/v1/hosts/agent/download" \
|
||||
-o /usr/local/bin/patchmon-agent.sh
|
||||
|
||||
chmod +x /usr/local/bin/patchmon-agent.sh
|
||||
|
||||
# Get the agent version from the downloaded script
|
||||
AGENT_VERSION=$(grep '^AGENT_VERSION=' /usr/local/bin/patchmon-agent.sh | cut -d'"' -f2 2>/dev/null || echo "Unknown")
|
||||
info "📋 Agent version: $AGENT_VERSION"
|
||||
|
||||
# Handle existing log files
|
||||
if [[ -f "/var/log/patchmon-agent.log" ]]; then
|
||||
warning "⚠️ Existing log file found at /var/log/patchmon-agent.log"
|
||||
warning "⚠️ Rotating log file for fresh start"
|
||||
|
||||
# Rotate the log file
|
||||
mv /var/log/patchmon-agent.log /var/log/patchmon-agent.log.old.$(date +%Y%m%d_%H%M%S)
|
||||
info "📋 Log file rotated to: /var/log/patchmon-agent.log.old.$(date +%Y%m%d_%H%M%S)"
|
||||
fi
|
||||
|
||||
# Step 4: Test the configuration
|
||||
info "🧪 Testing API credentials and connectivity..."
|
||||
if /usr/local/bin/patchmon-agent.sh test; then
|
||||
success "Configuration test passed!"
|
||||
success "✅ API credentials are valid and server is reachable"
|
||||
else
|
||||
error "Configuration test failed. Please check your credentials."
|
||||
error "❌ Failed to validate API credentials or reach server"
|
||||
fi
|
||||
|
||||
# Send initial update
|
||||
info "📊 Sending initial package data..."
|
||||
# Step 5: Send initial data
|
||||
info "📊 Sending initial package data to server..."
|
||||
if /usr/local/bin/patchmon-agent.sh update; then
|
||||
success "Initial package data sent successfully!"
|
||||
success "✅ Initial package data sent successfully"
|
||||
else
|
||||
warning "Initial package data failed, but agent is configured. You can run 'patchmon-agent.sh update' manually."
|
||||
warning "⚠️ Failed to send initial data. You can retry later with: /usr/local/bin/patchmon-agent.sh update"
|
||||
fi
|
||||
|
||||
# Setup crontab for automatic package status updates
|
||||
info "⏰ Setting up automatic package status update every $UPDATE_INTERVAL minutes..."
|
||||
# Step 6: Get update interval policy from server and setup crontab
|
||||
info "⏰ Getting update interval policy from server..."
|
||||
UPDATE_INTERVAL=$(curl -ks \
|
||||
-H "X-API-ID: $API_ID" \
|
||||
-H "X-API-KEY: $API_KEY" \
|
||||
"$PATCHMON_URL/api/v1/settings/update-interval" | \
|
||||
grep -o '"updateInterval":[0-9]*' | cut -d':' -f2 2>/dev/null || echo "60")
|
||||
|
||||
# Check if patchmon cron job already exists
|
||||
PATCHMON_CRON_EXISTS=$(crontab -l 2>/dev/null | grep -c "patchmon-agent.sh update" || true)
|
||||
info "📋 Update interval: $UPDATE_INTERVAL minutes"
|
||||
|
||||
if [[ $PATCHMON_CRON_EXISTS -gt 0 ]]; then
|
||||
info " Existing PatchMon cron job found, removing old entry..."
|
||||
# Remove existing patchmon cron entries and preserve other entries
|
||||
(crontab -l 2>/dev/null | grep -v "patchmon-agent.sh update") | crontab -
|
||||
# Setup crontab (smart duplicate detection)
|
||||
info "📅 Setting up automated updates..."
|
||||
|
||||
# Check if PatchMon cron entries already exist
|
||||
if crontab -l 2>/dev/null | grep -q "/usr/local/bin/patchmon-agent.sh update"; then
|
||||
warning "⚠️ Existing PatchMon cron entries found"
|
||||
warning "⚠️ These will be replaced with new schedule"
|
||||
fi
|
||||
|
||||
if [[ $UPDATE_INTERVAL -eq 60 ]]; then
|
||||
# Hourly updates - safely append to existing crontab
|
||||
(crontab -l 2>/dev/null; echo "0 * * * * /usr/local/bin/patchmon-agent.sh update >/dev/null 2>&1") | crontab -
|
||||
else
|
||||
# Custom interval updates - safely append to existing crontab
|
||||
(crontab -l 2>/dev/null; echo "*/$UPDATE_INTERVAL * * * * /usr/local/bin/patchmon-agent.sh update >/dev/null 2>&1") | crontab -
|
||||
fi
|
||||
# Function to setup crontab without duplicates
|
||||
setup_crontab() {
|
||||
local update_interval="$1"
|
||||
local patchmon_pattern="/usr/local/bin/patchmon-agent.sh update"
|
||||
|
||||
# Get current crontab, remove any existing patchmon entries
|
||||
local current_cron=$(crontab -l 2>/dev/null | grep -v "$patchmon_pattern" || true)
|
||||
|
||||
# Determine new cron entry
|
||||
local new_entry
|
||||
if [[ "$update_interval" -eq 60 ]]; then
|
||||
# Hourly updates - use a random minute to spread load
|
||||
local current_minute=$(date +%M)
|
||||
new_entry="$current_minute * * * * $patchmon_pattern >/dev/null 2>&1"
|
||||
info "📋 Configuring hourly updates at minute $current_minute"
|
||||
else
|
||||
# Custom interval updates
|
||||
new_entry="*/$update_interval * * * * $patchmon_pattern >/dev/null 2>&1"
|
||||
info "📋 Configuring updates every $update_interval minutes"
|
||||
fi
|
||||
|
||||
# Combine existing cron (without patchmon entries) + new entry
|
||||
{
|
||||
if [[ -n "$current_cron" ]]; then
|
||||
echo "$current_cron"
|
||||
fi
|
||||
echo "$new_entry"
|
||||
} | crontab -
|
||||
|
||||
success "✅ Crontab configured successfully (duplicates removed)"
|
||||
}
|
||||
|
||||
success "🎉 PatchMon Agent installation complete!"
|
||||
setup_crontab "$UPDATE_INTERVAL"
|
||||
|
||||
# Installation complete
|
||||
success "🎉 PatchMon Agent installation completed successfully!"
|
||||
echo ""
|
||||
echo "📋 Installation Summary:"
|
||||
echo " • Dependencies installed: jq, curl"
|
||||
echo -e "${GREEN}📋 Installation Summary:${NC}"
|
||||
echo " • Configuration directory: /etc/patchmon"
|
||||
echo " • Agent installed: /usr/local/bin/patchmon-agent.sh"
|
||||
echo " • Agent version: $AGENT_VERSION"
|
||||
if [[ "$EXPECTED_VERSION" != "Unknown" ]]; then
|
||||
echo " • Expected version: $EXPECTED_VERSION"
|
||||
fi
|
||||
echo " • Config directory: /etc/patchmon/"
|
||||
echo " • Credentials file: /etc/patchmon/credentials"
|
||||
echo " • Status updates: Every $UPDATE_INTERVAL minutes via crontab"
|
||||
echo " • View logs: tail -f /var/log/patchmon-agent.log"
|
||||
echo ""
|
||||
echo "🔧 Manual commands:"
|
||||
echo " • Test connection: patchmon-agent.sh test"
|
||||
echo " • Send update: patchmon-agent.sh update"
|
||||
echo " • Check status: patchmon-agent.sh ping"
|
||||
echo ""
|
||||
success "Your host is now connected to PatchMon!"
|
||||
echo " • Dependencies installed: jq, curl"
|
||||
echo " • Crontab configured for automatic updates"
|
||||
echo " • API credentials configured and tested"
|
||||
|
||||
# Check for moved files and show them
|
||||
MOVED_FILES=$(ls /etc/patchmon/credentials.backup.* /usr/local/bin/patchmon-agent.sh.backup.* /var/log/patchmon-agent.log.old.* 2>/dev/null || true)
|
||||
if [[ -n "$MOVED_FILES" ]]; then
|
||||
echo ""
|
||||
echo -e "${YELLOW}📋 Files Moved for Fresh Installation:${NC}"
|
||||
echo "$MOVED_FILES" | while read -r moved_file; do
|
||||
echo " • $moved_file"
|
||||
done
|
||||
echo ""
|
||||
echo -e "${BLUE}💡 Note: Old files are automatically cleaned up (keeping last 3)${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}🔧 Management Commands:${NC}"
|
||||
echo " • Test connection: /usr/local/bin/patchmon-agent.sh test"
|
||||
echo " • Manual update: /usr/local/bin/patchmon-agent.sh update"
|
||||
echo " • Check status: /usr/local/bin/patchmon-agent.sh diagnostics"
|
||||
echo ""
|
||||
success "✅ Your system is now being monitored by PatchMon!"
|
||||
|
||||
217
agents/patchmon_remove.sh
Executable file
217
agents/patchmon_remove.sh
Executable file
@@ -0,0 +1,217 @@
|
||||
#!/bin/bash
|
||||
|
||||
# PatchMon Agent Removal Script
|
||||
# Usage: curl -ks {PATCHMON_URL}/api/v1/hosts/remove | bash
|
||||
# This script completely removes PatchMon from the system
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Functions
|
||||
error() {
|
||||
echo -e "${RED}❌ ERROR: $1${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
info() {
|
||||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
# Check if running as root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
error "This script must be run as root (use sudo)"
|
||||
fi
|
||||
|
||||
info "🗑️ Starting PatchMon Agent Removal..."
|
||||
echo ""
|
||||
|
||||
# Step 1: Stop any running PatchMon processes
|
||||
info "🛑 Stopping PatchMon processes..."
|
||||
if pgrep -f "patchmon-agent.sh" >/dev/null; then
|
||||
warning "Found running PatchMon processes, stopping them..."
|
||||
pkill -f "patchmon-agent.sh" || true
|
||||
sleep 2
|
||||
success "PatchMon processes stopped"
|
||||
else
|
||||
info "No running PatchMon processes found"
|
||||
fi
|
||||
|
||||
# Step 2: Remove crontab entries
|
||||
info "📅 Removing PatchMon crontab entries..."
|
||||
if crontab -l 2>/dev/null | grep -q "patchmon-agent.sh"; then
|
||||
warning "Found PatchMon crontab entries, removing them..."
|
||||
crontab -l 2>/dev/null | grep -v "patchmon-agent.sh" | crontab -
|
||||
success "Crontab entries removed"
|
||||
else
|
||||
info "No PatchMon crontab entries found"
|
||||
fi
|
||||
|
||||
# Step 3: Remove agent script
|
||||
info "📄 Removing agent script..."
|
||||
if [[ -f "/usr/local/bin/patchmon-agent.sh" ]]; then
|
||||
warning "Removing agent script: /usr/local/bin/patchmon-agent.sh"
|
||||
rm -f /usr/local/bin/patchmon-agent.sh
|
||||
success "Agent script removed"
|
||||
else
|
||||
info "Agent script not found"
|
||||
fi
|
||||
|
||||
# Step 4: Remove configuration directory and files
|
||||
info "📁 Removing configuration files..."
|
||||
if [[ -d "/etc/patchmon" ]]; then
|
||||
warning "Removing configuration directory: /etc/patchmon"
|
||||
|
||||
# Show what's being removed
|
||||
info "📋 Files in /etc/patchmon:"
|
||||
ls -la /etc/patchmon/ 2>/dev/null | grep -v "^total" | while read -r line; do
|
||||
echo " $line"
|
||||
done
|
||||
|
||||
# Remove the directory
|
||||
rm -rf /etc/patchmon
|
||||
success "Configuration directory removed"
|
||||
else
|
||||
info "Configuration directory not found"
|
||||
fi
|
||||
|
||||
# Step 5: Remove log files
|
||||
info "📝 Removing log files..."
|
||||
if [[ -f "/var/log/patchmon-agent.log" ]]; then
|
||||
warning "Removing log file: /var/log/patchmon-agent.log"
|
||||
rm -f /var/log/patchmon-agent.log
|
||||
success "Log file removed"
|
||||
else
|
||||
info "Log file not found"
|
||||
fi
|
||||
|
||||
# Step 6: Clean up backup files (optional)
|
||||
info "🧹 Cleaning up backup files..."
|
||||
BACKUP_COUNT=0
|
||||
|
||||
# Count credential backups
|
||||
CRED_BACKUPS=$(ls /etc/patchmon/credentials.backup.* 2>/dev/null | wc -l || echo "0")
|
||||
if [[ $CRED_BACKUPS -gt 0 ]]; then
|
||||
BACKUP_COUNT=$((BACKUP_COUNT + CRED_BACKUPS))
|
||||
fi
|
||||
|
||||
# Count agent backups
|
||||
AGENT_BACKUPS=$(ls /usr/local/bin/patchmon-agent.sh.backup.* 2>/dev/null | wc -l || echo "0")
|
||||
if [[ $AGENT_BACKUPS -gt 0 ]]; then
|
||||
BACKUP_COUNT=$((BACKUP_COUNT + AGENT_BACKUPS))
|
||||
fi
|
||||
|
||||
# Count log backups
|
||||
LOG_BACKUPS=$(ls /var/log/patchmon-agent.log.old.* 2>/dev/null | wc -l || echo "0")
|
||||
if [[ $LOG_BACKUPS -gt 0 ]]; then
|
||||
BACKUP_COUNT=$((BACKUP_COUNT + LOG_BACKUPS))
|
||||
fi
|
||||
|
||||
if [[ $BACKUP_COUNT -gt 0 ]]; then
|
||||
warning "Found $BACKUP_COUNT backup files"
|
||||
echo ""
|
||||
echo -e "${YELLOW}📋 Backup files found:${NC}"
|
||||
|
||||
# Show credential backups
|
||||
if [[ $CRED_BACKUPS -gt 0 ]]; then
|
||||
echo " Credential backups:"
|
||||
ls /etc/patchmon/credentials.backup.* 2>/dev/null | while read -r file; do
|
||||
echo " • $file"
|
||||
done
|
||||
fi
|
||||
|
||||
# Show agent backups
|
||||
if [[ $AGENT_BACKUPS -gt 0 ]]; then
|
||||
echo " Agent script backups:"
|
||||
ls /usr/local/bin/patchmon-agent.sh.backup.* 2>/dev/null | while read -r file; do
|
||||
echo " • $file"
|
||||
done
|
||||
fi
|
||||
|
||||
# Show log backups
|
||||
if [[ $LOG_BACKUPS -gt 0 ]]; then
|
||||
echo " Log file backups:"
|
||||
ls /var/log/patchmon-agent.log.old.* 2>/dev/null | while read -r file; do
|
||||
echo " • $file"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}💡 Note: Backup files are preserved for safety${NC}"
|
||||
echo -e "${BLUE}💡 You can remove them manually if not needed${NC}"
|
||||
else
|
||||
info "No backup files found"
|
||||
fi
|
||||
|
||||
# Step 7: Remove dependencies (optional)
|
||||
info "📦 Checking for PatchMon-specific dependencies..."
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
warning "jq is installed (used by PatchMon)"
|
||||
echo -e "${BLUE}💡 Note: jq may be used by other applications${NC}"
|
||||
echo -e "${BLUE}💡 Consider keeping it unless you're sure it's not needed${NC}"
|
||||
else
|
||||
info "jq not found"
|
||||
fi
|
||||
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
warning "curl is installed (used by PatchMon)"
|
||||
echo -e "${BLUE}💡 Note: curl is commonly used by many applications${NC}"
|
||||
echo -e "${BLUE}💡 Consider keeping it unless you're sure it's not needed${NC}"
|
||||
else
|
||||
info "curl not found"
|
||||
fi
|
||||
|
||||
# Step 8: Final verification
|
||||
info "🔍 Verifying removal..."
|
||||
REMAINING_FILES=0
|
||||
|
||||
if [[ -f "/usr/local/bin/patchmon-agent.sh" ]]; then
|
||||
REMAINING_FILES=$((REMAINING_FILES + 1))
|
||||
fi
|
||||
|
||||
if [[ -d "/etc/patchmon" ]]; then
|
||||
REMAINING_FILES=$((REMAINING_FILES + 1))
|
||||
fi
|
||||
|
||||
if [[ -f "/var/log/patchmon-agent.log" ]]; then
|
||||
REMAINING_FILES=$((REMAINING_FILES + 1))
|
||||
fi
|
||||
|
||||
if crontab -l 2>/dev/null | grep -q "patchmon-agent.sh"; then
|
||||
REMAINING_FILES=$((REMAINING_FILES + 1))
|
||||
fi
|
||||
|
||||
if [[ $REMAINING_FILES -eq 0 ]]; then
|
||||
success "✅ PatchMon has been completely removed from the system!"
|
||||
else
|
||||
warning "⚠️ Some PatchMon files may still remain ($REMAINING_FILES items)"
|
||||
echo -e "${BLUE}💡 You may need to remove them manually${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}📋 Removal Summary:${NC}"
|
||||
echo " • Agent script: Removed"
|
||||
echo " • Configuration files: Removed"
|
||||
echo " • Log files: Removed"
|
||||
echo " • Crontab entries: Removed"
|
||||
echo " • Running processes: Stopped"
|
||||
echo " • Backup files: Preserved (if any)"
|
||||
echo ""
|
||||
echo -e "${BLUE}🔧 Manual cleanup (if needed):${NC}"
|
||||
echo " • Remove backup files: rm /etc/patchmon/credentials.backup.* /usr/local/bin/patchmon-agent.sh.backup.* /var/log/patchmon-agent.log.old.*"
|
||||
echo " • Remove dependencies: apt remove jq curl (if not needed by other apps)"
|
||||
echo ""
|
||||
success "🎉 PatchMon removal completed!"
|
||||
Reference in New Issue
Block a user