vault/command/log_flags.go
hashicorp-copywrite[bot] 0b12cdcfd1
[COMPLIANCE] License changes (#22290)
* Adding explicit MPL license for sub-package.

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Adding explicit MPL license for sub-package.

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Updating the license from MPL to Business Source License.

Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at https://hashi.co/bsl-blog, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl.

* add missing license headers

* Update copyright file headers to BUS-1.1

* Fix test that expected exact offset on hcl file

---------

Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
Co-authored-by: Sarah Thompson <sthompson@hashicorp.com>
Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>
2023-08-10 18:14:03 -07:00

179 lines
5.1 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package command
import (
"flag"
"os"
"strconv"
"github.com/hashicorp/vault/internalshared/configutil"
"github.com/posener/complete"
)
// logFlags are the 'log' related flags that can be shared across commands.
type logFlags struct {
flagCombineLogs bool
flagLogLevel string
flagLogFormat string
flagLogFile string
flagLogRotateBytes int
flagLogRotateDuration string
flagLogRotateMaxFiles int
}
// valuesProvider has the intention of providing a way to supply a func with a
// way to retrieve values for flags and environment variables without having to
// directly call a specific implementation.
// The reasoning for its existence is to facilitate testing.
type valuesProvider struct {
flagProvider func(string) (flag.Value, bool)
envVarProvider func(string) (string, bool)
}
// addLogFlags will add the set of 'log' related flags to a flag set.
func (f *FlagSet) addLogFlags(l *logFlags) {
f.BoolVar(&BoolVar{
Name: flagNameCombineLogs,
Target: &l.flagCombineLogs,
Default: false,
Hidden: true,
})
f.StringVar(&StringVar{
Name: flagNameLogLevel,
Target: &l.flagLogLevel,
Default: notSetValue,
EnvVar: EnvVaultLogLevel,
Completion: complete.PredictSet("trace", "debug", "info", "warn", "error"),
Usage: "Log verbosity level. Supported values (in order of detail) are " +
"\"trace\", \"debug\", \"info\", \"warn\", and \"error\".",
})
f.StringVar(&StringVar{
Name: flagNameLogFormat,
Target: &l.flagLogFormat,
Default: notSetValue,
EnvVar: EnvVaultLogFormat,
Completion: complete.PredictSet("standard", "json"),
Usage: `Log format. Supported values are "standard" and "json".`,
})
f.StringVar(&StringVar{
Name: flagNameLogFile,
Target: &l.flagLogFile,
Usage: "Path to the log file that Vault should use for logging",
})
f.IntVar(&IntVar{
Name: flagNameLogRotateBytes,
Target: &l.flagLogRotateBytes,
Usage: "Number of bytes that should be written to a log before it needs to be rotated. " +
"Unless specified, there is no limit to the number of bytes that can be written to a log file",
})
f.StringVar(&StringVar{
Name: flagNameLogRotateDuration,
Target: &l.flagLogRotateDuration,
Usage: "The maximum duration a log should be written to before it needs to be rotated. " +
"Must be a duration value such as 30s",
})
f.IntVar(&IntVar{
Name: flagNameLogRotateMaxFiles,
Target: &l.flagLogRotateMaxFiles,
Usage: "The maximum number of older log file archives to keep",
})
}
// envVarValue attempts to get a named value from the environment variables.
// The value will be returned as a string along with a boolean value indiciating
// to the caller whether the named env var existed.
func envVarValue(key string) (string, bool) {
if key == "" {
return "", false
}
return os.LookupEnv(key)
}
// flagValue attempts to find the named flag in a set of FlagSets.
// The flag.Value is returned if it was specified, and the boolean value indicates
// to the caller if the flag was specified by the end user.
func (f *FlagSets) flagValue(flagName string) (flag.Value, bool) {
var result flag.Value
var isFlagSpecified bool
if f != nil {
f.Visit(func(fl *flag.Flag) {
if fl.Name == flagName {
result = fl.Value
isFlagSpecified = true
}
})
}
return result, isFlagSpecified
}
// overrideValue uses the provided keys to check CLI flags and environment
// variables for values that may be used to override any specified configuration.
func (p *valuesProvider) overrideValue(flagKey, envVarKey string) (string, bool) {
var result string
found := true
flg, flgFound := p.flagProvider(flagKey)
env, envFound := p.envVarProvider(envVarKey)
switch {
case flgFound:
result = flg.String()
case envFound:
result = env
default:
found = false
}
return result, found
}
// applyLogConfigOverrides will accept a shared config and specifically attempt to update the 'log' related config keys.
// For each 'log' key, we aggregate file config, env vars and CLI flags to select the one with the highest precedence.
// This method mutates the config object passed into it.
func (f *FlagSets) applyLogConfigOverrides(config *configutil.SharedConfig) {
p := &valuesProvider{
flagProvider: f.flagValue,
envVarProvider: envVarValue,
}
// Update log level
if val, found := p.overrideValue(flagNameLogLevel, EnvVaultLogLevel); found {
config.LogLevel = val
}
// Update log format
if val, found := p.overrideValue(flagNameLogFormat, EnvVaultLogFormat); found {
config.LogFormat = val
}
// Update log file name
if val, found := p.overrideValue(flagNameLogFile, ""); found {
config.LogFile = val
}
// Update log rotation duration
if val, found := p.overrideValue(flagNameLogRotateDuration, ""); found {
config.LogRotateDuration = val
}
// Update log max files
if val, found := p.overrideValue(flagNameLogRotateMaxFiles, ""); found {
config.LogRotateMaxFiles, _ = strconv.Atoi(val)
}
// Update log rotation max bytes
if val, found := p.overrideValue(flagNameLogRotateBytes, ""); found {
config.LogRotateBytes, _ = strconv.Atoi(val)
}
}