Skip to content
Merged
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
2 changes: 2 additions & 0 deletions docs/parameters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ description: |+
type: bool
default: false
components: ["cache", "director", "origin", "registry"]
runtime_configurable: false
---
name: IssuerKey
description: |+
Expand Down Expand Up @@ -200,6 +201,7 @@ default: none
client_default: warn
server_default: info
components: ["*"]
runtime_configurable: true
---
name: Logging.LogLocation
description: |+
Expand Down
73 changes: 64 additions & 9 deletions generate/param_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type TemplateData struct {

var requiredKeys = [3]string{"description", "default", "type"}
var deprecatedMap = make(map[string][]string)
var runtimeConfigurableMap = make(map[string]bool)

func GenParamEnum() {
/*
Expand Down Expand Up @@ -153,7 +154,15 @@ func GenParamEnum() {
deprecatedMap[entry["name"].(string)] = replacedBySlice
}

// Handle runtime_configurable field
rawName := entry["name"].(string)
if runtimeConfigurable, ok := entry["runtime_configurable"].(bool); ok {
runtimeConfigurableMap[rawName] = runtimeConfigurable
} else {
// Default to false if not specified
runtimeConfigurableMap[rawName] = false
}

name := strings.ReplaceAll(rawName, ".", "_")
pType := entry["type"].(string)
switch pType {
Expand Down Expand Up @@ -192,15 +201,16 @@ func GenParamEnum() {

// Generate the code based on the template
err = packageTemplate.Execute(f, struct {
StringMap map[string]string
StringSliceMap map[string]string
IntMap map[string]string
BoolMap map[string]string
DurationMap map[string]string
ObjectMap map[string]string
DeprecatedMap map[string][]string
AllParamNames []string
}{StringMap: stringParamMap, StringSliceMap: stringSliceParamMap, IntMap: intParamMap, BoolMap: boolParamMap, DurationMap: durationParamMap, ObjectMap: objectParamMap, DeprecatedMap: deprecatedMap, AllParamNames: allParamNames})
StringMap map[string]string
StringSliceMap map[string]string
IntMap map[string]string
BoolMap map[string]string
DurationMap map[string]string
ObjectMap map[string]string
DeprecatedMap map[string][]string
RuntimeConfigurableMap map[string]bool
AllParamNames []string
}{StringMap: stringParamMap, StringSliceMap: stringSliceParamMap, IntMap: intParamMap, BoolMap: boolParamMap, DurationMap: durationParamMap, ObjectMap: objectParamMap, DeprecatedMap: deprecatedMap, RuntimeConfigurableMap: runtimeConfigurableMap, AllParamNames: allParamNames})

if err != nil {
panic(err)
Expand Down Expand Up @@ -476,6 +486,27 @@ func GetDeprecated() map[string][]string {
}
}

// runtimeConfigurableMap is a map of parameter names to their runtime configurability status.
// It is generated from docs/parameters.yaml and indicates whether a parameter can be reloaded
// at runtime without requiring a server restart.
var runtimeConfigurableMap = map[string]bool{
{{- range $key, $value := .RuntimeConfigurableMap}}
"{{$key}}": {{$value}},
{{- end}}
}

func GetRuntimeConfigurable() map[string]bool {
return runtimeConfigurableMap
}

// IsRuntimeConfigurable returns whether the given parameter name can be reloaded at runtime
func IsRuntimeConfigurable(paramName string) bool {
if val, ok := runtimeConfigurableMap[paramName]; ok {
return val
}
return false
}

func (sP StringParam) GetString() string {
config := getOrCreateConfig()
switch sP.name {
Expand All @@ -495,6 +526,10 @@ func (sP StringParam) IsSet() bool {
return viper.IsSet(sP.name)
}

func (sP StringParam) IsRuntimeConfigurable() bool {
return IsRuntimeConfigurable(sP.name)
}

func (slP StringSliceParam) GetStringSlice() []string {
config := getOrCreateConfig()
switch slP.name {
Expand All @@ -514,6 +549,10 @@ func (slP StringSliceParam) IsSet() bool {
return viper.IsSet(slP.name)
}

func (slP StringSliceParam) IsRuntimeConfigurable() bool {
return IsRuntimeConfigurable(slP.name)
}

func (iP IntParam) GetInt() int {
config := getOrCreateConfig()
switch iP.name {
Expand All @@ -533,6 +572,10 @@ func (iP IntParam) IsSet() bool {
return viper.IsSet(iP.name)
}

func (iP IntParam) IsRuntimeConfigurable() bool {
return IsRuntimeConfigurable(iP.name)
}

func (bP BoolParam) GetBool() bool {
config := getOrCreateConfig()
switch bP.name {
Expand All @@ -552,6 +595,10 @@ func (bP BoolParam) IsSet() bool {
return viper.IsSet(bP.name)
}

func (bP BoolParam) IsRuntimeConfigurable() bool {
return IsRuntimeConfigurable(bP.name)
}

func (dP DurationParam) GetDuration() time.Duration {
config := getOrCreateConfig()
switch dP.name {
Expand All @@ -571,6 +618,10 @@ func (dP DurationParam) IsSet() bool {
return viper.IsSet(dP.name)
}

func (dP DurationParam) IsRuntimeConfigurable() bool {
return IsRuntimeConfigurable(dP.name)
}

func (oP ObjectParam) Unmarshal(rawVal any) error {
return viper.UnmarshalKey(oP.name, rawVal)
}
Expand All @@ -583,6 +634,10 @@ func (oP ObjectParam) IsSet() bool {
return viper.IsSet(oP.name)
}

func (oP ObjectParam) IsRuntimeConfigurable() bool {
return IsRuntimeConfigurable(oP.name)
}

// allParameterNames is the list of all config keys generated from
// docs/parameters.yaml. It is primarily used to bind environment variables so
// that env-only overrides are included in viper.AllSettings().
Expand Down
36 changes: 36 additions & 0 deletions param/param_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,39 @@ func TestAccessorFunctionsWithNoConfig(t *testing.T) {
require.NotNil(t, config)
assert.Equal(t, 7000, config.Cache.Port)
}

func TestIsRuntimeConfigurable(t *testing.T) {
// Test the package-level function with a parameter that has runtime_configurable: true
assert.True(t, IsRuntimeConfigurable("Logging.Level"), "Logging.Level should be runtime configurable")

// Test with a parameter that has runtime_configurable: false
assert.False(t, IsRuntimeConfigurable("TLSSkipVerify"), "TLSSkipVerify should not be runtime configurable")

// Test with a parameter that doesn't specify runtime_configurable (should default to false)
assert.False(t, IsRuntimeConfigurable("Cache.Port"), "Cache.Port should default to not runtime configurable")

// Test with a non-existent parameter
assert.False(t, IsRuntimeConfigurable("NonExistent.Parameter"), "Non-existent parameter should return false")
}

func TestParamIsRuntimeConfigurable(t *testing.T) {
// Test the method on different param types
assert.True(t, Logging_Level.IsRuntimeConfigurable(), "Logging.Level should be runtime configurable")
assert.False(t, TLSSkipVerify.IsRuntimeConfigurable(), "TLSSkipVerify should not be runtime configurable")
assert.False(t, Cache_Port.IsRuntimeConfigurable(), "Cache.Port should not be runtime configurable")
}

func TestGetRuntimeConfigurable(t *testing.T) {
// Test that GetRuntimeConfigurable returns a valid map
runtimeConfigMap := GetRuntimeConfigurable()
require.NotNil(t, runtimeConfigMap, "GetRuntimeConfigurable should return a non-nil map")

// Verify specific entries
loggingLevel, exists := runtimeConfigMap["Logging.Level"]
assert.True(t, exists, "Logging.Level should exist in the map")
assert.True(t, loggingLevel, "Logging.Level should be true in the map")

tlsSkipVerify, exists := runtimeConfigMap["TLSSkipVerify"]
assert.True(t, exists, "TLSSkipVerify should exist in the map")
assert.False(t, tlsSkipVerify, "TLSSkipVerify should be false in the map")
}
Loading
Loading