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,6 +37,23 @@ func runDeployFlow(r preflight.Result) {
|
||||||
var s state.State
|
var s state.State
|
||||||
s.DeploymentType = "native"
|
s.DeploymentType = "native"
|
||||||
|
|
||||||
|
// 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
|
// Step 1: Cloud region
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("─── Cloud Region ───")
|
fmt.Println("─── Cloud Region ───")
|
||||||
|
|
@ -72,11 +89,22 @@ func runDeployFlow(r preflight.Result) {
|
||||||
fmt.Println("Token cannot be empty.")
|
fmt.Println("Token cannot be empty.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Step 3: Node configuration
|
// Step 3: Node configuration
|
||||||
|
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.Println()
|
||||||
fmt.Print("Node name: ")
|
fmt.Print("Node name: ")
|
||||||
nodeName, _ := reader.ReadString('\n')
|
nodeName, _ = reader.ReadString('\n')
|
||||||
nodeName = strings.TrimSpace(nodeName)
|
nodeName = strings.TrimSpace(nodeName)
|
||||||
if nodeName == "" {
|
if nodeName == "" {
|
||||||
fmt.Println("Node name required.")
|
fmt.Println("Node name required.")
|
||||||
|
|
@ -84,29 +112,28 @@ func runDeployFlow(r preflight.Result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Print("Listen port [8081]: ")
|
fmt.Print("Listen port [8081]: ")
|
||||||
port, _ := reader.ReadString('\n')
|
port, _ = reader.ReadString('\n')
|
||||||
port = strings.TrimSpace(port)
|
port = strings.TrimSpace(port)
|
||||||
if port == "" {
|
if port == "" {
|
||||||
port = "8081"
|
port = "8081"
|
||||||
}
|
}
|
||||||
address := "0.0.0.0:" + port
|
|
||||||
|
|
||||||
fmt.Print("Upstream IP [127.0.0.1]: ")
|
fmt.Print("Upstream IP [127.0.0.1]: ")
|
||||||
upstreamIP, _ := reader.ReadString('\n')
|
upstreamIP, _ = reader.ReadString('\n')
|
||||||
upstreamIP = strings.TrimSpace(upstreamIP)
|
upstreamIP = strings.TrimSpace(upstreamIP)
|
||||||
if upstreamIP == "" {
|
if upstreamIP == "" {
|
||||||
upstreamIP = "127.0.0.1"
|
upstreamIP = "127.0.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Print("Upstream port [80]: ")
|
fmt.Print("Upstream port [80]: ")
|
||||||
upstreamPort, _ := reader.ReadString('\n')
|
upstreamPort, _ = reader.ReadString('\n')
|
||||||
upstreamPort = strings.TrimSpace(upstreamPort)
|
upstreamPort = strings.TrimSpace(upstreamPort)
|
||||||
if upstreamPort == "" {
|
if upstreamPort == "" {
|
||||||
upstreamPort = "80"
|
upstreamPort = "80"
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Print("Labels [group=" + nodeName + "]: ")
|
fmt.Print("Labels [group=" + nodeName + "]: ")
|
||||||
labels, _ := reader.ReadString('\n')
|
labels, _ = reader.ReadString('\n')
|
||||||
labels = strings.TrimSpace(labels)
|
labels = strings.TrimSpace(labels)
|
||||||
if labels == "" {
|
if labels == "" {
|
||||||
labels = "group=" + nodeName
|
labels = "group=" + nodeName
|
||||||
|
|
@ -114,7 +141,7 @@ func runDeployFlow(r preflight.Result) {
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Printf(" Node: %s\n", nodeName)
|
fmt.Printf(" Node: %s\n", nodeName)
|
||||||
fmt.Printf(" Listen: %s\n", address)
|
fmt.Printf(" Listen: %s\n", "0.0.0.0:"+port)
|
||||||
fmt.Printf(" Upstream: %s:%s\n", upstreamIP, upstreamPort)
|
fmt.Printf(" Upstream: %s:%s\n", upstreamIP, upstreamPort)
|
||||||
fmt.Printf(" Region: %s (%s)\n", s.CloudRegion, s.APIHost)
|
fmt.Printf(" Region: %s (%s)\n", s.CloudRegion, s.APIHost)
|
||||||
fmt.Print("\nProceed with deployment? [Y/n]: ")
|
fmt.Print("\nProceed with deployment? [Y/n]: ")
|
||||||
|
|
@ -124,6 +151,13 @@ func runDeployFlow(r preflight.Result) {
|
||||||
fmt.Println("Cancelled.")
|
fmt.Println("Cancelled.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
baseDir := "/opt/fw"
|
baseDir := "/opt/fw"
|
||||||
instanceDir := baseDir + "/" + nodeName + "/wallarm"
|
instanceDir := baseDir + "/" + nodeName + "/wallarm"
|
||||||
|
|
@ -178,6 +212,11 @@ WALLARM_REGION=%s
|
||||||
fmt.Fprintf(os.Stderr, "Warning: could not save state: %v\n", err)
|
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()
|
||||||
fmt.Println("✅ Deployment complete!")
|
fmt.Println("✅ Deployment complete!")
|
||||||
fmt.Println()
|
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