mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-10-22 23:32:03 +00:00
Refactored code to remove duplicate backend api endpoints for counting Improved connection persistence issues Improved database connection pooling issues Fixed redis connection efficiency Changed version to 1.3.0 Fixed GO binary detection based on package manager rather than OS
264 lines
9.2 KiB
Bash
Executable File
264 lines
9.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# redis-setup.sh - Redis Database and User Setup for PatchMon
|
|
# This script creates a dedicated Redis database and user for a PatchMon instance
|
|
|
|
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
|
|
|
|
# Default Redis connection details
|
|
REDIS_HOST=${REDIS_HOST:-"localhost"}
|
|
REDIS_PORT=${REDIS_PORT:-6379}
|
|
REDIS_ADMIN_PASSWORD=${REDIS_ADMIN_PASSWORD:-"YOURREDISPASSHERE"}
|
|
|
|
echo -e "${BLUE}🔧 PatchMon Redis Setup${NC}"
|
|
echo "=================================="
|
|
|
|
# Function to generate random strings
|
|
generate_random_string() {
|
|
local length=${1:-16}
|
|
openssl rand -base64 $length | tr -d "=+/" | cut -c1-$length
|
|
}
|
|
|
|
# Function to check if Redis is accessible
|
|
check_redis_connection() {
|
|
echo -e "${YELLOW}📡 Checking Redis connection...${NC}"
|
|
|
|
if [ -n "$REDIS_ADMIN_PASSWORD" ]; then
|
|
# With password - use ACL admin user
|
|
if redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" --user admin --pass "$REDIS_ADMIN_PASSWORD" --no-auth-warning ping > /dev/null 2>&1; then
|
|
echo -e "${GREEN}✅ Redis connection successful${NC}"
|
|
return 0
|
|
else
|
|
echo -e "${RED}❌ Cannot connect to Redis with ACL admin user${NC}"
|
|
echo "Please ensure Redis is running and the admin password is correct"
|
|
return 1
|
|
fi
|
|
else
|
|
# Without password
|
|
if redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" ping > /dev/null 2>&1; then
|
|
echo -e "${GREEN}✅ Redis connection successful${NC}"
|
|
return 0
|
|
else
|
|
echo -e "${RED}❌ Cannot connect to Redis${NC}"
|
|
echo "Please ensure Redis is running"
|
|
return 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Function to find next available database number
|
|
find_next_db() {
|
|
echo -e "${YELLOW}🔍 Finding next available database...${NC}" >&2
|
|
|
|
# Start from database 0 and keep checking until we find an empty one
|
|
local db_num=0
|
|
local max_attempts=100 # Safety limit to prevent infinite loop
|
|
|
|
while [ $db_num -lt $max_attempts ]; do
|
|
# Test if database is empty
|
|
local key_count
|
|
local redis_output
|
|
|
|
if [ -n "$REDIS_ADMIN_PASSWORD" ]; then
|
|
# With password - use ACL admin user
|
|
redis_output=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" --user admin --pass "$REDIS_ADMIN_PASSWORD" --no-auth-warning -n "$db_num" DBSIZE 2>&1)
|
|
else
|
|
# Without password
|
|
redis_output=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" -n "$db_num" DBSIZE 2>&1)
|
|
fi
|
|
|
|
# Check for authentication errors
|
|
if echo "$redis_output" | grep -q "NOAUTH"; then
|
|
echo -e "${RED}❌ Authentication required but REDIS_ADMIN_PASSWORD not set${NC}" >&2
|
|
echo -e "${YELLOW}💡 Please set REDIS_ADMIN_PASSWORD environment variable:${NC}" >&2
|
|
echo -e "${YELLOW} export REDIS_ADMIN_PASSWORD='your_password'${NC}" >&2
|
|
echo -e "${YELLOW} Or run: REDIS_ADMIN_PASSWORD='your_password' ./setup-redis.sh${NC}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Check for other errors
|
|
if echo "$redis_output" | grep -q "ERR"; then
|
|
if echo "$redis_output" | grep -q "invalid DB index"; then
|
|
echo -e "${RED}❌ Reached maximum database limit at database $db_num${NC}" >&2
|
|
echo -e "${YELLOW}💡 Redis is configured with $db_num databases maximum.${NC}" >&2
|
|
echo -e "${YELLOW}💡 Increase 'databases' setting in redis.conf or clean up unused databases.${NC}" >&2
|
|
exit 1
|
|
else
|
|
echo -e "${RED}❌ Error checking database $db_num: $redis_output${NC}" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
key_count="$redis_output"
|
|
|
|
# If database is empty, use it
|
|
if [ "$key_count" = "0" ]; then
|
|
echo -e "${GREEN}✅ Found available database: $db_num (empty)${NC}" >&2
|
|
echo "$db_num"
|
|
return
|
|
fi
|
|
|
|
echo -e "${BLUE} Database $db_num has $key_count keys, checking next...${NC}" >&2
|
|
db_num=$((db_num + 1))
|
|
done
|
|
|
|
echo -e "${RED}❌ No available databases found (checked 0-$max_attempts)${NC}" >&2
|
|
echo -e "${YELLOW}💡 All checked databases are in use. Consider cleaning up unused databases.${NC}" >&2
|
|
exit 1
|
|
}
|
|
|
|
# Function to create Redis user
|
|
create_redis_user() {
|
|
local username="$1"
|
|
local password="$2"
|
|
local db_num="$3"
|
|
|
|
echo -e "${YELLOW}👤 Creating Redis user: $username for database $db_num${NC}"
|
|
|
|
# Create user with password and permissions
|
|
# Note: >password syntax is for Redis ACL, we need to properly escape it
|
|
local result
|
|
if [ -n "$REDIS_ADMIN_PASSWORD" ]; then
|
|
# With password - use ACL admin user
|
|
result=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" --user admin --pass "$REDIS_ADMIN_PASSWORD" --no-auth-warning ACL SETUSER "$username" on ">${password}" ~* +@all 2>&1)
|
|
else
|
|
# Without password
|
|
result=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" ACL SETUSER "$username" on ">${password}" ~* +@all 2>&1)
|
|
fi
|
|
|
|
if [ $? -eq 0 ] && [ "$result" = "OK" ]; then
|
|
echo -e "${GREEN}✅ Redis user '$username' created successfully for database $db_num${NC}"
|
|
|
|
# Save ACL users to file to persist across restarts
|
|
local save_result
|
|
if [ -n "$REDIS_ADMIN_PASSWORD" ]; then
|
|
save_result=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" --user admin --pass "$REDIS_ADMIN_PASSWORD" --no-auth-warning ACL SAVE 2>&1)
|
|
else
|
|
save_result=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" ACL SAVE 2>&1)
|
|
fi
|
|
|
|
if [ "$save_result" = "OK" ]; then
|
|
echo -e "${GREEN}✅ Redis ACL users saved to file${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠️ Failed to save ACL users to file: $save_result${NC}"
|
|
fi
|
|
|
|
# Verify user was created
|
|
if [ -n "$REDIS_ADMIN_PASSWORD" ]; then
|
|
local verify=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" --user admin --pass "$REDIS_ADMIN_PASSWORD" --no-auth-warning ACL GETUSER "$username" 2>&1)
|
|
else
|
|
local verify=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" ACL GETUSER "$username" 2>&1)
|
|
fi
|
|
|
|
if [ "$verify" = "(nil)" ]; then
|
|
echo -e "${RED}❌ User creation reported OK but user does not exist${NC}"
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
else
|
|
echo -e "${RED}❌ Failed to create Redis user${NC}"
|
|
echo -e "${RED}Error: $result${NC}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to test user connection
|
|
test_user_connection() {
|
|
local username="$1"
|
|
local password="$2"
|
|
local db_num="$3"
|
|
|
|
echo -e "${YELLOW}🧪 Testing user connection...${NC}"
|
|
|
|
if redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" --user "$username" --pass "$password" --no-auth-warning -n "$db_num" ping > /dev/null 2>&1; then
|
|
echo -e "${GREEN}✅ User connection test successful${NC}"
|
|
return 0
|
|
else
|
|
echo -e "${RED}❌ User connection test failed${NC}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to mark database as in-use
|
|
mark_database_in_use() {
|
|
local db_num="$1"
|
|
|
|
echo -e "${YELLOW}📝 Marking database as in-use...${NC}"
|
|
|
|
if [ -n "$REDIS_ADMIN_PASSWORD" ]; then
|
|
redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" --user admin --pass "$REDIS_ADMIN_PASSWORD" --no-auth-warning -n "$db_num" SET "patchmon:initialized" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > /dev/null
|
|
else
|
|
redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" -n "$db_num" SET "patchmon:initialized" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > /dev/null
|
|
fi
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}✅ Database marked as in-use${NC}"
|
|
return 0
|
|
else
|
|
echo -e "${RED}❌ Failed to mark database${NC}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Main execution
|
|
main() {
|
|
# Check Redis connection
|
|
if ! check_redis_connection; then
|
|
exit 1
|
|
fi
|
|
|
|
# Generate random credentials
|
|
USERNAME="patchmon_$(generate_random_string 8)"
|
|
PASSWORD=$(generate_random_string 32)
|
|
DB_NUM=$(find_next_db)
|
|
|
|
echo ""
|
|
echo -e "${BLUE}📋 Generated Configuration:${NC}"
|
|
echo "Username: $USERNAME"
|
|
echo "Password: $PASSWORD"
|
|
echo "Database: $DB_NUM"
|
|
echo ""
|
|
|
|
# Create Redis user
|
|
if ! create_redis_user "$USERNAME" "$PASSWORD" "$DB_NUM"; then
|
|
exit 1
|
|
fi
|
|
|
|
# Test user connection
|
|
if ! test_user_connection "$USERNAME" "$PASSWORD" "$DB_NUM"; then
|
|
exit 1
|
|
fi
|
|
|
|
# Mark database as in-use to prevent reuse on next run
|
|
if ! mark_database_in_use "$DB_NUM"; then
|
|
exit 1
|
|
fi
|
|
|
|
# Output .env configuration
|
|
echo ""
|
|
echo -e "${GREEN}🎉 Redis setup completed successfully!${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}📄 Add these lines to your .env file:${NC}"
|
|
echo "=================================="
|
|
echo "REDIS_HOST=$REDIS_HOST"
|
|
echo "REDIS_PORT=$REDIS_PORT"
|
|
echo "REDIS_USER=$USERNAME"
|
|
echo "REDIS_PASSWORD=$PASSWORD"
|
|
echo "REDIS_DB=$DB_NUM"
|
|
echo "=================================="
|
|
echo ""
|
|
|
|
echo -e "${YELLOW}💡 Copy the configuration above to your .env file${NC}"
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|