Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,17 @@ var (

// Config represents the CLI configuration stored in ~/.volcano/config.json.
type Config struct {
// APIBaseURL overrides the compiled API URL for synthetic command configs.
// APIBaseURL overrides the configured API URL for synthetic command configs.
// It is intentionally not persisted to the user's cloud config file.
APIBaseURL string `json:"-"`
UserToken string `json:"user_token,omitempty"`
UserID string `json:"user_id,omitempty"`
AnonKey string `json:"-"`
ServiceKey string `json:"-"`
CurrentProject *ProjectConfig `json:"current_project,omitempty"`
APIBaseURL string `json:"-"`
Comment on lines +43 to +45
// ConfiguredAPIURL is the durable API endpoint selected by the installer.
// VOLCANO_API_URL remains the higher-precedence, per-process override.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing in this repo currently writes ConfiguredAPIURLcfg.Save() call sites (auth.go, function.go, project.go) never set it, so today this only round-trips a value that was placed into config.json by an external process (per the comment, "selected by the installer"). Worth confirming that installer path actually exists/is landing separately, since right now there's no way for a user to get this field populated (short of hand-editing the file) and exercise the new precedence.

ConfiguredAPIURL string `json:"api_url,omitempty"`
UserToken string `json:"user_token,omitempty"`
UserID string `json:"user_id,omitempty"`
AnonKey string `json:"-"`
ServiceKey string `json:"-"`
CurrentProject *ProjectConfig `json:"current_project,omitempty"`
// FunctionAliases stores per-user function invoke aliases by API URL and
// project ID scope. Scope keys are produced by FunctionAliasScope.
FunctionAliases map[string]map[string]string `json:"function_aliases,omitempty"`
Expand Down Expand Up @@ -182,14 +185,17 @@ func (c *Config) ProjectID() string {
}

// APIURL returns the API URL with VOLCANO_API_URL taking precedence unless env overrides are disabled.
// Precedence: env > runtime override (APIBaseURL) > compiled default.
// Precedence: env > runtime override (APIBaseURL) > persisted config > compiled default.
func (c *Config) APIURL() string {
if apiURL := strings.TrimSpace(os.Getenv(envAPIURL)); !c.IgnoreEnv && apiURL != "" {
return apiURL
}
if c.APIBaseURL != "" {
return c.APIBaseURL
}
Comment on lines 193 to 195
if apiURL := strings.TrimSpace(c.ConfiguredAPIURL); apiURL != "" {
return apiURL
}
return compiledDefaultAPIURL
}

Expand Down
33 changes: 26 additions & 7 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,34 +52,53 @@ func TestLoadSaveDeleteAndPermissions(t *testing.T) {
assert.Nil(t, empty.CurrentProject)
}

func TestSaveOmitsRuntimeOnlyAPIURL(t *testing.T) {
func TestSavePersistsConfiguredAPIURLButOmitsRuntimeOnlyFields(t *testing.T) {
t.Setenv("HOME", t.TempDir())

cfg := &Config{
APIBaseURL: "http://localhost:8000",
UserToken: "file-token",
AnonKey: "local-anon-key",
ServiceKey: "local-service-key",
APIBaseURL: "http://runtime.example.test",
ConfiguredAPIURL: "http://configured.example.test",
UserToken: "file-token",
AnonKey: "local-anon-key",
ServiceKey: "local-service-key",
}
require.NoError(t, cfg.Save())

configPath, err := Path()
require.NoError(t, err)
data, err := os.ReadFile(configPath)
require.NoError(t, err)
assert.NotContains(t, string(data), "api_url")
assert.NotContains(t, string(data), "http://localhost:8000")
assert.Contains(t, string(data), `"api_url": "http://configured.example.test"`)
assert.NotContains(t, string(data), "http://runtime.example.test")
assert.NotContains(t, string(data), "local-anon-key")
assert.NotContains(t, string(data), "local-service-key")

loaded, err := Load()
require.NoError(t, err)
assert.Empty(t, loaded.APIBaseURL)
assert.Equal(t, "http://configured.example.test", loaded.ConfiguredAPIURL)
assert.Empty(t, loaded.AnonKey)
assert.Empty(t, loaded.ServiceKey)
assert.Equal(t, "file-token", loaded.UserToken)
}

func TestAPIURLPrecedence(t *testing.T) {
cfg := &Config{
APIBaseURL: "http://runtime.example.test",
ConfiguredAPIURL: "http://configured.example.test",
}
assert.Equal(t, "http://runtime.example.test", cfg.APIURL())

t.Setenv("VOLCANO_API_URL", "http://environment.example.test")
assert.Equal(t, "http://environment.example.test", cfg.APIURL())

cfg.IgnoreEnv = true
assert.Equal(t, "http://runtime.example.test", cfg.APIURL())

cfg.APIBaseURL = ""
assert.Equal(t, "http://configured.example.test", cfg.APIURL())
}

func TestFunctionInvokeTokenPrefersServiceKey(t *testing.T) {
cfg := &Config{
UserToken: "user-token",
Expand Down
Loading