mirror of
https://github.com/veops/oneterm.git
synced 2025-09-26 19:31:14 +08:00
feat(deploy): add password management scripts with setup and migration tools #75
This commit is contained in:
30
deploy/.gitignore
vendored
Normal file
30
deploy/.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# OneTerm Deploy Directory - Sensitive Files
|
||||
# Do not commit passwords or backup files
|
||||
|
||||
# Password reference files
|
||||
.passwords
|
||||
*.passwords
|
||||
|
||||
# Backup files created by migration scripts
|
||||
*.backup.*
|
||||
*.original.*
|
||||
backup_*.sql
|
||||
|
||||
# Environment files with sensitive data
|
||||
.env.local
|
||||
.env.production
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# Database volumes (if mounted locally)
|
||||
volume/
|
||||
|
||||
# Docker override files (may contain local passwords)
|
||||
docker-compose.override.yml
|
||||
docker-compose.override.yaml
|
190
deploy/README.md
Normal file
190
deploy/README.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# OneTerm Deployment Scripts
|
||||
|
||||
This directory contains scripts to help you deploy and manage OneTerm with custom database passwords.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### For New Installations
|
||||
|
||||
If you're installing OneTerm for the first time:
|
||||
|
||||
```bash
|
||||
# Clone the repository and navigate to deploy directory
|
||||
cd oneterm/deploy
|
||||
|
||||
# Run the setup script to configure passwords
|
||||
./setup.sh
|
||||
|
||||
# Start OneTerm services
|
||||
docker compose up -d
|
||||
|
||||
# Check service status
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
### For Existing Installations
|
||||
|
||||
If you already have OneTerm running and want to change passwords:
|
||||
|
||||
```bash
|
||||
# Navigate to your OneTerm deploy directory
|
||||
cd oneterm/deploy
|
||||
|
||||
# Run the migration script
|
||||
./migrate-passwords.sh
|
||||
|
||||
# The script will guide you through the password change process
|
||||
```
|
||||
|
||||
## Script Details
|
||||
|
||||
### setup.sh
|
||||
|
||||
**Purpose**: Initial configuration for new OneTerm deployments
|
||||
**When to use**: Before first `docker compose up` command
|
||||
**What it does**:
|
||||
- Configures database passwords in all configuration files
|
||||
- Creates backup of original files
|
||||
- Generates random passwords or accepts custom ones
|
||||
- Updates docker-compose.yaml, config.yaml, create-users.sql, and .env
|
||||
|
||||
**Usage**:
|
||||
```bash
|
||||
./setup.sh
|
||||
```
|
||||
|
||||
**Options**:
|
||||
- Option 1: Enter custom passwords manually
|
||||
- Option 2: Generate random passwords automatically (recommended)
|
||||
|
||||
### migrate-passwords.sh
|
||||
|
||||
**Purpose**: Password migration for existing OneTerm installations
|
||||
**When to use**: When OneTerm is already running and you want to change passwords
|
||||
**What it does**:
|
||||
- Creates database backup before changes
|
||||
- Verifies current passwords
|
||||
- Updates database user passwords
|
||||
- Updates all configuration files
|
||||
- Restarts services with new configuration
|
||||
- Performs health checks
|
||||
|
||||
**Usage**:
|
||||
```bash
|
||||
./migrate-passwords.sh
|
||||
```
|
||||
|
||||
**Safety features**:
|
||||
- Creates automatic backups
|
||||
- Verifies passwords before proceeding
|
||||
- Graceful service restart
|
||||
- Rollback instructions if issues occur
|
||||
|
||||
## File Structure
|
||||
|
||||
After running setup.sh, your directory will contain:
|
||||
|
||||
```
|
||||
deploy/
|
||||
├── docker-compose.yaml # Updated with new MySQL root password
|
||||
├── config.yaml # Updated with OneTerm DB password
|
||||
├── create-users.sql # Updated with ACL/OneTerm passwords
|
||||
├── .env # Updated with ACL configuration
|
||||
├── .passwords # Password reference file (keep secure!)
|
||||
├── setup.sh # Setup script for new installations
|
||||
├── migrate-passwords.sh # Migration script for existing systems
|
||||
└── *.backup.* # Backup files (created during migration)
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Password Storage**: The `.passwords` file contains sensitive information. Keep it secure and consider deleting after noting passwords elsewhere.
|
||||
|
||||
2. **Backup Files**: Migration creates backup files with timestamps. Review and clean up old backups periodically.
|
||||
|
||||
3. **Default Passwords**: Never use default passwords (123456) in production environments.
|
||||
|
||||
4. **Network Security**: Ensure proper firewall configuration and network isolation.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Services Won't Start After Password Change
|
||||
|
||||
1. Check service logs:
|
||||
```bash
|
||||
docker compose logs oneterm-api
|
||||
docker compose logs oneterm-acl-api
|
||||
docker compose logs oneterm-mysql
|
||||
```
|
||||
|
||||
2. Verify database connections:
|
||||
```bash
|
||||
docker exec oneterm-mysql mysql -u root -p[NEW_PASSWORD] -e "SELECT 1;"
|
||||
```
|
||||
|
||||
3. If migration failed, restore from backup:
|
||||
```bash
|
||||
# Stop services
|
||||
docker compose down
|
||||
|
||||
# Restore configuration files
|
||||
cp docker-compose.yaml.backup.TIMESTAMP docker-compose.yaml
|
||||
cp config.yaml.backup.TIMESTAMP config.yaml
|
||||
cp .env.backup.TIMESTAMP .env
|
||||
|
||||
# Restore database if needed
|
||||
docker compose up -d mysql
|
||||
docker exec oneterm-mysql mysql -u root -p[OLD_PASSWORD] < backup_TIMESTAMP.sql
|
||||
|
||||
# Start all services
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### ACL Service Connection Issues
|
||||
|
||||
If ACL service can't connect to database after password change:
|
||||
|
||||
1. Verify .env file contains correct database URL
|
||||
2. Check ACL container logs for connection errors
|
||||
3. Ensure the updated ACL image supports environment variable overrides
|
||||
|
||||
### Permission Denied Errors
|
||||
|
||||
If you get permission errors running scripts:
|
||||
|
||||
```bash
|
||||
chmod +x setup.sh migrate-passwords.sh
|
||||
```
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Custom Database Configuration
|
||||
|
||||
You can manually edit configuration files if needed:
|
||||
|
||||
1. **docker-compose.yaml**: MySQL root password
|
||||
2. **config.yaml**: OneTerm database connection
|
||||
3. **create-users.sql**: Database user creation
|
||||
4. **.env**: ACL service database configuration
|
||||
|
||||
### Using External Database
|
||||
|
||||
To use an external MySQL database:
|
||||
|
||||
1. Update database host in config.yaml and .env
|
||||
2. Ensure network connectivity
|
||||
3. Create required databases and users manually
|
||||
4. Skip MySQL container in docker-compose.yaml
|
||||
|
||||
## Support
|
||||
|
||||
For issues or questions:
|
||||
|
||||
1. Check the main OneTerm documentation
|
||||
2. Review container logs for error messages
|
||||
3. Ensure all prerequisites are met
|
||||
4. Verify network connectivity between containers
|
||||
|
||||
## Version Compatibility
|
||||
|
||||
These scripts are designed for OneTerm v25.8.2 later. For older versions, manual configuration may be required.
|
@@ -121,7 +121,7 @@ services:
|
||||
- "8666:80"
|
||||
|
||||
acl-api:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/veops/acl-api:2.1
|
||||
image: registry.cn-hangzhou.aliyuncs.com/veops/acl-api:2.2
|
||||
container_name: oneterm-acl-api
|
||||
depends_on:
|
||||
mysql:
|
||||
|
318
deploy/migrate-passwords.sh
Executable file
318
deploy/migrate-passwords.sh
Executable file
@@ -0,0 +1,318 @@
|
||||
#!/bin/bash
|
||||
# migrate-passwords.sh - Password migration tool for existing OneTerm installations
|
||||
# This script safely migrates database passwords for running OneTerm systems
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${CYAN}=== OneTerm Password Migration Tool ===${NC}"
|
||||
echo -e "${YELLOW}WARNING: This will change database passwords for running system${NC}"
|
||||
echo -e "${BLUE}Please ensure you have backups before proceeding${NC}"
|
||||
echo
|
||||
|
||||
# Function to check if docker compose is available
|
||||
check_docker_compose() {
|
||||
if command -v docker-compose &> /dev/null; then
|
||||
DOCKER_COMPOSE="docker-compose"
|
||||
elif docker compose version &> /dev/null; then
|
||||
DOCKER_COMPOSE="docker compose"
|
||||
else
|
||||
echo "ERROR: Docker Compose not found"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to verify container is running
|
||||
check_container_running() {
|
||||
local container_name=$1
|
||||
if ! docker ps --format "table {{.Names}}" | grep -q "^${container_name}$"; then
|
||||
echo -e "${RED}ERROR: Container ${container_name} is not running${NC}"
|
||||
echo "Please start OneTerm containers first: ${DOCKER_COMPOSE} up -d"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to test database connection
|
||||
test_db_connection() {
|
||||
local username=$1
|
||||
local password=$2
|
||||
local database=${3:-""}
|
||||
|
||||
if [ -n "$database" ]; then
|
||||
docker exec oneterm-mysql mysql -u "$username" -p"$password" "$database" -e "SELECT 1;" &>/dev/null
|
||||
else
|
||||
docker exec oneterm-mysql mysql -u "$username" -p"$password" -e "SELECT 1;" &>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# Initialize
|
||||
check_docker_compose
|
||||
|
||||
echo "Checking system status..."
|
||||
check_container_running "oneterm-mysql"
|
||||
|
||||
# Get current passwords
|
||||
echo "Enter CURRENT passwords (press Enter for default '123456'):"
|
||||
echo -n "Current MySQL root password [123456]: "
|
||||
read -s CURRENT_ROOT
|
||||
CURRENT_ROOT=${CURRENT_ROOT:-123456}
|
||||
echo
|
||||
|
||||
echo -n "Current ACL database password [123456]: "
|
||||
read -s CURRENT_ACL
|
||||
CURRENT_ACL=${CURRENT_ACL:-123456}
|
||||
echo
|
||||
|
||||
echo -n "Current OneTerm database password [123456]: "
|
||||
read -s CURRENT_ONETERM
|
||||
CURRENT_ONETERM=${CURRENT_ONETERM:-123456}
|
||||
echo
|
||||
|
||||
# Get new passwords
|
||||
echo
|
||||
echo "Enter NEW passwords:"
|
||||
echo -n "New MySQL root password: "
|
||||
read -s NEW_ROOT
|
||||
echo
|
||||
|
||||
while [ -z "$NEW_ROOT" ]; do
|
||||
echo "Root password cannot be empty!"
|
||||
echo -n "New MySQL root password: "
|
||||
read -s NEW_ROOT
|
||||
echo
|
||||
done
|
||||
|
||||
echo -n "New ACL database password: "
|
||||
read -s NEW_ACL
|
||||
echo
|
||||
|
||||
while [ -z "$NEW_ACL" ]; do
|
||||
echo "ACL password cannot be empty!"
|
||||
echo -n "New ACL database password: "
|
||||
read -s NEW_ACL
|
||||
echo
|
||||
done
|
||||
|
||||
echo -n "New OneTerm database password: "
|
||||
read -s NEW_ONETERM
|
||||
echo
|
||||
|
||||
while [ -z "$NEW_ONETERM" ]; do
|
||||
echo "OneTerm password cannot be empty!"
|
||||
echo -n "New OneTerm database password: "
|
||||
read -s NEW_ONETERM
|
||||
echo
|
||||
done
|
||||
|
||||
# Verify current passwords
|
||||
echo
|
||||
echo "Verifying current passwords..."
|
||||
if ! test_db_connection "root" "$CURRENT_ROOT"; then
|
||||
echo "ERROR: Current root password is incorrect!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! test_db_connection "acl" "$CURRENT_ACL" "acl"; then
|
||||
echo "ERROR: Current ACL password is incorrect!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! test_db_connection "oneterm" "$CURRENT_ONETERM" "oneterm"; then
|
||||
echo "ERROR: Current OneTerm password is incorrect!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}SUCCESS: Current passwords verified${NC}"
|
||||
|
||||
# Create backup
|
||||
echo
|
||||
echo "Creating database backup..."
|
||||
BACKUP_FILE="backup_$(date +%Y%m%d_%H%M%S).sql"
|
||||
docker exec oneterm-mysql mysqldump -u root -p"${CURRENT_ROOT}" --all-databases > "$BACKUP_FILE"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "SUCCESS: Database backup created: $BACKUP_FILE"
|
||||
else
|
||||
echo "ERROR: Failed to create backup"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Stop application services (keep database running)
|
||||
echo
|
||||
echo "Stopping application services..."
|
||||
$DOCKER_COMPOSE stop oneterm-api oneterm-acl-api oneterm-ui oneterm-guacd 2>/dev/null || true
|
||||
|
||||
# Wait a moment for graceful shutdown
|
||||
sleep 5
|
||||
|
||||
# Update database passwords
|
||||
echo
|
||||
echo "Updating database passwords..."
|
||||
|
||||
# Update database passwords using direct execution
|
||||
echo "Updating root password..."
|
||||
docker exec oneterm-mysql mysql -u root -p"${CURRENT_ROOT}" -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${NEW_ROOT}'; ALTER USER 'root'@'%' IDENTIFIED BY '${NEW_ROOT}'; FLUSH PRIVILEGES;" 2>/dev/null
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}Root password updated successfully${NC}"
|
||||
else
|
||||
echo "ERROR: Failed to update root password"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Updating application user passwords..."
|
||||
docker exec oneterm-mysql mysql -u root -p"${NEW_ROOT}" -e "ALTER USER 'acl'@'%' IDENTIFIED BY '${NEW_ACL}'; ALTER USER 'oneterm'@'%' IDENTIFIED BY '${NEW_ONETERM}'; FLUSH PRIVILEGES;" 2>/dev/null
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}SUCCESS: Database passwords updated${NC}"
|
||||
else
|
||||
echo "ERROR: Failed to update application user passwords"
|
||||
echo "You may need to restore from backup: $BACKUP_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Backup configuration files
|
||||
echo
|
||||
echo "Backing up configuration files..."
|
||||
cp docker-compose.yaml docker-compose.yaml.backup.$(date +%Y%m%d_%H%M%S) 2>/dev/null || true
|
||||
cp config.yaml config.yaml.backup.$(date +%Y%m%d_%H%M%S) 2>/dev/null || true
|
||||
cp .env .env.backup.$(date +%Y%m%d_%H%M%S) 2>/dev/null || true
|
||||
|
||||
# Update docker-compose.yaml
|
||||
echo "Updating docker-compose.yaml..."
|
||||
if [ -f docker-compose.yaml ]; then
|
||||
# Create a temporary file for safer processing
|
||||
cp docker-compose.yaml docker-compose.yaml.tmp
|
||||
|
||||
# Escape special characters in password for sed
|
||||
ESCAPED_NEW_ROOT=$(printf '%s\n' "$NEW_ROOT" | sed 's/[[\.*^$()+?{|]/\\&/g')
|
||||
|
||||
# Update MySQL root password - use escaped password
|
||||
sed -i '' "s|MYSQL_ROOT_PASSWORD: '[^']*'|MYSQL_ROOT_PASSWORD: '${ESCAPED_NEW_ROOT}'|g" docker-compose.yaml.tmp
|
||||
sed -i '' "s|MYSQL_ROOT_PASSWORD: \"[^\"]*\"|MYSQL_ROOT_PASSWORD: \"${ESCAPED_NEW_ROOT}\"|g" docker-compose.yaml.tmp
|
||||
|
||||
# Handle unquoted passwords
|
||||
sed -i '' "s|MYSQL_ROOT_PASSWORD: [^'\"[:space:]]*$|MYSQL_ROOT_PASSWORD: '${ESCAPED_NEW_ROOT}'|g" docker-compose.yaml.tmp
|
||||
|
||||
# Update healthcheck password for MySQL - handle current format
|
||||
sed -i '' "s|\"-p[0-9][0-9]*\"|\"-p${ESCAPED_NEW_ROOT}\"|g" docker-compose.yaml.tmp
|
||||
|
||||
# Move updated file back
|
||||
mv docker-compose.yaml.tmp docker-compose.yaml
|
||||
|
||||
echo "SUCCESS: docker-compose.yaml updated"
|
||||
fi
|
||||
|
||||
# Update config.yaml for OneTerm (only MySQL password, not Redis)
|
||||
echo "Updating config.yaml..."
|
||||
if [ -f config.yaml ]; then
|
||||
# config.yaml uses root user, so use root password
|
||||
ESCAPED_NEW_ROOT_FOR_CONFIG=$(printf '%s\n' "$NEW_ROOT" | sed 's/[[\.*^$()+?{|]/\\&/g')
|
||||
# Update only MySQL password section, not Redis
|
||||
sed -i .tmp '/^mysql:/,/^[a-z]/s|password: [^#]*|password: '"${ESCAPED_NEW_ROOT_FOR_CONFIG}"'|g' config.yaml
|
||||
rm -f config.yaml.tmp
|
||||
echo -e "${GREEN}SUCCESS: config.yaml updated${NC}"
|
||||
fi
|
||||
|
||||
# Update .env file for ACL
|
||||
echo "Updating .env file..."
|
||||
cat > .env << EOF
|
||||
# Updated by migration script $(date)
|
||||
FLASK_APP=autoapp.py
|
||||
FLASK_DEBUG=1
|
||||
FLASK_ENV=development
|
||||
GUNICORN_WORKERS=2
|
||||
LOG_LEVEL=debug
|
||||
SECRET_KEY='xW2FAUfgffjmerTEBXADmURDOQ43ojLN'
|
||||
|
||||
# Database password - used by settings.py to build connection string
|
||||
DB_ACL_PASSWORD=${NEW_ACL}
|
||||
DB_ONETERM_PASSWORD=${NEW_ONETERM}
|
||||
DB_ROOT_PASSWORD=${NEW_ROOT}
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN}SUCCESS: .env file updated${NC}"
|
||||
|
||||
# Note: ACL API settings.py should be updated in the Docker image to read DB_ACL_PASSWORD from environment
|
||||
|
||||
# Restart services
|
||||
echo
|
||||
echo "Restarting OneTerm services..."
|
||||
$DOCKER_COMPOSE down
|
||||
$DOCKER_COMPOSE up -d
|
||||
|
||||
# Wait for services to start
|
||||
echo "Waiting for services to start..."
|
||||
sleep 30
|
||||
|
||||
# Health check
|
||||
echo
|
||||
echo "Performing health check..."
|
||||
UNHEALTHY_SERVICES=0
|
||||
|
||||
# Check each service
|
||||
for service in oneterm-mysql oneterm-redis oneterm-acl-api oneterm-api oneterm-ui; do
|
||||
if docker ps --format "table {{.Names}}\t{{.Status}}" | grep "$service" | grep -q "unhealthy\|Exited\|Restarting"; then
|
||||
echo "WARNING: Service $service appears unhealthy"
|
||||
UNHEALTHY_SERVICES=$((UNHEALTHY_SERVICES + 1))
|
||||
else
|
||||
echo "OK: Service $service is running"
|
||||
fi
|
||||
done
|
||||
|
||||
# Test database connections with new passwords
|
||||
echo
|
||||
echo "Testing database connections..."
|
||||
if test_db_connection "root" "$NEW_ROOT"; then
|
||||
echo "OK: Root connection successful"
|
||||
else
|
||||
echo "WARNING: Root connection failed"
|
||||
UNHEALTHY_SERVICES=$((UNHEALTHY_SERVICES + 1))
|
||||
fi
|
||||
|
||||
if test_db_connection "acl" "$NEW_ACL" "acl"; then
|
||||
echo "OK: ACL connection successful"
|
||||
else
|
||||
echo "WARNING: ACL connection failed"
|
||||
UNHEALTHY_SERVICES=$((UNHEALTHY_SERVICES + 1))
|
||||
fi
|
||||
|
||||
if test_db_connection "oneterm" "$NEW_ONETERM" "oneterm"; then
|
||||
echo "OK: OneTerm connection successful"
|
||||
else
|
||||
echo "WARNING: OneTerm connection failed"
|
||||
UNHEALTHY_SERVICES=$((UNHEALTHY_SERVICES + 1))
|
||||
fi
|
||||
|
||||
# Final status
|
||||
echo
|
||||
echo -e "${CYAN}=== Migration Summary ===${NC}"
|
||||
if [ $UNHEALTHY_SERVICES -eq 0 ]; then
|
||||
echo -e "${GREEN}SUCCESS: Password migration completed successfully!${NC}"
|
||||
echo -e "${GREEN}All services are running normally with new passwords.${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}WARNING: Migration completed but $UNHEALTHY_SERVICES issue(s) detected.${NC}"
|
||||
echo -e "${BLUE}Check service logs if you experience problems:${NC}"
|
||||
echo -e " ${CYAN}$DOCKER_COMPOSE logs oneterm-api${NC}"
|
||||
echo -e " ${CYAN}$DOCKER_COMPOSE logs oneterm-acl-api${NC}"
|
||||
echo -e " ${CYAN}$DOCKER_COMPOSE logs oneterm-mysql${NC}"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Backup files created:"
|
||||
echo " Database backup: $BACKUP_FILE"
|
||||
echo " Config backups: *.backup.*"
|
||||
echo
|
||||
echo "If you encounter issues, you can:"
|
||||
echo "1. Check logs: $DOCKER_COMPOSE logs [service-name]"
|
||||
echo "2. Restart services: $DOCKER_COMPOSE restart"
|
||||
echo "3. Restore from backup if needed"
|
||||
echo
|
||||
echo "Migration completed at $(date)"
|
252
deploy/setup.sh
Executable file
252
deploy/setup.sh
Executable file
@@ -0,0 +1,252 @@
|
||||
#!/bin/bash
|
||||
# setup.sh - Initial setup script for new OneTerm installations
|
||||
# This script helps users configure passwords before first deployment
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${CYAN}=== OneTerm Initial Setup ===${NC}"
|
||||
echo -e "${BLUE}This script will help you configure OneTerm for first-time deployment${NC}"
|
||||
echo
|
||||
|
||||
# Function to generate random password
|
||||
generate_password() {
|
||||
openssl rand -base64 12 2>/dev/null || date +%s | sha256sum | base64 | head -c 12
|
||||
}
|
||||
|
||||
# Function to check if files exist
|
||||
check_files() {
|
||||
local missing_files=0
|
||||
|
||||
if [ ! -f "docker-compose.yaml" ]; then
|
||||
echo "ERROR: docker-compose.yaml not found in current directory"
|
||||
missing_files=$((missing_files + 1))
|
||||
fi
|
||||
|
||||
if [ ! -f "config.yaml" ]; then
|
||||
echo "ERROR: config.yaml not found in current directory"
|
||||
missing_files=$((missing_files + 1))
|
||||
fi
|
||||
|
||||
if [ ! -f "create-users.sql" ]; then
|
||||
echo "ERROR: create-users.sql not found in current directory"
|
||||
missing_files=$((missing_files + 1))
|
||||
fi
|
||||
|
||||
if [ $missing_files -gt 0 ]; then
|
||||
echo "Please run this script from the OneTerm deploy directory"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to backup original files
|
||||
backup_files() {
|
||||
local timestamp=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
echo "Creating backup of original files..."
|
||||
cp docker-compose.yaml docker-compose.yaml.original.$timestamp
|
||||
cp config.yaml config.yaml.original.$timestamp
|
||||
cp create-users.sql create-users.sql.original.$timestamp
|
||||
echo "Backup files created with suffix: .original.$timestamp"
|
||||
}
|
||||
|
||||
# Function to validate password strength
|
||||
validate_password() {
|
||||
local password=$1
|
||||
local min_length=8
|
||||
|
||||
if [ ${#password} -lt $min_length ]; then
|
||||
echo "Password must be at least $min_length characters long"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Check prerequisites
|
||||
check_files
|
||||
|
||||
# Check if this looks like an existing installation
|
||||
if docker ps 2>/dev/null | grep -q "oneterm"; then
|
||||
echo "WARNING: OneTerm containers are already running!"
|
||||
echo "This appears to be an existing installation."
|
||||
echo "For existing installations, use migrate-passwords.sh instead"
|
||||
echo
|
||||
echo -n "Continue anyway? (y/N): "
|
||||
read -r response
|
||||
if [[ ! "$response" =~ ^[Yy]$ ]]; then
|
||||
echo "Setup cancelled"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Backup original files
|
||||
backup_files
|
||||
|
||||
echo
|
||||
echo "Password Configuration:"
|
||||
echo "You can either:"
|
||||
echo "1. Enter custom passwords"
|
||||
echo "2. Generate random passwords automatically"
|
||||
echo
|
||||
|
||||
echo -n "Choose option (1/2) [2]: "
|
||||
read -r option
|
||||
option=${option:-2}
|
||||
|
||||
if [ "$option" = "1" ]; then
|
||||
# Manual password entry
|
||||
echo
|
||||
echo "Enter passwords for database users:"
|
||||
|
||||
echo -n "MySQL root password: "
|
||||
read -s ROOT_PASS
|
||||
echo
|
||||
while ! validate_password "$ROOT_PASS"; do
|
||||
echo -n "MySQL root password (min 8 chars): "
|
||||
read -s ROOT_PASS
|
||||
echo
|
||||
done
|
||||
|
||||
echo -n "ACL database password: "
|
||||
read -s ACL_PASS
|
||||
echo
|
||||
while ! validate_password "$ACL_PASS"; do
|
||||
echo -n "ACL database password (min 8 chars): "
|
||||
read -s ACL_PASS
|
||||
echo
|
||||
done
|
||||
|
||||
echo -n "OneTerm database password: "
|
||||
read -s ONETERM_PASS
|
||||
echo
|
||||
while ! validate_password "$ONETERM_PASS"; do
|
||||
echo -n "OneTerm database password (min 8 chars): "
|
||||
read -s ONETERM_PASS
|
||||
echo
|
||||
done
|
||||
|
||||
elif [ "$option" = "2" ]; then
|
||||
# Generate random passwords
|
||||
echo
|
||||
echo "Generating random passwords..."
|
||||
ROOT_PASS=$(generate_password)
|
||||
ACL_PASS=$(generate_password)
|
||||
ONETERM_PASS=$(generate_password)
|
||||
|
||||
echo "Generated passwords:"
|
||||
echo " MySQL root: $ROOT_PASS"
|
||||
echo " ACL database: $ACL_PASS"
|
||||
echo " OneTerm database: $ONETERM_PASS"
|
||||
echo
|
||||
echo "IMPORTANT: Save these passwords securely!"
|
||||
echo
|
||||
else
|
||||
echo "Invalid option selected"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update docker-compose.yaml
|
||||
echo
|
||||
echo "Updating docker-compose.yaml..."
|
||||
# Create a temporary file for safer processing
|
||||
cp docker-compose.yaml docker-compose.yaml.tmp
|
||||
|
||||
# Escape special characters in password for sed
|
||||
ESCAPED_ROOT_PASS=$(printf '%s\n' "$ROOT_PASS" | sed 's/[[\.*^$()+?{|]/\\&/g')
|
||||
|
||||
# Update MySQL root password patterns - handle various formats
|
||||
sed -i '' "s|MYSQL_ROOT_PASSWORD: '[^']*'|MYSQL_ROOT_PASSWORD: '${ESCAPED_ROOT_PASS}'|g" docker-compose.yaml.tmp
|
||||
sed -i '' "s|MYSQL_ROOT_PASSWORD: \"[^\"]*\"|MYSQL_ROOT_PASSWORD: \"${ESCAPED_ROOT_PASS}\"|g" docker-compose.yaml.tmp
|
||||
sed -i '' "s|MYSQL_ROOT_PASSWORD: [^'\"[:space:]]*$|MYSQL_ROOT_PASSWORD: '${ESCAPED_ROOT_PASS}'|g" docker-compose.yaml.tmp
|
||||
|
||||
# Update healthcheck password
|
||||
sed -i '' "s|\"-p[0-9][0-9]*\"|\"-p${ESCAPED_ROOT_PASS}\"|g" docker-compose.yaml.tmp
|
||||
|
||||
# Move updated file back
|
||||
mv docker-compose.yaml.tmp docker-compose.yaml
|
||||
|
||||
# Update config.yaml (only MySQL password, not Redis)
|
||||
echo "Updating config.yaml..."
|
||||
# config.yaml uses root user, so use root password
|
||||
ESCAPED_ROOT_PASS_FOR_CONFIG=$(printf '%s\n' "$ROOT_PASS" | sed 's/[[\.*^$()+?{|]/\\&/g')
|
||||
# Only update MySQL password section, not Redis
|
||||
sed -i .tmp '/^mysql:/,/^[a-z]/s|password: [^#]*|password: '"${ESCAPED_ROOT_PASS_FOR_CONFIG}"'|g' config.yaml
|
||||
rm -f config.yaml.tmp
|
||||
|
||||
# Update create-users.sql
|
||||
echo "Updating create-users.sql..."
|
||||
# Escape passwords for sed
|
||||
ESCAPED_ONETERM_PASS=$(printf '%s\n' "$ONETERM_PASS" | sed 's/[[\.*^$()+?{|]/\\&/g')
|
||||
ESCAPED_ACL_PASS=$(printf '%s\n' "$ACL_PASS" | sed 's/[[\.*^$()+?{|]/\\&/g')
|
||||
# Update passwords using | as delimiter
|
||||
sed -i .tmp "s|'oneterm'@'%' IDENTIFIED BY '[^']*'|'oneterm'@'%' IDENTIFIED BY '${ESCAPED_ONETERM_PASS}'|g" create-users.sql
|
||||
sed -i .tmp "s|'acl'@'%' IDENTIFIED BY '[^']*'|'acl'@'%' IDENTIFIED BY '${ESCAPED_ACL_PASS}'|g" create-users.sql
|
||||
rm -f create-users.sql.tmp
|
||||
|
||||
# Create/update .env file for ACL
|
||||
echo "Creating .env file..."
|
||||
cat > .env << EOF
|
||||
# OneTerm Configuration
|
||||
# Generated by setup script on $(date)
|
||||
|
||||
FLASK_APP=autoapp.py
|
||||
FLASK_DEBUG=1
|
||||
FLASK_ENV=development
|
||||
GUNICORN_WORKERS=2
|
||||
LOG_LEVEL=debug
|
||||
SECRET_KEY='xW2FAUfgffjmerTEBXADmURDOQ43ojLN'
|
||||
|
||||
# Database password - used by settings.py to build connection string
|
||||
DB_ROOT_PASSWORD=${ROOT_PASS}
|
||||
DB_ACL_PASSWORD=${ACL_PASS}
|
||||
DB_ONETERM_PASSWORD=${ONETERM_PASS}
|
||||
EOF
|
||||
|
||||
# Note: ACL API Docker image should be updated to read DB_ACL_PASSWORD from environment
|
||||
|
||||
# Save passwords to a secure file
|
||||
echo "Creating password reference file..."
|
||||
cat > .passwords << EOF
|
||||
# OneTerm Database Passwords
|
||||
# Generated on $(date)
|
||||
# Keep this file secure and do not commit to version control
|
||||
|
||||
MySQL Root Password: ${ROOT_PASS}
|
||||
ACL Database Password: ${ACL_PASS}
|
||||
OneTerm Database Password: ${ONETERM_PASS}
|
||||
EOF
|
||||
|
||||
chmod 600 .passwords
|
||||
|
||||
echo
|
||||
echo -e "${GREEN}=== Setup Complete ===${NC}"
|
||||
echo -e "${GREEN}Configuration files have been updated with your passwords.${NC}"
|
||||
echo
|
||||
echo -e "${BLUE}Files modified:${NC}"
|
||||
echo -e " ${CYAN}- docker-compose.yaml${NC} (MySQL root password)"
|
||||
echo -e " ${CYAN}- config.yaml${NC} (MySQL root password for OneTerm API)"
|
||||
echo -e " ${CYAN}- create-users.sql${NC} (ACL and OneTerm database user passwords)"
|
||||
echo -e " ${CYAN}- .env${NC} (ACL database configuration)"
|
||||
echo
|
||||
echo -e "${BLUE}Files created:${NC}"
|
||||
echo -e " ${YELLOW}- .passwords${NC} (password reference - keep secure!)"
|
||||
echo
|
||||
echo -e "${YELLOW}Next steps:${NC}"
|
||||
echo -e "${GREEN}1.${NC} Review the configuration files"
|
||||
echo -e "${GREEN}2.${NC} Start OneTerm: ${CYAN}docker compose up -d${NC}"
|
||||
echo -e "${GREEN}3.${NC} Wait for all services to become healthy"
|
||||
echo -e "${GREEN}4.${NC} Access the web interface"
|
||||
echo
|
||||
echo "To check service status: docker compose ps"
|
||||
echo "To view logs: docker compose logs [service-name]"
|
||||
echo
|
||||
echo "SECURITY NOTE: The .passwords file contains sensitive information."
|
||||
echo "Keep it secure and consider deleting it after noting the passwords elsewhere."
|
Reference in New Issue
Block a user