Skip to content

Commit 8abcde7

Browse files
authored
VAULT-12264: Fix log rotation params which require an integer (hashicorp#18666)
* integer values for some log flags * Adjusted `log_flags` to expect `int` for max files and max bytes * Updated `server` and `agent` Renamed updateConfig (and updateLogConfig) * Added int log params to test * Adjust config/params so we can identify when they're not present * Removed pointer confusion
1 parent 49da254 commit 8abcde7

File tree

9 files changed

+157
-126
lines changed

9 files changed

+157
-126
lines changed

command/agent.go

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ func (c *AgentCommand) Run(args []string) int {
211211
c.UI.Info("No auto_auth block found in config, the automatic authentication feature will not be started")
212212
}
213213

214-
c.updateConfig(f, config) // This only needs to happen on start-up to aggregate config from flags and env vars
214+
c.applyConfigOverrides(f, config) // This only needs to happen on start-up to aggregate config from flags and env vars
215215
c.config = config
216216

217217
l, err := c.newLogger()
@@ -961,16 +961,16 @@ func (c *AgentCommand) Run(args []string) int {
961961
return exitCode
962962
}
963963

964-
// updateConfig ensures that the config object accurately reflects the desired
964+
// applyConfigOverrides ensures that the config object accurately reflects the desired
965965
// settings as configured by the user. It applies the relevant config setting based
966966
// on the precedence (env var overrides file config, cli overrides env var).
967967
// It mutates the config object supplied.
968-
func (c *AgentCommand) updateConfig(f *FlagSets, config *agentConfig.Config) {
968+
func (c *AgentCommand) applyConfigOverrides(f *FlagSets, config *agentConfig.Config) {
969969
if config.Vault == nil {
970970
config.Vault = &agentConfig.Vault{}
971971
}
972972

973-
f.updateLogConfig(config.SharedConfig)
973+
f.applyLogConfigOverrides(config.SharedConfig)
974974

975975
f.Visit(func(fl *flag.Flag) {
976976
if fl.Name == flagNameAgentExitAfterAuth {
@@ -1228,16 +1228,6 @@ func (c *AgentCommand) newLogger() (log.InterceptLogger, error) {
12281228
errors = multierror.Append(errors, err)
12291229
}
12301230

1231-
logRotateBytes, err := parseutil.ParseInt(c.config.LogRotateBytes)
1232-
if err != nil {
1233-
errors = multierror.Append(errors, err)
1234-
}
1235-
1236-
logRotateMaxFiles, err := parseutil.ParseInt(c.config.LogRotateMaxFiles)
1237-
if err != nil {
1238-
errors = multierror.Append(errors, err)
1239-
}
1240-
12411231
if errors != nil {
12421232
return nil, errors
12431233
}
@@ -1248,8 +1238,8 @@ func (c *AgentCommand) newLogger() (log.InterceptLogger, error) {
12481238
LogFormat: logFormat,
12491239
LogFilePath: c.config.LogFile,
12501240
LogRotateDuration: logRotateDuration,
1251-
LogRotateBytes: int(logRotateBytes),
1252-
LogRotateMaxFiles: int(logRotateMaxFiles),
1241+
LogRotateBytes: c.config.LogRotateBytes,
1242+
LogRotateMaxFiles: c.config.LogRotateMaxFiles,
12531243
}
12541244

12551245
l, err := logging.Setup(logCfg, c.logWriter)

command/agent_test.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ const (
3838
BasicHclConfig = `
3939
log_file = "TMPDIR/juan.log"
4040
log_level="warn"
41+
log_rotate_max_files=2
42+
log_rotate_bytes=1048576
4143
vault {
4244
address = "http://127.0.0.1:8200"
4345
retry {
@@ -54,6 +56,8 @@ listener "tcp" {
5456
BasicHclConfig2 = `
5557
log_file = "TMPDIR/juan.log"
5658
log_level="debug"
59+
log_rotate_max_files=-1
60+
log_rotate_bytes=1048576
5761
vault {
5862
address = "http://127.0.0.1:8200"
5963
retry {
@@ -2110,7 +2114,7 @@ func TestAgent_LogFile_CliOverridesConfig(t *testing.T) {
21102114
}
21112115

21122116
// Update the config based on the inputs.
2113-
cmd.updateConfig(f, cfg)
2117+
cmd.applyConfigOverrides(f, cfg)
21142118

21152119
assert.NotEqual(t, "TMPDIR/juan.log", cfg.LogFile)
21162120
assert.NotEqual(t, "/squiggle/logs.txt", cfg.LogFile)
@@ -2127,6 +2131,8 @@ func TestAgent_LogFile_Config(t *testing.T) {
21272131

21282132
// Sanity check that the config value is the current value
21292133
assert.Equal(t, "TMPDIR/juan.log", cfg.LogFile, "sanity check on log config failed")
2134+
assert.Equal(t, 2, cfg.LogRotateMaxFiles)
2135+
assert.Equal(t, 1048576, cfg.LogRotateBytes)
21302136

21312137
// Parse the cli flags (but we pass in an empty slice)
21322138
cmd := &AgentCommand{BaseCommand: &BaseCommand{}}
@@ -2136,9 +2142,12 @@ func TestAgent_LogFile_Config(t *testing.T) {
21362142
t.Fatal(err)
21372143
}
21382144

2139-
cmd.updateConfig(f, cfg)
2145+
// Should change nothing...
2146+
cmd.applyConfigOverrides(f, cfg)
21402147

21412148
assert.Equal(t, "TMPDIR/juan.log", cfg.LogFile, "actual config check")
2149+
assert.Equal(t, 2, cfg.LogRotateMaxFiles)
2150+
assert.Equal(t, 1048576, cfg.LogRotateBytes)
21422151
}
21432152

21442153
func TestAgent_Config_NewLogger_Default(t *testing.T) {

command/base_flags.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,14 @@ func (i *intValue) Set(s string) error {
249249
return err
250250
}
251251
if v >= math.MinInt && v <= math.MaxInt {
252-
*i.target = int(v)
252+
*i.target = v
253253
return nil
254254
}
255255
return fmt.Errorf("Incorrect conversion of a 64-bit integer to a lower bit size. Value %d is not within bounds for int32", v)
256256
}
257257

258-
func (i *intValue) Get() interface{} { return int(*i.target) }
259-
func (i *intValue) String() string { return strconv.Itoa(int(*i.target)) }
258+
func (i *intValue) Get() interface{} { return *i.target }
259+
func (i *intValue) String() string { return strconv.Itoa(*i.target) }
260260
func (i *intValue) Example() string { return "int" }
261261
func (i *intValue) Hidden() bool { return i.hidden }
262262

command/log_flags.go

Lines changed: 65 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package command
33
import (
44
"flag"
55
"os"
6-
"strings"
6+
"strconv"
77

88
"github.com/hashicorp/vault/internalshared/configutil"
99
"github.com/posener/complete"
@@ -15,20 +15,18 @@ type logFlags struct {
1515
flagLogLevel string
1616
flagLogFormat string
1717
flagLogFile string
18-
flagLogRotateBytes string
18+
flagLogRotateBytes int
1919
flagLogRotateDuration string
20-
flagLogRotateMaxFiles string
20+
flagLogRotateMaxFiles int
2121
}
2222

23-
type provider = func(key string) (string, bool)
24-
2523
// valuesProvider has the intention of providing a way to supply a func with a
2624
// way to retrieve values for flags and environment variables without having to
27-
// directly call a specific implementation. The reasoning for its existence is
28-
// to facilitate testing.
25+
// directly call a specific implementation.
26+
// The reasoning for its existence is to facilitate testing.
2927
type valuesProvider struct {
30-
flagProvider provider
31-
envVarProvider provider
28+
flagProvider func(string) (flag.Value, bool)
29+
envVarProvider func(string) (string, bool)
3230
}
3331

3432
// addLogFlags will add the set of 'log' related flags to a flag set.
@@ -65,7 +63,7 @@ func (f *FlagSet) addLogFlags(l *logFlags) {
6563
Usage: "Path to the log file that Vault should use for logging",
6664
})
6765

68-
f.StringVar(&StringVar{
66+
f.IntVar(&IntVar{
6967
Name: flagNameLogRotateBytes,
7068
Target: &l.flagLogRotateBytes,
7169
Usage: "Number of bytes that should be written to a log before it needs to be rotated. " +
@@ -79,23 +77,34 @@ func (f *FlagSet) addLogFlags(l *logFlags) {
7977
"Must be a duration value such as 30s",
8078
})
8179

82-
f.StringVar(&StringVar{
80+
f.IntVar(&IntVar{
8381
Name: flagNameLogRotateMaxFiles,
8482
Target: &l.flagLogRotateMaxFiles,
8583
Usage: "The maximum number of older log file archives to keep",
8684
})
8785
}
8886

89-
// getValue will attempt to find the flag with the corresponding flag name (key)
90-
// and return the value along with a bool representing whether of not the flag had been found/set.
91-
func (f *FlagSets) getValue(flagName string) (string, bool) {
92-
var result string
87+
// envVarValue attempts to get a named value from the environment variables.
88+
// The value will be returned as a string along with a boolean value indiciating
89+
// to the caller whether the named env var existed.
90+
func envVarValue(key string) (string, bool) {
91+
if key == "" {
92+
return "", false
93+
}
94+
return os.LookupEnv(key)
95+
}
96+
97+
// flagValue attempts to find the named flag in a set of FlagSets.
98+
// The flag.Value is returned if it was specified, and the boolean value indicates
99+
// to the caller if the flag was specified by the end user.
100+
func (f *FlagSets) flagValue(flagName string) (flag.Value, bool) {
101+
var result flag.Value
93102
var isFlagSpecified bool
94103

95104
if f != nil {
96105
f.Visit(func(fl *flag.Flag) {
97106
if fl.Name == flagName {
98-
result = fl.Value.String()
107+
result = fl.Value
99108
isFlagSpecified = true
100109
}
101110
})
@@ -104,51 +113,63 @@ func (f *FlagSets) getValue(flagName string) (string, bool) {
104113
return result, isFlagSpecified
105114
}
106115

107-
// getAggregatedConfigValue uses the provided keys to check CLI flags and environment
116+
// overrideValue uses the provided keys to check CLI flags and environment
108117
// variables for values that may be used to override any specified configuration.
109-
// If nothing can be found in flags/env vars or config, the 'fallback' (default) value will be provided.
110-
func (p *valuesProvider) getAggregatedConfigValue(flagKey, envVarKey, current, fallback string) string {
118+
func (p *valuesProvider) overrideValue(flagKey, envVarKey string) (string, bool) {
111119
var result string
112-
current = strings.TrimSpace(current)
120+
found := true
113121

114122
flg, flgFound := p.flagProvider(flagKey)
115123
env, envFound := p.envVarProvider(envVarKey)
116124

117125
switch {
118126
case flgFound:
119-
result = flg
127+
result = flg.String()
120128
case envFound:
121-
// Use value from env var
122129
result = env
123-
case current != "":
124-
// Use value from config
125-
result = current
126130
default:
127-
// Use the default value
128-
result = fallback
131+
found = false
129132
}
130133

131-
return result
134+
return result, found
132135
}
133136

134-
// updateLogConfig will accept a shared config and specifically attempt to update the 'log' related config keys.
135-
// For each 'log' key we aggregate file config/env vars and CLI flags to select the one with the highest precedence.
137+
// applyLogConfigOverrides will accept a shared config and specifically attempt to update the 'log' related config keys.
138+
// For each 'log' key, we aggregate file config, env vars and CLI flags to select the one with the highest precedence.
136139
// This method mutates the config object passed into it.
137-
func (f *FlagSets) updateLogConfig(config *configutil.SharedConfig) {
140+
func (f *FlagSets) applyLogConfigOverrides(config *configutil.SharedConfig) {
138141
p := &valuesProvider{
139-
flagProvider: func(key string) (string, bool) { return f.getValue(key) },
140-
envVarProvider: func(key string) (string, bool) {
141-
if key == "" {
142-
return "", false
143-
}
144-
return os.LookupEnv(key)
145-
},
142+
flagProvider: f.flagValue,
143+
envVarProvider: envVarValue,
144+
}
145+
146+
// Update log level
147+
if val, found := p.overrideValue(flagNameLogLevel, EnvVaultLogLevel); found {
148+
config.LogLevel = val
146149
}
147150

148-
config.LogLevel = p.getAggregatedConfigValue(flagNameLogLevel, EnvVaultLogLevel, config.LogLevel, "info")
149-
config.LogFormat = p.getAggregatedConfigValue(flagNameLogFormat, EnvVaultLogFormat, config.LogFormat, "")
150-
config.LogFile = p.getAggregatedConfigValue(flagNameLogFile, "", config.LogFile, "")
151-
config.LogRotateDuration = p.getAggregatedConfigValue(flagNameLogRotateDuration, "", config.LogRotateDuration, "")
152-
config.LogRotateBytes = p.getAggregatedConfigValue(flagNameLogRotateBytes, "", config.LogRotateBytes, "")
153-
config.LogRotateMaxFiles = p.getAggregatedConfigValue(flagNameLogRotateMaxFiles, "", config.LogRotateMaxFiles, "")
151+
// Update log format
152+
if val, found := p.overrideValue(flagNameLogFormat, EnvVaultLogFormat); found {
153+
config.LogFormat = val
154+
}
155+
156+
// Update log file name
157+
if val, found := p.overrideValue(flagNameLogFile, ""); found {
158+
config.LogFile = val
159+
}
160+
161+
// Update log rotation duration
162+
if val, found := p.overrideValue(flagNameLogRotateDuration, ""); found {
163+
config.LogRotateDuration = val
164+
}
165+
166+
// Update log max files
167+
if val, found := p.overrideValue(flagNameLogRotateMaxFiles, ""); found {
168+
config.LogRotateMaxFiles, _ = strconv.Atoi(val)
169+
}
170+
171+
// Update log rotation max bytes
172+
if val, found := p.overrideValue(flagNameLogRotateBytes, ""); found {
173+
config.LogRotateBytes, _ = strconv.Atoi(val)
174+
}
154175
}

0 commit comments

Comments
 (0)