
Some checks failed
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Security Audit (push) Has been cancelled
CI/CD Pipeline / Build Docker Image (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Performance Benchmarks (push) Has been cancelled
CI/CD Pipeline / Cleanup (push) Has been cancelled
656 lines
16 KiB
Bash
Executable File
656 lines
16 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Configuration Management Script for Rustelo
|
|
# Provides commands to manage, validate, and deploy configurations
|
|
# Usage: ./manage-config.sh [command] [options]
|
|
|
|
set -e
|
|
|
|
# Script configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
CONFIG_DIR="$(dirname "$SCRIPT_DIR")"
|
|
PROJECT_ROOT="$(dirname "$CONFIG_DIR")"
|
|
BACKUP_DIR="$CONFIG_DIR/backups"
|
|
ENVIRONMENTS=("dev" "prod" "example")
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
PURPLE='\033[0;35m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Logging functions
|
|
log_info() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
log_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
log_debug() {
|
|
if [ "${DEBUG:-0}" = "1" ]; then
|
|
echo -e "${PURPLE}[DEBUG]${NC} $1"
|
|
fi
|
|
}
|
|
|
|
# Show help
|
|
show_help() {
|
|
cat << EOF
|
|
Configuration Management Script for Rustelo
|
|
|
|
USAGE:
|
|
$0 [COMMAND] [OPTIONS]
|
|
|
|
COMMANDS:
|
|
build ENV [OUTPUT] Build configuration for environment
|
|
validate ENV Validate configuration for environment
|
|
list-features List available features
|
|
list-environments List available environments
|
|
backup ENV Backup existing configuration
|
|
restore BACKUP_FILE Restore configuration from backup
|
|
diff ENV1 ENV2 Compare configurations between environments
|
|
template FEATURE Create new feature template
|
|
clean Clean generated configurations
|
|
status Show configuration status
|
|
help Show this help message
|
|
|
|
ENVIRONMENTS:
|
|
dev Development environment
|
|
prod Production environment
|
|
example Example/template environment
|
|
|
|
OPTIONS:
|
|
--debug Enable debug output
|
|
--dry-run Show what would be done without executing
|
|
--force Force operation without confirmation
|
|
--quiet Suppress non-error output
|
|
--backup-dir DIR Use custom backup directory
|
|
|
|
EXAMPLES:
|
|
$0 build dev # Build dev configuration
|
|
$0 build prod config.prod.toml # Build prod config with custom name
|
|
$0 validate dev # Validate dev configuration
|
|
$0 diff dev prod # Compare dev and prod configurations
|
|
$0 backup prod # Backup prod configuration
|
|
$0 template auth # Create new auth feature template
|
|
$0 clean # Clean all generated configs
|
|
$0 status # Show configuration status
|
|
|
|
ENVIRONMENT VARIABLES:
|
|
CONFIG_DEBUG=1 Enable debug output
|
|
CONFIG_QUIET=1 Suppress non-error output
|
|
CONFIG_FORCE=1 Force operations without confirmation
|
|
CONFIG_BACKUP_DIR=path Custom backup directory
|
|
|
|
EOF
|
|
}
|
|
|
|
# Parse command line arguments
|
|
parse_args() {
|
|
COMMAND=""
|
|
ENV=""
|
|
OUTPUT=""
|
|
DEBUG="${DEBUG:-0}"
|
|
DRY_RUN="${DRY_RUN:-0}"
|
|
FORCE="${FORCE:-0}"
|
|
QUIET="${QUIET:-0}"
|
|
BACKUP_DIR_OVERRIDE=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--debug)
|
|
DEBUG=1
|
|
shift
|
|
;;
|
|
--dry-run)
|
|
DRY_RUN=1
|
|
shift
|
|
;;
|
|
--force)
|
|
FORCE=1
|
|
shift
|
|
;;
|
|
--quiet)
|
|
QUIET=1
|
|
shift
|
|
;;
|
|
--backup-dir)
|
|
BACKUP_DIR_OVERRIDE="$2"
|
|
shift 2
|
|
;;
|
|
build|validate|backup|restore|diff|template|clean|status|list-features|list-environments|help)
|
|
COMMAND="$1"
|
|
shift
|
|
;;
|
|
*)
|
|
if [ -z "$ENV" ]; then
|
|
ENV="$1"
|
|
elif [ -z "$OUTPUT" ]; then
|
|
OUTPUT="$1"
|
|
else
|
|
log_error "Unknown argument: $1"
|
|
exit 1
|
|
fi
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Override backup directory if specified
|
|
if [ -n "$BACKUP_DIR_OVERRIDE" ]; then
|
|
BACKUP_DIR="$BACKUP_DIR_OVERRIDE"
|
|
fi
|
|
|
|
# Apply environment variables
|
|
[ "${CONFIG_DEBUG:-0}" = "1" ] && DEBUG=1
|
|
[ "${CONFIG_QUIET:-0}" = "1" ] && QUIET=1
|
|
[ "${CONFIG_FORCE:-0}" = "1" ] && FORCE=1
|
|
[ -n "${CONFIG_BACKUP_DIR:-}" ] && BACKUP_DIR="$CONFIG_BACKUP_DIR"
|
|
}
|
|
|
|
# Check if environment is valid
|
|
validate_environment() {
|
|
local env="$1"
|
|
for valid_env in "${ENVIRONMENTS[@]}"; do
|
|
if [ "$env" = "$valid_env" ]; then
|
|
return 0
|
|
fi
|
|
done
|
|
log_error "Invalid environment: $env"
|
|
log_error "Valid environments: ${ENVIRONMENTS[*]}"
|
|
return 1
|
|
}
|
|
|
|
# Create backup directory if it doesn't exist
|
|
ensure_backup_dir() {
|
|
if [ ! -d "$BACKUP_DIR" ]; then
|
|
mkdir -p "$BACKUP_DIR"
|
|
log_debug "Created backup directory: $BACKUP_DIR"
|
|
fi
|
|
}
|
|
|
|
# Build configuration
|
|
cmd_build() {
|
|
local env="$1"
|
|
local output="${2:-config.toml}"
|
|
|
|
if [ -z "$env" ]; then
|
|
log_error "Environment required for build command"
|
|
return 1
|
|
fi
|
|
|
|
if ! validate_environment "$env"; then
|
|
return 1
|
|
fi
|
|
|
|
log_info "Building configuration for environment: $env"
|
|
|
|
# Use Python script if available, otherwise use bash script
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
log_info "Would build configuration using shell script"
|
|
return 0
|
|
fi
|
|
"$SCRIPT_DIR/build-config.sh" "$env" "$output"
|
|
}
|
|
|
|
# Validate configuration
|
|
cmd_validate() {
|
|
local env="$1"
|
|
|
|
if [ -z "$env" ]; then
|
|
log_error "Environment required for validate command"
|
|
return 1
|
|
fi
|
|
|
|
if ! validate_environment "$env"; then
|
|
return 1
|
|
fi
|
|
|
|
log_info "Validating configuration for environment: $env"
|
|
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
log_info "Would validate configuration"
|
|
return 0
|
|
fi
|
|
|
|
# Use Python script if available
|
|
CONFIG_VALIDATE_ONLY=1 "$SCRIPT_DIR/build-config.sh" "$env"
|
|
}
|
|
|
|
# List available features
|
|
cmd_list_features() {
|
|
log_info "Available features:"
|
|
|
|
if [ -d "$CONFIG_DIR/features" ]; then
|
|
for feature_dir in "$CONFIG_DIR/features"/*; do
|
|
if [ -d "$feature_dir" ]; then
|
|
local feature_name=$(basename "$feature_dir")
|
|
log_info " - $feature_name"
|
|
|
|
# Show available environments for this feature
|
|
local envs=()
|
|
for env in "${ENVIRONMENTS[@]}"; do
|
|
if [ -f "$feature_dir/$env.toml" ]; then
|
|
envs+=("$env")
|
|
fi
|
|
done
|
|
|
|
if [ ${#envs[@]} -gt 0 ]; then
|
|
log_info " Environments: ${envs[*]}"
|
|
fi
|
|
fi
|
|
done
|
|
else
|
|
log_error "Features directory not found: $CONFIG_DIR/features"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# List available environments
|
|
cmd_list_environments() {
|
|
log_info "Available environments:"
|
|
|
|
for env in "${ENVIRONMENTS[@]}"; do
|
|
log_info " - $env"
|
|
|
|
# Check if base configuration exists
|
|
if [ -f "$CONFIG_DIR/base/$env.toml" ]; then
|
|
log_info " Base config: ✓"
|
|
else
|
|
log_info " Base config: ✗"
|
|
fi
|
|
|
|
# Count available features
|
|
local feature_count=0
|
|
if [ -d "$CONFIG_DIR/features" ]; then
|
|
for feature_dir in "$CONFIG_DIR/features"/*; do
|
|
if [ -d "$feature_dir" ] && [ -f "$feature_dir/$env.toml" ]; then
|
|
((feature_count++))
|
|
fi
|
|
done
|
|
fi
|
|
log_info " Available features: $feature_count"
|
|
done
|
|
}
|
|
|
|
# Compare configurations between environments
|
|
cmd_diff() {
|
|
local env1="$1"
|
|
local env2="$2"
|
|
|
|
if [ -z "$env1" ] || [ -z "$env2" ]; then
|
|
log_error "Two environments required for diff command"
|
|
return 1
|
|
fi
|
|
|
|
if ! validate_environment "$env1" || ! validate_environment "$env2"; then
|
|
return 1
|
|
fi
|
|
|
|
log_info "Comparing configurations: $env1 vs $env2"
|
|
|
|
# Create temporary files
|
|
local temp1=$(mktemp)
|
|
local temp2=$(mktemp)
|
|
trap "rm -f $temp1 $temp2" EXIT
|
|
|
|
# Build configurations
|
|
if ! cmd_build "$env1" "$temp1"; then
|
|
log_error "Failed to build configuration for $env1"
|
|
return 1
|
|
fi
|
|
|
|
if ! cmd_build "$env2" "$temp2"; then
|
|
log_error "Failed to build configuration for $env2"
|
|
return 1
|
|
fi
|
|
|
|
# Compare configurations
|
|
if command -v diff &> /dev/null; then
|
|
diff -u "$temp1" "$temp2" || true
|
|
else
|
|
log_warning "diff command not available, using basic comparison"
|
|
if cmp -s "$temp1" "$temp2"; then
|
|
log_info "Configurations are identical"
|
|
else
|
|
log_info "Configurations differ"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Create backup of configuration
|
|
cmd_backup() {
|
|
local env="$1"
|
|
local config_file="${2:-config.toml}"
|
|
|
|
if [ -z "$env" ]; then
|
|
log_error "Environment required for backup command"
|
|
return 1
|
|
fi
|
|
|
|
if ! validate_environment "$env"; then
|
|
return 1
|
|
fi
|
|
|
|
ensure_backup_dir
|
|
|
|
local timestamp=$(date +%Y%m%d_%H%M%S)
|
|
local backup_file="$BACKUP_DIR/config_${env}_${timestamp}.toml"
|
|
|
|
if [ -f "$config_file" ]; then
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
log_info "Would backup $config_file to $backup_file"
|
|
return 0
|
|
fi
|
|
|
|
cp "$config_file" "$backup_file"
|
|
log_success "Configuration backed up to: $backup_file"
|
|
else
|
|
log_error "Configuration file not found: $config_file"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Restore configuration from backup
|
|
cmd_restore() {
|
|
local backup_file="$1"
|
|
local output_file="${2:-config.toml}"
|
|
|
|
if [ -z "$backup_file" ]; then
|
|
log_error "Backup file required for restore command"
|
|
return 1
|
|
fi
|
|
|
|
if [ ! -f "$backup_file" ]; then
|
|
log_error "Backup file not found: $backup_file"
|
|
return 1
|
|
fi
|
|
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
log_info "Would restore $backup_file to $output_file"
|
|
return 0
|
|
fi
|
|
|
|
# Create backup of current file if it exists
|
|
if [ -f "$output_file" ]; then
|
|
local timestamp=$(date +%Y%m%d_%H%M%S)
|
|
local current_backup="$BACKUP_DIR/config_current_${timestamp}.toml"
|
|
ensure_backup_dir
|
|
cp "$output_file" "$current_backup"
|
|
log_info "Current configuration backed up to: $current_backup"
|
|
fi
|
|
|
|
cp "$backup_file" "$output_file"
|
|
log_success "Configuration restored from: $backup_file"
|
|
}
|
|
|
|
# Create new feature template
|
|
cmd_template() {
|
|
local feature_name="$1"
|
|
|
|
if [ -z "$feature_name" ]; then
|
|
log_error "Feature name required for template command"
|
|
return 1
|
|
fi
|
|
|
|
local feature_dir="$CONFIG_DIR/features/$feature_name"
|
|
|
|
if [ -d "$feature_dir" ]; then
|
|
if [ "$FORCE" != "1" ]; then
|
|
log_error "Feature directory already exists: $feature_dir"
|
|
log_error "Use --force to overwrite"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
log_info "Would create feature template: $feature_name"
|
|
return 0
|
|
fi
|
|
|
|
# Create feature directory
|
|
mkdir -p "$feature_dir"
|
|
|
|
# Create template files for each environment
|
|
for env in "${ENVIRONMENTS[@]}"; do
|
|
local template_file="$feature_dir/$env.toml"
|
|
cat > "$template_file" << EOF
|
|
# $feature_name Feature Configuration - $(echo $env | sed 's/./\U&/') Environment
|
|
# Settings for the $feature_name feature
|
|
|
|
[features]
|
|
$feature_name = true
|
|
|
|
[$feature_name]
|
|
enabled = true
|
|
# Add your feature-specific settings here
|
|
|
|
# Example configuration options:
|
|
# option1 = "value1"
|
|
# option2 = 42
|
|
# option3 = true
|
|
EOF
|
|
log_info "Created template file: $template_file"
|
|
done
|
|
|
|
# Create README for the feature
|
|
cat > "$feature_dir/README.md" << EOF
|
|
# $feature_name Feature
|
|
|
|
Description of the $feature_name feature.
|
|
|
|
## Configuration Options
|
|
|
|
### Environment-Specific Settings
|
|
|
|
#### Development (\`dev.toml\`)
|
|
- Optimized for development and debugging
|
|
- Relaxed security settings
|
|
- Verbose logging enabled
|
|
|
|
#### Production (\`prod.toml\`)
|
|
- Optimized for production performance
|
|
- Strict security settings
|
|
- Minimal logging
|
|
|
|
#### Example (\`example.toml\`)
|
|
- Complete documentation of all options
|
|
- Best practice configurations
|
|
- Commented examples
|
|
|
|
## Usage
|
|
|
|
Enable this feature by setting:
|
|
|
|
\`\`\`toml
|
|
[features]
|
|
$feature_name = true
|
|
\`\`\`
|
|
|
|
## Dependencies
|
|
|
|
List any features that this feature depends on.
|
|
|
|
## Security Considerations
|
|
|
|
Document any security implications of this feature.
|
|
EOF
|
|
|
|
log_success "Feature template created: $feature_name"
|
|
}
|
|
|
|
# Clean generated configurations
|
|
cmd_clean() {
|
|
log_info "Cleaning generated configurations..."
|
|
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
log_info "Would clean generated configuration files"
|
|
return 0
|
|
fi
|
|
|
|
local cleaned_count=0
|
|
|
|
# Remove generated config files
|
|
for config_file in config.toml config.*.toml; do
|
|
if [ -f "$config_file" ]; then
|
|
rm "$config_file"
|
|
log_info "Removed: $config_file"
|
|
((cleaned_count++))
|
|
fi
|
|
done
|
|
|
|
# Remove temporary files
|
|
for temp_file in /tmp/config_*.toml /tmp/rustelo_config_*.toml; do
|
|
if [ -f "$temp_file" ]; then
|
|
rm "$temp_file"
|
|
log_info "Removed: $temp_file"
|
|
((cleaned_count++))
|
|
fi
|
|
done
|
|
|
|
log_success "Cleaned $cleaned_count files"
|
|
}
|
|
|
|
# Show configuration status
|
|
cmd_status() {
|
|
log_info "Configuration system status:"
|
|
|
|
# Check directories
|
|
log_info "Directories:"
|
|
for dir in base features scripts; do
|
|
if [ -d "$CONFIG_DIR/$dir" ]; then
|
|
log_info " $dir: ✓"
|
|
else
|
|
log_info " $dir: ✗"
|
|
fi
|
|
done
|
|
|
|
# Check base configurations
|
|
log_info "Base configurations:"
|
|
for env in "${ENVIRONMENTS[@]}"; do
|
|
if [ -f "$CONFIG_DIR/base/$env.toml" ]; then
|
|
log_info " $env: ✓"
|
|
else
|
|
log_info " $env: ✗"
|
|
fi
|
|
done
|
|
|
|
# Check features
|
|
log_info "Features:"
|
|
if [ -d "$CONFIG_DIR/features" ]; then
|
|
for feature_dir in "$CONFIG_DIR/features"/*; do
|
|
if [ -d "$feature_dir" ]; then
|
|
local feature_name=$(basename "$feature_dir")
|
|
local env_count=0
|
|
for env in "${ENVIRONMENTS[@]}"; do
|
|
if [ -f "$feature_dir/$env.toml" ]; then
|
|
((env_count++))
|
|
fi
|
|
done
|
|
log_info " $feature_name: $env_count/${#ENVIRONMENTS[@]} environments"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Check scripts
|
|
log_info "Scripts:"
|
|
for script in build-config.sh; do
|
|
if [ -f "$SCRIPT_DIR/$script" ]; then
|
|
log_info " $script: ✓"
|
|
else
|
|
log_error " $script: ✗"
|
|
fi
|
|
done
|
|
|
|
# Check tools
|
|
log_info "Tools:"
|
|
if command -v python3 &> /dev/null; then
|
|
log_info " python3: ✓"
|
|
if python3 -c "import toml" 2>/dev/null; then
|
|
log_info " toml (Python): ✓"
|
|
else
|
|
log_info " toml (Python): ✗"
|
|
fi
|
|
else
|
|
log_info " python3: ✗"
|
|
fi
|
|
|
|
if command -v toml &> /dev/null; then
|
|
log_info " toml (CLI): ✓"
|
|
else
|
|
log_info " toml (CLI): ✗"
|
|
fi
|
|
}
|
|
|
|
# Main function
|
|
main() {
|
|
parse_args "$@"
|
|
|
|
# Enable debug if requested
|
|
if [ "$DEBUG" = "1" ]; then
|
|
set -x
|
|
fi
|
|
|
|
# Handle quiet mode
|
|
if [ "$QUIET" = "1" ]; then
|
|
exec 1>/dev/null
|
|
fi
|
|
|
|
# Execute command
|
|
case "$COMMAND" in
|
|
build)
|
|
cmd_build "$ENV" "$OUTPUT"
|
|
;;
|
|
validate)
|
|
cmd_validate "$ENV"
|
|
;;
|
|
list-features)
|
|
cmd_list_features
|
|
;;
|
|
list-environments)
|
|
cmd_list_environments
|
|
;;
|
|
diff)
|
|
cmd_diff "$ENV" "$OUTPUT"
|
|
;;
|
|
backup)
|
|
cmd_backup "$ENV" "$OUTPUT"
|
|
;;
|
|
restore)
|
|
cmd_restore "$ENV" "$OUTPUT"
|
|
;;
|
|
template)
|
|
cmd_template "$ENV"
|
|
;;
|
|
clean)
|
|
cmd_clean
|
|
;;
|
|
status)
|
|
cmd_status
|
|
;;
|
|
help|"")
|
|
show_help
|
|
;;
|
|
*)
|
|
log_error "Unknown command: $COMMAND"
|
|
show_help
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|