From 5208117c56e3e2ece7898cb958349d96b1dedaff Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 30 Mar 2026 17:18:22 -0700 Subject: [PATCH] Add name to provisioning --- main.go | 10 ++++++++++ websocket/config.go | 27 +++++++++++++++++++++++++++ websocket/types.go | 1 + 3 files changed, 38 insertions(+) diff --git a/main.go b/main.go index c573ee2..6ad1c2f 100644 --- a/main.go +++ b/main.go @@ -169,6 +169,9 @@ var ( // Provisioning key – exchanged once for a permanent newt ID + secret provisioningKey string + // Optional name for the site created during provisioning + newtName string + // Path to config file (overrides CONFIG_FILE env var and default location) configFile string ) @@ -284,6 +287,7 @@ func runNewtMain(ctx context.Context) { noCloudEnv := os.Getenv("NO_CLOUD") noCloud = noCloudEnv == "true" provisioningKey = os.Getenv("NEWT_PROVISIONING_KEY") + newtName = os.Getenv("NEWT_NAME") configFile = os.Getenv("CONFIG_FILE") if endpoint == "" { @@ -336,6 +340,9 @@ func runNewtMain(ctx context.Context) { if provisioningKey == "" { flag.StringVar(&provisioningKey, "provisioning-key", "", "One-time provisioning key used to obtain a newt ID and secret from the server") } + if newtName == "" { + flag.StringVar(&newtName, "name", "", "Name for the site created during provisioning (supports {{env.VAR}} interpolation)") + } if configFile == "" { flag.StringVar(&configFile, "config-file", "", "Path to config file (overrides CONFIG_FILE env var and default location)") } @@ -623,6 +630,9 @@ func runNewtMain(ctx context.Context) { if provisioningKey != "" && client.GetConfig().ProvisioningKey == "" { client.GetConfig().ProvisioningKey = provisioningKey } + if newtName != "" && client.GetConfig().Name == "" { + client.GetConfig().Name = newtName + } endpoint = client.GetConfig().Endpoint // Update endpoint from config id = client.GetConfig().ID // Update ID from config diff --git a/websocket/config.go b/websocket/config.go index 4fb6513..d727a41 100644 --- a/websocket/config.go +++ b/websocket/config.go @@ -12,6 +12,7 @@ import ( "net/url" "os" "path/filepath" + "regexp" "runtime" "strings" "time" @@ -99,6 +100,10 @@ func (c *Client) loadConfig() error { if c.config.ProvisioningKey == "" { c.config.ProvisioningKey = config.ProvisioningKey } + // Always load the name from the file if not already set + if c.config.Name == "" { + c.config.Name = config.Name + } // Check if CLI args provided values that override file values if (!fileHadID && originalConfig.ID != "") || @@ -135,6 +140,21 @@ func (c *Client) saveConfig() error { return err } +// interpolateString replaces {{env.VAR}} tokens in s with the corresponding +// environment variable values. Tokens that do not match a supported scheme are +// left unchanged, mirroring the blueprint interpolation logic. +func interpolateString(s string) string { + re := regexp.MustCompile(`\{\{([^}]+)\}\}`) + return re.ReplaceAllStringFunc(s, func(match string) string { + inner := strings.TrimSpace(match[2 : len(match)-2]) + if strings.HasPrefix(inner, "env.") { + varName := strings.TrimPrefix(inner, "env.") + return os.Getenv(varName) + } + return match + }) +} + // provisionIfNeeded checks whether a provisioning key is present and, if so, // exchanges it for a newt ID and secret by calling the registration endpoint. // On success the config is updated in-place and flagged for saving so that @@ -158,9 +178,15 @@ func (c *Client) provisionIfNeeded() error { } baseEndpoint := strings.TrimRight(baseURL.String(), "/") + // Interpolate any {{env.VAR}} tokens in the name before sending. + name := interpolateString(c.config.Name) + reqBody := map[string]interface{}{ "provisioningKey": c.config.ProvisioningKey, } + if name != "" { + reqBody["name"] = name + } jsonData, err := json.Marshal(reqBody) if err != nil { return fmt.Errorf("failed to marshal provisioning request: %w", err) @@ -236,6 +262,7 @@ func (c *Client) provisionIfNeeded() error { c.config.ID = provResp.Data.NewtID c.config.Secret = provResp.Data.Secret c.config.ProvisioningKey = "" + c.config.Name = "" c.configNeedsSave = true // Save immediately so that if the subsequent connection attempt fails the diff --git a/websocket/types.go b/websocket/types.go index 2b32dae..195e06f 100644 --- a/websocket/types.go +++ b/websocket/types.go @@ -6,6 +6,7 @@ type Config struct { Endpoint string `json:"endpoint"` TlsClientCert string `json:"tlsClientCert"` ProvisioningKey string `json:"provisioningKey,omitempty"` + Name string `json:"name,omitempty"` } type TokenResponse struct {