feat: .env file support — skip prompts on repeat deploys
- /opt/fw/.env stores token, cloud, node, port, upstream - If .env exists with WALLARM_TOKEN, all prompts are skipped - Saved automatically after successful deployment - Perfect for testing: edit .env once, deploy repeatedly
This commit is contained in:
parent
cbe6d51ac6
commit
e9dff30d84
1 changed files with 130 additions and 76 deletions
|
|
@ -37,94 +37,128 @@ func runDeployFlow(r preflight.Result) {
|
|||
var s state.State
|
||||
s.DeploymentType = "native"
|
||||
|
||||
// Step 1: Cloud region
|
||||
fmt.Println()
|
||||
fmt.Println("─── Cloud Region ───")
|
||||
if r.USReachable && r.EUReachable {
|
||||
fmt.Println(" [1] US (us1.api.wallarm.com)")
|
||||
fmt.Println(" [2] EU (api.wallarm.com)")
|
||||
fmt.Print("Choose region [1/2]: ")
|
||||
choice, _ := reader.ReadString('\n')
|
||||
choice = strings.TrimSpace(choice)
|
||||
if choice == "2" {
|
||||
s.CloudRegion = "EU"
|
||||
s.APIHost = "api.wallarm.com"
|
||||
// Check for .env file — skip prompts if present
|
||||
envPath := "/opt/fw/.env"
|
||||
envData, _ := os.ReadFile(envPath)
|
||||
envMap := parseEnv(string(envData))
|
||||
skipPrompts := envMap["WALLARM_TOKEN"] != ""
|
||||
|
||||
if skipPrompts {
|
||||
fmt.Println()
|
||||
fmt.Println("Using saved configuration from /opt/fw/.env")
|
||||
s.CloudRegion = envMap["WALLARM_CLOUD"]
|
||||
if s.CloudRegion == "US" {
|
||||
s.APIHost = "us1.api.wallarm.com"
|
||||
} else {
|
||||
s.APIHost = "api.wallarm.com"
|
||||
}
|
||||
s.APIToken = envMap["WALLARM_TOKEN"]
|
||||
} else {
|
||||
// Step 1: Cloud region
|
||||
fmt.Println()
|
||||
fmt.Println("─── Cloud Region ───")
|
||||
if r.USReachable && r.EUReachable {
|
||||
fmt.Println(" [1] US (us1.api.wallarm.com)")
|
||||
fmt.Println(" [2] EU (api.wallarm.com)")
|
||||
fmt.Print("Choose region [1/2]: ")
|
||||
choice, _ := reader.ReadString('\n')
|
||||
choice = strings.TrimSpace(choice)
|
||||
if choice == "2" {
|
||||
s.CloudRegion = "EU"
|
||||
s.APIHost = "api.wallarm.com"
|
||||
} else {
|
||||
s.CloudRegion = "US"
|
||||
s.APIHost = "us1.api.wallarm.com"
|
||||
}
|
||||
} else if r.USReachable {
|
||||
fmt.Println(" US (us1.api.wallarm.com) — only reachable region")
|
||||
s.CloudRegion = "US"
|
||||
s.APIHost = "us1.api.wallarm.com"
|
||||
} else {
|
||||
fmt.Println(" EU (api.wallarm.com) — only reachable region")
|
||||
s.CloudRegion = "EU"
|
||||
s.APIHost = "api.wallarm.com"
|
||||
}
|
||||
} else if r.USReachable {
|
||||
fmt.Println(" US (us1.api.wallarm.com) — only reachable region")
|
||||
s.CloudRegion = "US"
|
||||
s.APIHost = "us1.api.wallarm.com"
|
||||
} else {
|
||||
fmt.Println(" EU (api.wallarm.com) — only reachable region")
|
||||
s.CloudRegion = "EU"
|
||||
s.APIHost = "api.wallarm.com"
|
||||
}
|
||||
|
||||
// Step 2: API Token
|
||||
fmt.Println()
|
||||
fmt.Print("Wallarm API Token (Deploy role): ")
|
||||
token, _ := reader.ReadString('\n')
|
||||
s.APIToken = strings.TrimSpace(token)
|
||||
if s.APIToken == "" {
|
||||
fmt.Println("Token cannot be empty.")
|
||||
return
|
||||
// Step 2: API Token
|
||||
fmt.Println()
|
||||
fmt.Print("Wallarm API Token (Deploy role): ")
|
||||
token, _ := reader.ReadString('\n')
|
||||
s.APIToken = strings.TrimSpace(token)
|
||||
if s.APIToken == "" {
|
||||
fmt.Println("Token cannot be empty.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: Node configuration
|
||||
fmt.Println()
|
||||
fmt.Print("Node name: ")
|
||||
nodeName, _ := reader.ReadString('\n')
|
||||
nodeName = strings.TrimSpace(nodeName)
|
||||
if nodeName == "" {
|
||||
fmt.Println("Node name required.")
|
||||
return
|
||||
var nodeName, port, upstreamIP, upstreamPort, labels string
|
||||
if skipPrompts {
|
||||
nodeName = envMap["WALLARM_NODE"]
|
||||
port = envMap["WALLARM_PORT"]
|
||||
upstreamIP = envMap["WALLARM_UPSTREAM_IP"]
|
||||
upstreamPort = envMap["WALLARM_UPSTREAM_PORT"]
|
||||
labels = envMap["WALLARM_LABELS"]
|
||||
fmt.Printf("\n Node: %s | Port: %s | Upstream: %s:%s | Cloud: %s\n",
|
||||
nodeName, port, upstreamIP, upstreamPort, s.CloudRegion)
|
||||
} else {
|
||||
fmt.Println()
|
||||
fmt.Print("Node name: ")
|
||||
nodeName, _ = reader.ReadString('\n')
|
||||
nodeName = strings.TrimSpace(nodeName)
|
||||
if nodeName == "" {
|
||||
fmt.Println("Node name required.")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print("Listen port [8081]: ")
|
||||
port, _ = reader.ReadString('\n')
|
||||
port = strings.TrimSpace(port)
|
||||
if port == "" {
|
||||
port = "8081"
|
||||
}
|
||||
|
||||
fmt.Print("Upstream IP [127.0.0.1]: ")
|
||||
upstreamIP, _ = reader.ReadString('\n')
|
||||
upstreamIP = strings.TrimSpace(upstreamIP)
|
||||
if upstreamIP == "" {
|
||||
upstreamIP = "127.0.0.1"
|
||||
}
|
||||
|
||||
fmt.Print("Upstream port [80]: ")
|
||||
upstreamPort, _ = reader.ReadString('\n')
|
||||
upstreamPort = strings.TrimSpace(upstreamPort)
|
||||
if upstreamPort == "" {
|
||||
upstreamPort = "80"
|
||||
}
|
||||
|
||||
fmt.Print("Labels [group=" + nodeName + "]: ")
|
||||
labels, _ = reader.ReadString('\n')
|
||||
labels = strings.TrimSpace(labels)
|
||||
if labels == "" {
|
||||
labels = "group=" + nodeName
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Printf(" Node: %s\n", nodeName)
|
||||
fmt.Printf(" Listen: %s\n", "0.0.0.0:"+port)
|
||||
fmt.Printf(" Upstream: %s:%s\n", upstreamIP, upstreamPort)
|
||||
fmt.Printf(" Region: %s (%s)\n", s.CloudRegion, s.APIHost)
|
||||
fmt.Print("\nProceed with deployment? [Y/n]: ")
|
||||
confirm, _ := reader.ReadString('\n')
|
||||
confirm = strings.TrimSpace(strings.ToLower(confirm))
|
||||
if confirm != "" && confirm != "y" && confirm != "yes" {
|
||||
fmt.Println("Cancelled.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Print("Listen port [8081]: ")
|
||||
port, _ := reader.ReadString('\n')
|
||||
port = strings.TrimSpace(port)
|
||||
if port == "" {
|
||||
port = "8081"
|
||||
}
|
||||
if port == "" { port = "8081" }
|
||||
if upstreamIP == "" { upstreamIP = "127.0.0.1" }
|
||||
if upstreamPort == "" { upstreamPort = "80" }
|
||||
if labels == "" { labels = "group=" + nodeName }
|
||||
address := "0.0.0.0:" + port
|
||||
|
||||
fmt.Print("Upstream IP [127.0.0.1]: ")
|
||||
upstreamIP, _ := reader.ReadString('\n')
|
||||
upstreamIP = strings.TrimSpace(upstreamIP)
|
||||
if upstreamIP == "" {
|
||||
upstreamIP = "127.0.0.1"
|
||||
}
|
||||
|
||||
fmt.Print("Upstream port [80]: ")
|
||||
upstreamPort, _ := reader.ReadString('\n')
|
||||
upstreamPort = strings.TrimSpace(upstreamPort)
|
||||
if upstreamPort == "" {
|
||||
upstreamPort = "80"
|
||||
}
|
||||
|
||||
fmt.Print("Labels [group=" + nodeName + "]: ")
|
||||
labels, _ := reader.ReadString('\n')
|
||||
labels = strings.TrimSpace(labels)
|
||||
if labels == "" {
|
||||
labels = "group=" + nodeName
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Printf(" Node: %s\n", nodeName)
|
||||
fmt.Printf(" Listen: %s\n", address)
|
||||
fmt.Printf(" Upstream: %s:%s\n", upstreamIP, upstreamPort)
|
||||
fmt.Printf(" Region: %s (%s)\n", s.CloudRegion, s.APIHost)
|
||||
fmt.Print("\nProceed with deployment? [Y/n]: ")
|
||||
confirm, _ := reader.ReadString('\n')
|
||||
confirm = strings.TrimSpace(strings.ToLower(confirm))
|
||||
if confirm != "" && confirm != "y" && confirm != "yes" {
|
||||
fmt.Println("Cancelled.")
|
||||
return
|
||||
}
|
||||
|
||||
baseDir := "/opt/fw"
|
||||
instanceDir := baseDir + "/" + nodeName + "/wallarm"
|
||||
|
||||
|
|
@ -178,6 +212,11 @@ WALLARM_REGION=%s
|
|||
fmt.Fprintf(os.Stderr, "Warning: could not save state: %v\n", err)
|
||||
}
|
||||
|
||||
// Save .env for future runs
|
||||
os.WriteFile(envPath, []byte(fmt.Sprintf(
|
||||
"WALLARM_TOKEN=%s\nWALLARM_CLOUD=%s\nWALLARM_NODE=%s\nWALLARM_PORT=%s\nWALLARM_UPSTREAM_IP=%s\nWALLARM_UPSTREAM_PORT=%s\nWALLARM_LABELS=%s\n",
|
||||
s.APIToken, s.CloudRegion, nodeName, port, upstreamIP, upstreamPort, labels)), 0644)
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("✅ Deployment complete!")
|
||||
fmt.Println()
|
||||
|
|
@ -334,3 +373,18 @@ deployment. On subsequent runs, it shows your existing deployments.
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func parseEnv(data string) map[string]string {
|
||||
m := map[string]string{}
|
||||
for _, line := range strings.Split(data, "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
parts := strings.SplitN(line, "=", 2)
|
||||
if len(parts) == 2 {
|
||||
m[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue