diff --git a/mods/scripts/.DS_Store b/mods/scripts/.DS_Store index d400eb87b2..4b73e5514d 100644 Binary files a/mods/scripts/.DS_Store and b/mods/scripts/.DS_Store differ diff --git a/mods/scripts/apps/deploy.sh b/mods/scripts/apps/deploy.sh index 0a431b88fd..8843286abb 100644 --- a/mods/scripts/apps/deploy.sh +++ b/mods/scripts/apps/deploy.sh @@ -11,6 +11,11 @@ NC="\033[0m" # No color app_name=$1 script_type=$2 # personal or official +# Configuration file paths +dns_provider_config="/pg/config/dns_provider.cfg" +app_config_official="/pg/config/${app_name}.cfg" +app_config_personal="/pg/personal_configs/${app_name}.cfg" + # Name of the Docker network to check or create network_name="plexguide" @@ -35,14 +40,56 @@ check_and_create_network() { # Function to source configuration and functions for the app appsourcing() { if [[ "$script_type" == "personal" ]]; then - source "/pg/personal_configs/${app_name}.cfg" + source "$app_config_personal" source "/pg/p_apps/${app_name}/${app_name}.functions" 2>/dev/null else - source "/pg/config/${app_name}.cfg" + source "$app_config_official" source "/pg/apps/${app_name}/${app_name}.functions" 2>/dev/null fi } +# Function to update traefik_domain in the app's config +update_traefik_domain() { + # Ensure dns_provider.cfg exists + if [[ ! -f "$dns_provider_config" ]]; then + mkdir -p "$(dirname "$dns_provider_config")" + touch "$dns_provider_config" + fi + + # Read domain_name from dns_provider.cfg + if grep -q "^domain_name=" "$dns_provider_config"; then + domain_name=$(grep "^domain_name=" "$dns_provider_config" | cut -d'=' -f2) + else + domain_name="" + fi + + # Set traefik_domain value based on domain_name + if [[ -z "$domain_name" ]]; then + # No domain set, use empty value + traefik_domain="traefik_domain=\"\"" + else + # Domain exists, use it in the traefik_domain + traefik_domain="traefik_domain=\"$domain_name\"" + fi + + # Update the app's configuration file + if [[ "$script_type" == "personal" ]]; then + # Overwrite traefik_domain in the personal config file + if grep -q "^traefik_domain=" "$app_config_personal"; then + sed -i "s/^traefik_domain=.*/$traefik_domain/" "$app_config_personal" + else + echo "$traefik_domain" >> "$app_config_personal" + fi + else + # Overwrite traefik_domain in the official config file + if grep -q "^traefik_domain=" "$app_config_official"; then + sed -i "s/^traefik_domain=.*/$traefik_domain/" "$app_config_official" + else + echo "$traefik_domain" >> "$app_config_official" + fi + fi +} + # Function: Deploys / Redploys App redeploy_app() { # Check if lspci is installed; detect NVIDIA graphics cards @@ -56,6 +103,9 @@ redeploy_app() { check_and_create_network echo "Deploying $app_name" + + # Update traefik_domain based on the domain_name in dns_provider.cfg + update_traefik_domain # Determine which support script to source if [[ "$script_type" == "personal" ]]; then diff --git a/mods/scripts/apps/starter_menu.sh b/mods/scripts/apps/starter_menu.sh index a0e864eb1a..363afcf89d 100644 --- a/mods/scripts/apps/starter_menu.sh +++ b/mods/scripts/apps/starter_menu.sh @@ -147,7 +147,10 @@ main_menu() { # Conditionally hide options Q and R if the repo is set to "None" if [[ "$repo" != "None" ]]; then - printf " Q) Personal: Manage [%d]\n" "$P_COUNT" + # Only display option Q) if there are personal apps deployed (P_COUNT > 0) + if [[ "$P_COUNT" -gt 0 ]]; then + printf " Q) Personal: Manage [%d]\n" "$P_COUNT" + fi printf " R) Personal: Deploy Apps\n" fi @@ -191,8 +194,8 @@ main_menu() { bash /pg/scripts/apps/personal_select.sh ;; Q|q) - if [[ "$repo" == "None" ]]; then - echo -e "${RED}Option Q is not available. Please use P to set a User and Repo first.${NC}" + if [[ "$repo" == "None" || "$P_COUNT" -eq 0 ]]; then + echo -e "${RED}Option Q is not available. Please deploy a personal app first.${NC}" read -p "Press Enter to continue..." else bash /pg/scripts/apps/running.sh "personal" @@ -220,6 +223,5 @@ main_menu() { done } - # Call the main menu function main_menu diff --git a/mods/scripts/cloud_server.sh b/mods/scripts/cloud_server.sh index 486855ce36..3a23493a95 100644 --- a/mods/scripts/cloud_server.sh +++ b/mods/scripts/cloud_server.sh @@ -25,7 +25,7 @@ cloud_server_menu() { echo "" # Space between options and input prompt # Prompt for user input - read -p "Enter your choice: " choice + read -p "Select an Option > " choice # Process user input case ${choice,,} in diff --git a/mods/scripts/cf_tunnel.sh b/mods/scripts/cloudflare/tunnel.sh similarity index 59% rename from mods/scripts/cf_tunnel.sh rename to mods/scripts/cloudflare/tunnel.sh index 75367da248..e51460a4f1 100644 --- a/mods/scripts/cf_tunnel.sh +++ b/mods/scripts/cloudflare/tunnel.sh @@ -3,11 +3,14 @@ # Configuration file path CONFIG_FILE="/pg/config/cf_tunnel.cfg" -# ANSI color codes for green, red, and blue -GREEN="\033[0;32m" +# ANSI color codes for green, hot pink, and others +GREEN="\033[1;32m" # Bold Green +HOT_PINK="\033[1;35m" # Bold Hot Pink RED="\033[0;31m" BLUE="\033[0;34m" NC="\033[0m" # No color +CYAN="\033[0;36m" +BOLD="\033[1m" # Clear the screen when the script starts clear @@ -39,14 +42,11 @@ container_exists() { # Function to display the main menu show_menu() { clear - echo "PG: CloudFlare Tunnel" - - # Display container deployment status - echo -n "Container Deployed: " + echo -n -e "${CYAN}${BOLD}PG: CloudFlare Tunnel${NC} " if container_running; then - echo -e "${GREEN}Yes${NC}" + echo -e "${GREEN}${BOLD}[Deployed]${NC}" else - echo -e "${RED}No${NC}" + echo -e "${RED}${BOLD}[Not Deployed]${NC}" fi echo @@ -64,7 +64,7 @@ show_menu() { # Function to prompt the user with a choice prompt_choice() { - read -p "Select an option: " choice + read -p "Select an Option > " choice case ${choice,,} in # Convert input to lowercase for v/V, c/C, d/D, s/S, z/Z handling v) clear @@ -72,35 +72,11 @@ prompt_choice() { ;; c) clear - local change_code=$(printf "%04d" $((RANDOM % 10000))) # Generate a 4-digit code - while true; do - read -p "$(echo -e "To change the Cloudflare token, type [${RED}${change_code}${NC}] to proceed or [${GREEN}no${NC}] to cancel: ")" input_code - if [[ "$input_code" == "$change_code" ]]; then - change_token - break - elif [[ "${input_code,,}" == "no" ]]; then - echo "Operation cancelled." - break - else - echo -e "${RED}Invalid response.${NC} Please type [${RED}${change_code}${NC}] or [${GREEN}no${NC}]." - fi - done + change_token ;; d) clear - local deploy_code=$(printf "%04d" $((RANDOM % 10000))) # Generate a 4-digit code - while true; do - read -p "$(echo -e "Deploy CF Tunnel? Type [${RED}${deploy_code}${NC}] to proceed or [${GREEN}no${NC}] to cancel: ")" input_code - if [[ "$input_code" == "$deploy_code" ]]; then - deploy_container - break - elif [[ "${input_code,,}" == "no" ]]; then - echo "Operation cancelled." - break - else - echo -e "${RED}Invalid response.${NC} Please type [${RED}${deploy_code}${NC}] or [${GREEN}no${NC}]." - fi - done + deploy_container ;; s) clear @@ -139,13 +115,52 @@ view_token() { # Function to change the Cloudflare token change_token() { - clear - read -p "Enter new Cloudflare token: " CLOUDFLARE_TOKEN - save_token_to_config - echo "Cloudflare token has been updated and saved to $CONFIG_FILE." - sleep 2 - show_menu - prompt_choice + local proceed_pin cancel_pin + proceed_pin=$(printf "%04d" $((RANDOM % 10000))) # Generate a 4-digit proceed pin + cancel_pin=$(printf "%04d" $((RANDOM % 10000))) # Generate a 4-digit cancel pin + + # Ask the user for the new token + echo -e "Enter new Cloudflare token:" + read -p "> " new_token # Get the new token from the user + echo # Echo a blank line for spacing + + # Confirmation prompt with hot pink pin for proceed and green for cancel + while true; do + echo -e "To proceed, enter this PIN [${HOT_PINK}${proceed_pin}${NC}]" + echo -e "To cancel, enter this PIN [${GREEN}${cancel_pin}${NC}]" + read -p "Enter PIN > " input_code + + if [[ "$input_code" == "$proceed_pin" ]]; then + # Save the token and confirm + CLOUDFLARE_TOKEN="$new_token" + save_token_to_config + echo -e "${GREEN}Cloudflare token has been updated and saved to $CONFIG_FILE.${NC}" + + # Check if the container is running, notify the user and stop/remove it + if container_running; then + echo -e "${RED}Note:${NC} The CloudFlare Tunnel container is currently running." + echo "You must redeploy the container for the changes to take effect." + + echo "Stopping and removing the running container..." + docker stop cf_tunnel + docker rm cf_tunnel + echo "Container stopped and removed." + fi + + sleep 2 + show_menu + prompt_choice + break + elif [[ "$input_code" == "$cancel_pin" ]]; then + echo -e "${GREEN}Operation cancelled.${NC}" + sleep 2 + show_menu + prompt_choice + break + else + echo -e "${RED}Invalid response.${NC} Please enter [${HOT_PINK}${proceed_pin}${NC}] to proceed or [${GREEN}${cancel_pin}${NC}] to cancel." + fi + done } # Function to deploy or redeploy the container diff --git a/mods/scripts/domain_menu.sh b/mods/scripts/domain_menu.sh index cb969c3b76..0774fbbe4b 100644 --- a/mods/scripts/domain_menu.sh +++ b/mods/scripts/domain_menu.sh @@ -33,7 +33,7 @@ get_port_status() { display_menu() { clear get_port_status # Fetch the port status - echo -e "${CYAN}PG Domain Configuration Interface${NC}" + echo -e "${CYAN}${BOLD}PG Domain Configuration Interface${NC}" echo echo -e "[${YELLOW}${BOLD}A${NC}] CloudFlare Tunnel" echo -e "[${CYAN}${BOLD}B${NC}] CloudFlare Traefik" @@ -45,14 +45,14 @@ display_menu() { # Main loop while true; do display_menu - read -p "Make a Choice > " choice + read -p "Select an Option > " choice case $choice in [Aa]) - bash /pg/scripts/cf_tunnel.sh + bash /pg/scripts/cloudflare/tunnel.sh ;; [Bb]) - bash /pg/scripts/traefik/traefik_menu.sh + bash /pg/scripts/traefik/menu.sh ;; [Pp]) bash /pg/scripts/default_ports.sh diff --git a/mods/scripts/menu.sh b/mods/scripts/menu.sh index 83a555b7d2..c6d949f969 100644 --- a/mods/scripts/menu.sh +++ b/mods/scripts/menu.sh @@ -165,7 +165,7 @@ main_menu() { echo "" # Space between options and input prompt # Prompt for user input - read -p "Choose and Option > " choice + read -p "Select an Option > " choice # Process user input case ${choice,,} in diff --git a/mods/scripts/options.sh b/mods/scripts/options.sh index 29ac6925dd..f1df99102d 100644 --- a/mods/scripts/options.sh +++ b/mods/scripts/options.sh @@ -1,9 +1,13 @@ #!/bin/bash # ANSI color codes +CYAN="\033[0;36m" RED="\033[0;31m" +ORANGE="\033[0;33m" +WHITE="\033[1;37m" +BOLD="\033[1m" +NC="\033[0m" # No color BLUE="\033[0;34m" -NC="\033[0m" # No color # Clear the screen at the start clear @@ -30,7 +34,7 @@ exit_script() { main_menu() { while true; do clear - echo -e "${BLUE}PlexGuide Options Interface${NC}" + echo -e "${CYAN}${BOLD}PG Options Interface${NC}" echo "" # Blank line for separation # Display the main menu options echo "G) Graphics Cards" diff --git a/mods/scripts/traefik/traefik_deploy.sh b/mods/scripts/traefik/deploy.sh similarity index 91% rename from mods/scripts/traefik/traefik_deploy.sh rename to mods/scripts/traefik/deploy.sh index 3b720da8ca..b0387ec159 100644 --- a/mods/scripts/traefik/traefik_deploy.sh +++ b/mods/scripts/traefik/deploy.sh @@ -62,36 +62,23 @@ services: - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - "--entrypoints.web.http.redirections.entrypoint.scheme=https" - "--certificatesresolvers.mytlschallenge.acme.dnschallenge=true" - - "--certificatesresolvers.mytlschallenge.acme.email=${letsencrypt_email:-example@example.com}" + - "--certificatesresolvers.mytlschallenge.acme.email=${letsencrypt_email}" - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.mytlschallenge.acme.dnschallenge.provider=cloudflare" - "--certificatesresolvers.mytlschallenge.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53" - "--certificatesresolvers.mytlschallenge.acme.dnschallenge.delaybeforecheck=60" -EOF - - # Add Cloudflare-specific environment variable - cat <> $DOCKER_COMPOSE_FILE environment: - CLOUDFLARE_DNS_API_TOKEN=$api_key -EOF - - # Finalize Docker Compose file - cat <> $DOCKER_COMPOSE_FILE volumes: - /var/run/docker.sock:/var/run/docker.sock - /pg/traefik/letsencrypt:/letsencrypt labels: - "traefik.enable=true" - - "traefik.http.routers.traefik.rule=Host(\`traefik.${domain_name}\`)" - "traefik.http.routers.traefik.entrypoints=websecure" - "traefik.http.routers.traefik.tls.certresolver=mytlschallenge" - "traefik.http.routers.traefik.service=api@internal" - "traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_AUTH}" restart: unless-stopped - -networks: - host: - external: true EOF echo -e "${GREEN}Docker Compose file for Traefik has been created at $DOCKER_COMPOSE_FILE.${NC}" diff --git a/mods/scripts/traefik/functions.sh b/mods/scripts/traefik/functions.sh new file mode 100644 index 0000000000..ecdfd7ffef --- /dev/null +++ b/mods/scripts/traefik/functions.sh @@ -0,0 +1,226 @@ +#!/bin/bash + +# ANSI color codes for styling output +CYAN="\033[0;36m" +GREEN="\033[0;32m" +RED="\033[0;31m" +YELLOW="\033[0;33m" +BLUE="\033[0;34m" +MAGENTA="\033[0;35m" +BOLD="\033[1m" +NC="\033[0m" # No color + +# Configuration file path +CONFIG_FILE="/pg/config/dns_provider.cfg" + +# Ensure config file exists +ensure_config_file() { + if [[ ! -f "$CONFIG_FILE" ]]; then + mkdir -p "$(dirname "$CONFIG_FILE")" + touch "$CONFIG_FILE" + fi +} + +# Function to check if Traefik is deployed +check_traefik_status() { + if docker ps --filter "name=traefik" --format '{{.Names}}' | grep -q 'traefik'; then + traefik_status="${GREEN}${BOLD}[Deployed]${NC}" + else + traefik_status="${RED}${BOLD}[Not Deployed]${NC}" + fi +} + +# Function to check if the Let's Encrypt email is set +check_email_status() { + if grep -q "^letsencrypt_email=" "$CONFIG_FILE"; then + letsencrypt_email=$(grep "^letsencrypt_email=" "$CONFIG_FILE" | cut -d'=' -f2) + if [[ -z "$letsencrypt_email" || "$letsencrypt_email" == "notset" ]]; then + email_status="${RED}${BOLD}Not Set${NC}" + else + email_status="${GREEN}${BOLD}Set${NC}" + fi + else + email_status="${RED}${BOLD}Not Set${NC}" + fi +} + +# Function to check if the domain is set +check_domain_status() { + if grep -q "^domain_name=" "$CONFIG_FILE"; then + domain_name=$(grep "^domain_name=" "$CONFIG_FILE" | cut -d'=' -f2) + # Check if the domain_name is not empty and matches the domain format + if [[ -n "$domain_name" && "$domain_name" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then + domain_status="${GREEN}${BOLD}Set${NC}" # Display Set in green + else + domain_status="${RED}${BOLD}Not Set${NC}" # Display Not Set in red if the value is invalid or empty + fi + else + domain_status="${RED}${BOLD}Not Set${NC}" # Display Not Set in red if the key doesn't exist + fi +} + +# Function to check if the Cloudflare credentials are properly set +check_provider_status() { + if grep -q "^api_key=" "$CONFIG_FILE" && grep -q "^email=" "$CONFIG_FILE"; then + api_key=$(grep "^api_key=" "$CONFIG_FILE" | cut -d'=' -f2) + if [[ -z "$api_key" || "$api_key" == "notset" ]]; then + provider_status="${RED}${BOLD}Not Set${NC}" + else + provider_status="${GREEN}${BOLD}Set${NC}" + fi + else + provider_status="${RED}${BOLD}Not Set${NC}" + fi +} + +# Function to configure DNS provider (Cloudflare only) +configure_provider() { + echo "" + echo -e "${CYAN}Configuring Cloudflare DNS Provider${NC}" + provider="cloudflare" + + # Prompt for Cloudflare email and API key + read -p "Enter your Cloudflare email: " cf_email + read -p "Enter your Cloudflare API key: " api_key + + # Trim any leading/trailing whitespace from the API key + api_key=$(echo "$api_key" | xargs) + + # Test the credentials before saving + echo -e "${YELLOW}Testing Cloudflare credentials...${NC}" + if test_cloudflare_credentials; then + # Overwrite existing email and api_key entries in the config file + if grep -q "^email=" "$CONFIG_FILE"; then + sed -i "s/^email=.*/email=$cf_email/" "$CONFIG_FILE" + else + echo "email=$cf_email" >> "$CONFIG_FILE" + fi + + if grep -q "^api_key=" "$CONFIG_FILE"; then + sed -i "s/^api_key=.*/api_key=$api_key/" "$CONFIG_FILE" + else + echo "api_key=$api_key" >> "$CONFIG_FILE" + fi + + echo "" + echo -e "${GREEN}Cloudflare credentials have been configured successfully.${NC}" + else + # Do not modify the config file if credentials are invalid + echo "" + echo -e "${RED}CloudFlare Information is Incorrect and/or the API Key may not have the proper permissions.${NC}" + echo "" + fi + + read -p "Press [ENTER] to continue..." +} + +# Function to validate domain format +validate_domain() { + local domain="$1" + if [[ "$domain" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then + return 0 # Domain is valid + else + return 1 # Domain is invalid + fi +} + +# Function to set domain name +set_domain() { + while true; do + read -p "Enter the domain name to use (e.g., example.com): " domain_name + + # Validate domain format + if validate_domain "$domain_name"; then + # Overwrite the existing domain_name entry in the config + if grep -q "^domain_name=" "$CONFIG_FILE"; then + sed -i "s/^domain_name=.*/domain_name=$domain_name/" "$CONFIG_FILE" + else + echo "domain_name=$domain_name" >> "$CONFIG_FILE" + fi + echo -e "${GREEN}Domain has been configured successfully.${NC}" + read -p "Press Enter to continue..." + break + else + echo -e "${RED}Invalid domain name. Please enter a valid domain (e.g., example.com).${NC}" + fi + done +} + + +# Function to set email for Let's Encrypt +set_email() { + while true; do + read -p "Enter your email for Let's Encrypt notifications: " letsencrypt_email + + # Validate email format + if validate_email "$letsencrypt_email"; then + # Overwrite the existing letsencrypt_email entry in the config + if grep -q "^letsencrypt_email=" "$CONFIG_FILE"; then + sed -i "s/^letsencrypt_email=.*/letsencrypt_email=$letsencrypt_email/" "$CONFIG_FILE" + else + echo "letsencrypt_email=$letsencrypt_email" >> "$CONFIG_FILE" + fi + echo -e "${GREEN}Email has been configured successfully.${NC}" + read -p "Press Enter to continue..." + break + else + echo -e "${RED}Invalid email format. Please enter a valid email (e.g., user@example.com).${NC}" + fi + done +} + +# Function to validate email format +validate_email() { + local email="$1" + if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then + return 0 # Email is valid + else + return 1 # Email is invalid + fi +} + +# Function to test Cloudflare credentials +test_cloudflare_credentials() { + response=$(curl -s -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \ + -H "Authorization: Bearer $api_key" \ + -H "Content-Type: application/json") + + if echo "$response" | grep -q "valid and active"; then + return 0 # Valid credentials + else + return 1 # Invalid credentials + fi +} + +# Function to handle Traefik stop and removal warning with PINs +warn_traefik_removal() { + echo "" + echo -e "${RED}Warning: Changing the Cloudflare credentials will stop and remove Traefik.${NC}" + echo "" + + # Generate two random 4-digit PINs + proceed_pin=$(shuf -i 1000-9999 -n 1) + cancel_pin=$(shuf -i 1000-9999 -n 1) + + # Display the PINs to the user + echo -e "If you want to proceed and remove Traefik, enter: ${RED}${proceed_pin}${NC}" + echo -e "If you do NOT want to proceed, enter: ${GREEN}${cancel_pin}${NC}" + echo "" + + # Read user input for PIN + read -p "Enter your choice (PIN): " user_pin + + # Check user's choice + if [[ "$user_pin" == "$proceed_pin" ]]; then + echo -e "${RED}Stopping and removing Traefik...${NC}" + docker stop traefik >/dev/null 2>&1 + docker rm traefik >/dev/null 2>&1 + return 0 # Proceed with changing credentials + elif [[ "$user_pin" == "$cancel_pin" ]]; then + echo -e "${GREEN}Operation canceled. Traefik will not be stopped or removed.${NC}" + return 1 # Do not proceed + else + echo -e "${RED}Invalid PIN entered. Operation aborted.${NC}" + return 1 # Invalid entry, cancel operation + fi +} diff --git a/mods/scripts/traefik/menu.sh b/mods/scripts/traefik/menu.sh new file mode 100644 index 0000000000..85a9ada29d --- /dev/null +++ b/mods/scripts/traefik/menu.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# Source the functions from the separate script +source /pg/scripts/traefik/functions.sh + +# Ensure the config file exists, create if missing +ensure_config_file + +# Function to display the main menu +setup_dns_provider() { + while true; do + clear + check_traefik_status + check_email_status + check_domain_status # This will update domain_status + check_provider_status # Update Cloudflare status + + echo -e "${CYAN}${BOLD}PG: CloudFlare Traefik Interface ${traefik_status}${NC}" + echo "" + echo -e "[${GREEN}${BOLD}A${NC}] Domain Name (${domain_status})" # Domain status (Set or Not Set) + echo -e "[${CYAN}${BOLD}C${NC}] CF Information (${provider_status})" + echo -e "[${MAGENTA}${BOLD}E${NC}] Notification E-Mail Address (${email_status})" + + # Show the Deploy Traefik option only if all conditions are met + if [[ "$domain_status" == "${GREEN}${BOLD}Set${NC}" && "$email_status" == "${GREEN}${BOLD}Set${NC}" && "$provider_status" == "${GREEN}${BOLD}Set${NC}" ]]; then + echo -e "[${BLUE}${BOLD}D${NC}] Deploy Traefik" + fi + + echo -e "[${RED}${BOLD}Z${NC}] Exit" + echo "" + + read -p "Select an Option > " choice + case $choice in + [Aa]) + set_domain # This updates domain_name in the config + ;; + [Cc]) + if docker ps --filter "name=traefik" --format '{{.Names}}' | grep -q 'traefik'; then + warn_traefik_removal + if [[ $? -eq 1 ]]; then + continue # Skip changing credentials if the user canceled + fi + fi + configure_provider + ;; + [Ee]) + set_email # This updates letsencrypt_email in the config + ;; + [Dd]) + if [[ "$domain_status" == "${GREEN}${BOLD}Set${NC}" && "$email_status" == "${GREEN}${BOLD}Set${NC}" && "$provider_status" == "${GREEN}${BOLD}Set${NC}" ]]; then + bash /pg/scripts/traefik/deploy.sh + echo "" + read -p "Press Enter to continue..." + fi + ;; + [Zz]) + exit 0 + ;; + *) + echo -e "${RED}Invalid option. Please try again.${NC}" + read -p "Press Enter to continue..." + ;; + esac + done +} + +# Run the menu +setup_dns_provider diff --git a/mods/scripts/traefik/traefik_menu.sh b/mods/scripts/traefik/traefik_menu.sh deleted file mode 100644 index 5d980d8bb3..0000000000 --- a/mods/scripts/traefik/traefik_menu.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/bin/bash - -# ANSI color codes for styling output -CYAN="\033[0;36m" -GREEN="\033[0;32m" -RED="\033[0;31m" -YELLOW="\033[0;33m" -BLUE="\033[0;34m" -MAGENTA="\033[0;35m" -NC="\033[0m" # No color - -# Configuration file path for storing DNS provider and domain details -CONFIG_FILE="/pg/config/dns_provider.cfg" - -# Function to check if Traefik is deployed -check_traefik_status() { - if docker ps --filter "name=traefik" --format '{{.Names}}' | grep -q 'traefik'; then - traefik_status="${GREEN}[Deployed]${NC}" - else - traefik_status="${RED}[Not Deployed]${NC}" - fi -} - - -# Function to test Cloudflare credentials -test_cloudflare_credentials() { - response=$(curl -s -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \ - -H "Authorization: Bearer $api_key" \ - -H "Content-Type: application/json") - - if echo "$response" | grep -q "valid and active"; then - return 0 # Valid credentials - else - return 1 # Invalid credentials - fi -} - -# Function to handle Traefik stop and removal warning with PINs -warn_traefik_removal() { - echo "" - echo -e "${RED}Warning: Changing the Cloudflare credentials will stop and remove Traefik.${NC}" - echo "" - - # Generate two random 4-digit PINs - proceed_pin=$(shuf -i 1000-9999 -n 1) - cancel_pin=$(shuf -i 1000-9999 -n 1) - - # Display the PINs to the user - echo -e "If you want to proceed and remove Traefik, enter: ${RED}${proceed_pin}${NC}" - echo -e "If you do NOT want to proceed, enter: ${GREEN}${cancel_pin}${NC}" - echo "" - - # Read user input for PIN - read -p "Enter your choice (PIN): " user_pin - - # Check user's choice - if [[ "$user_pin" == "$proceed_pin" ]]; then - echo -e "${RED}Stopping and removing Traefik...${NC}" - docker stop traefik >/dev/null 2>&1 - docker rm traefik >/dev/null 2>&1 - return 0 # Proceed with changing credentials - elif [[ "$user_pin" == "$cancel_pin" ]]; then - echo -e "${GREEN}Operation canceled. Traefik will not be stopped or removed.${NC}" - return 1 # Do not proceed - else - echo -e "${RED}Invalid PIN entered. Operation aborted.${NC}" - return 1 # Invalid entry, cancel operation - fi -} - -# Function to setup DNS provider -setup_dns_provider() { - while true; do - clear - check_traefik_status - - echo -e "${CYAN}PG: CloudFlare Traefik Interface ${traefik_status}${NC}" - echo "" - echo -e "[${CYAN}${BOLD}C${NC}] CF Information" - echo -e "[${MAGENTA}${BOLD}E${NC}] E-Mail for Let's Encrypt" - echo -e "[${BLUE}${BOLD}D${NC}] Deploy Traefik" - echo -e "[${RED}${BOLD}Z${NC}] Exit" - echo "" - - read -p "Enter your choice: " choice - case $choice in - [Cc]) - if docker ps --filter "name=traefik" --format '{{.Names}}' | grep -q 'traefik'; then - warn_traefik_removal - if [[ $? -eq 1 ]]; then - continue # Skip changing credentials if the user canceled - fi - fi - configure_provider - ;; - [Ee]) - set_email - ;; - [Dd]) - bash /pg/scripts/traefik/traefik_deploy.sh - echo "" - read -p "Press Enter to continue..." - ;; - [Zz]) - exit 0 - ;; - *) - echo -e "${RED}Invalid option. Please try again.${NC}" - read -p "Press Enter to continue..." - ;; - esac - done -} - -# Function to configure DNS provider (Cloudflare only) -configure_provider() { - echo "" - echo -e "${CYAN}Configuring Cloudflare DNS Provider${NC}" - provider="cloudflare" - - # Prompt for Cloudflare email and API key - read -p "Enter your Cloudflare email: " cf_email - read -p "Enter your Cloudflare API key: " api_key - - # Trim any leading/trailing whitespace from the API key - api_key=$(echo "$api_key" | xargs) - - # Test the credentials before saving - echo -e "${YELLOW}Testing Cloudflare credentials...${NC}" - if test_cloudflare_credentials; then - read -p "Enter the domain name to use (e.g., example.com): " domain_name - echo "provider=cloudflare" > "$CONFIG_FILE" - echo "email=$cf_email" >> "$CONFIG_FILE" - echo "api_key=$api_key" >> "$CONFIG_FILE" - echo "domain_name=$domain_name" >> "$CONFIG_FILE" - echo "" - echo -e "${GREEN}Cloudflare DNS provider and domain have been configured successfully.${NC}" - else - # Blank out all information in the config file if credentials are invalid - echo "" > "$CONFIG_FILE" - echo "" - echo -e "${RED}CloudFlare Information is Incorrect and/or the API Key may not have the proper permissions.${NC}" - echo "" - fi - - read -p "Press [ENTER] to continue..." -} - -# Function to set email for Let's Encrypt -set_email() { - read -p "Enter your email for Let's Encrypt notifications: " letsencrypt_email - echo "letsencrypt_email=$letsencrypt_email" >> "$CONFIG_FILE" - echo -e "${GREEN}Email has been configured successfully.${NC}" - read -p "Press Enter to continue..." -} - -# Execute the setup function -setup_dns_provider diff --git a/mods/scripts/zurg/menu.sh b/mods/scripts/zurg/menu.sh index d343dd1f03..a98782283a 100644 --- a/mods/scripts/zurg/menu.sh +++ b/mods/scripts/zurg/menu.sh @@ -55,17 +55,17 @@ main_menu() { check_docker_status echo -e "${CYAN}${BOLD}PG Zurg Interface${NC}" - echo -e "${BLUE}-------------------------------${NC}" - echo -e "[C] Clone repository to /pg/zurg ${repo_status}" + echo "" + echo -e "C) Clone repository to /pg/zurg ${repo_status}" if check_repo_status; then - echo -e "[T] Real Debrid API Token ${token_status}" + echo -e "T) Real Debrid API Token ${token_status}" fi if check_token_status; then - echo -e "[R] Run docker compose up -d ${docker_status}" + echo -e "R) Run docker compose up -d ${docker_status}" fi - echo -e "[D] Destroy & Remove All Data" - echo -e "[Z] Exit" - echo -e "${BLUE}-------------------------------${NC}" + echo -e "D) Destroy & Remove All Data" + echo -e "Z) Exit" + echo "" read -p "Select an Option > " choice case $choice in [Cc])