#!/bin/bash set -e set -o pipefail # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Helper functions print_header() { echo -e "\n${BLUE}=== $1 ===${NC}\n" } print_info() { echo -e "${BLUE}INFO:${NC} $1" } print_warning() { echo -e "${YELLOW}WARNING:${NC} $1" } print_success() { echo -e "${GREEN}SUCCESS:${NC} $1" } print_error() { echo -e "${RED}ERROR:${NC} $1" } # Function to prompt for input with default value prompt_with_default() { local prompt="$1" local default="$2" local current_value="$3" local result if [ -n "${current_value}" ] && [ "${current_value}" != "null" ]; then printf "%s [current: %s]: " "${prompt}" "${current_value}" >&2 read -r result if [ -z "${result}" ]; then result="${current_value}" fi elif [ -n "${default}" ]; then printf "%s [default: %s]: " "${prompt}" "${default}" >&2 read -r result if [ -z "${result}" ]; then result="${default}" fi else printf "%s: " "${prompt}" >&2 read -r result while [ -z "${result}" ]; do printf "This value is required. Please enter a value: " >&2 read -r result done fi echo "${result}" } # Function to get current config value safely get_current_config() { local key="$1" if [ -f "${WC_HOME}/config.yaml" ]; then set +e result=$(wild-config "${key}" 2>/dev/null) set -e echo "${result}" else echo "" fi } # Function to get current secret value safely get_current_secret() { local key="$1" if [ -f "${WC_HOME}/secrets.yaml" ]; then set +e result=$(wild-secret "${key}" 2>/dev/null) set -e echo "${result}" else echo "" fi } # Check if we're in a wild-cloud directory if [ ! -d ".wildcloud" ]; then print_error "You must run this script from a wild-cloud directory" exit 1 fi # Set and export WC_HOME if [ -z "${WC_HOME:-}" ]; then WC_HOME="$(pwd)" fi export WC_HOME # Detect current network subnet and gateway for IP suggestions CURRENT_IP=$(ip route get 8.8.8.8 | awk '{print $7; exit}' 2>/dev/null || echo "192.168.1.100") GATEWAY_IP=$(ip route | grep default | awk '{print $3; exit}' 2>/dev/null || echo "192.168.1.1") SUBNET_PREFIX=$(echo "${CURRENT_IP}" | cut -d. -f1-3) print_info "Detected network: ${SUBNET_PREFIX}.x (gateway: ${GATEWAY_IP})" print_header "Wild-Cloud Configuration Setup" echo "This script will help you configure your wild-cloud deployment." echo "You can press Enter to keep current values or defaults." echo "" # Basic Information print_header "Basic Information" current_email=$(get_current_config "operator.email") email=$(prompt_with_default "Your email address (for Let's Encrypt certificates)" "" "${current_email}") wild-config-set "operator.email" "${email}" # Domain Configuration print_header "Domain Configuration" current_base_domain=$(get_current_config "cloud.baseDomain") base_domain=$(prompt_with_default "Your base domain name (e.g., example.com)" "" "${current_base_domain}") wild-config-set "cloud.baseDomain" "${base_domain}" current_domain=$(get_current_config "cloud.domain") domain=$(prompt_with_default "Your public cloud domain" "cloud.${base_domain}" "${current_domain}") wild-config-set "cloud.domain" "${domain}" current_internal_domain=$(get_current_config "cloud.internalDomain") internal_domain=$(prompt_with_default "Your internal cloud domain" "internal.${domain}" "${current_internal_domain}") wild-config-set "cloud.internalDomain" "${internal_domain}" # Derive cluster name from domain (remove dots and make lowercase) cluster_name=$(echo "${domain}" | tr '.' '-' | tr '[:upper:]' '[:lower:]') wild-config-set "cluster.name" "${cluster_name}" # Cloudflare Configuration print_header "Cloudflare Configuration" echo "For automatic SSL certificates and DNS management, we use Cloudflare." echo "" current_cf_domain=$(get_current_config "cluster.certManager.cloudflare.domain") if [ -z "${current_cf_domain}" ]; then cf_domain="${domain}" else cf_domain="${current_cf_domain}" fi echo "Is your domain '${base_domain}' registered and managed through Cloudflare? (y/n)" read -r use_cloudflare if [[ "${use_cloudflare}" =~ ^[Yy]$ ]]; then wild-config-set "cluster.certManager.cloudflare.domain" "${cf_domain}" current_cf_token=$(get_current_secret "cloudflare.token") if [ -z "${current_cf_token}" ]; then echo "" print_info "You'll need a Cloudflare API token with the following permissions:" echo " - Zone:Zone:Read" echo " - Zone:DNS:Edit" echo " - Include:All zones" echo "" echo "Create one at: https://dash.cloudflare.com/profile/api-tokens" echo "" fi cf_token=$(prompt_with_default "Cloudflare API token" "" "${current_cf_token}") wild-secret-set "cloudflare.token" "${cf_token}" else print_warning "You'll need to configure DNS and SSL certificates manually." print_info "Consider transferring your domain to Cloudflare for easier management." fi # Network Configuration print_header "Network Configuration" current_router_ip=$(get_current_config "cloud.router.ip") router_ip=$(prompt_with_default "Router/Gateway IP" "${GATEWAY_IP}" "${current_router_ip}") wild-config-set "cloud.router.ip" "${router_ip}" current_dns_ip=$(get_current_config "cloud.dns.ip") dns_ip=$(prompt_with_default "DNS server IP (dnsmasq machine)" "${SUBNET_PREFIX}.50" "${current_dns_ip}") wild-config-set "cloud.dns.ip" "${dns_ip}" current_dhcp_range=$(get_current_config "cloud.dhcpRange") dhcp_range=$(prompt_with_default "DHCP range for dnsmasq" "${SUBNET_PREFIX}.100,${SUBNET_PREFIX}.200" "${current_dhcp_range}") wild-config-set "cloud.dhcpRange" "${dhcp_range}" current_interface=$(get_current_config "cloud.dnsmasq.interface") interface=$(prompt_with_default "Network interface for dnsmasq" "eth0" "${current_interface}") wild-config-set "cloud.dnsmasq.interface" "${interface}" current_external_resolver=$(get_current_config "cloud.dns.externalResolver") external_resolver=$(prompt_with_default "External DNS resolver" "1.1.1.1" "${current_external_resolver}") wild-config-set "cloud.dns.externalResolver" "${external_resolver}" # Cluster Configuration print_header "Kubernetes Cluster Configuration" current_talos_version=$(get_current_config "cluster.nodes.talos.version") talos_version=$(prompt_with_default "Talos version" "v1.6.1" "${current_talos_version}") wild-config-set "cluster.nodes.talos.version" "${talos_version}" current_ip_pool=$(get_current_config "cluster.ipAddressPool") ip_pool=$(prompt_with_default "MetalLB IP address pool" "${SUBNET_PREFIX}.80-${SUBNET_PREFIX}.89" "${current_ip_pool}") wild-config-set "cluster.ipAddressPool" "${ip_pool}" # Automatically set load balancer IP to first address in the pool lb_ip=$(echo "${ip_pool}" | cut -d'-' -f1) wild-config-set "cluster.loadBalancerIp" "${lb_ip}" # Control plane nodes echo "" current_vip=$(get_current_config "cluster.nodes.control.vip") vip=$(prompt_with_default "Control plane virtual IP" "${SUBNET_PREFIX}.90" "${current_vip}") wild-config-set "cluster.nodes.control.vip" "${vip}" for i in 1 2 3; do current_node_ip=$(get_current_config "cluster.nodes.control.node${i}.ip") node_ip=$(prompt_with_default "Control plane node ${i} IP address" "${SUBNET_PREFIX}.$(( 90 + i ))" "${current_node_ip}") wild-config-set "cluster.nodes.control.node${i}.ip" "${node_ip}" done # Talos Configuration echo "" current_schematic_id=$(get_current_config "cluster.nodes.talos.schematicId") echo "" print_info "Get your Talos schematic ID from: https://factory.talos.dev/" print_info "This customizes Talos with the drivers needed for your hardware." schematic_id=$(prompt_with_default "Talos schematic ID" "" "${current_schematic_id}") wild-config-set "cluster.nodes.talos.schematicId" "${schematic_id}" # External DNS current_owner_id=$(get_current_config "cluster.externalDns.ownerId") owner_id=$(prompt_with_default "External DNS owner ID" "external-dns-${cluster_name}" "${current_owner_id}") wild-config-set "cluster.externalDns.ownerId" "${owner_id}" # Storage Configuration print_header "Storage Configuration" current_nfs_host=$(get_current_config "cloud.nfs.host") nfs_host=$(prompt_with_default "NFS server host" "${dns_ip}" "${current_nfs_host}") wild-config-set "cloud.nfs.host" "${nfs_host}" current_media_path=$(get_current_config "cloud.nfs.mediaPath") media_path=$(prompt_with_default "NFS media path" "/mnt/storage/media" "${current_media_path}") wild-config-set "cloud.nfs.mediaPath" "${media_path}" current_storage_capacity=$(get_current_config "cloud.nfs.storageCapacity") storage_capacity=$(prompt_with_default "Storage capacity for NFS PV" "1Ti" "${current_storage_capacity}") wild-config-set "cloud.nfs.storageCapacity" "${storage_capacity}" # Docker Registry print_header "Docker Registry Configuration" current_registry_host=$(get_current_config "cloud.dockerRegistryHost") registry_host=$(prompt_with_default "Docker registry hostname" "registry.${internal_domain}" "${current_registry_host}") wild-config-set "cloud.dockerRegistryHost" "${registry_host}" # Summary print_header "Configuration Complete" print_success "Your wild-cloud configuration has been saved!" echo "" print_info "Configuration files:" echo " - ${WC_HOME}/config.yaml" echo " - ${WC_HOME}/secrets.yaml" echo "" print_info "Next steps:" echo " 1. Review your configuration files" echo " 2. Run 'wild-setup' to generate setup files" echo " 3. Follow the setup instructions in docs/SETUP_FULL.md" echo ""