mirror of
https://github.com/pomerium/pomerium.git
synced 2025-08-06 10:21:05 +02:00
add config option check logging (#3722)
This commit is contained in:
parent
02df20f10a
commit
74a7daed4f
2 changed files with 105 additions and 15 deletions
|
@ -11,11 +11,11 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/volatiletech/null/v9"
|
"github.com/volatiletech/null/v9"
|
||||||
|
|
||||||
|
@ -374,7 +374,9 @@ func optionsFromViper(configFile string) (*Options, error) {
|
||||||
if err := v.Unmarshal(o, ViperPolicyHooks, func(c *mapstructure.DecoderConfig) { c.Metadata = &metadata }); err != nil {
|
if err := v.Unmarshal(o, ViperPolicyHooks, func(c *mapstructure.DecoderConfig) { c.Metadata = &metadata }); err != nil {
|
||||||
return nil, fmt.Errorf("failed to unmarshal config: %w", err)
|
return nil, fmt.Errorf("failed to unmarshal config: %w", err)
|
||||||
}
|
}
|
||||||
checkUnusedConfigFields(configFile, metadata.Unused)
|
if err := checkConfigKeysErrors(configFile, metadata.Unused); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// This is necessary because v.Unmarshal will overwrite .viper field.
|
// This is necessary because v.Unmarshal will overwrite .viper field.
|
||||||
o.viper = v
|
o.viper = v
|
||||||
|
@ -385,22 +387,28 @@ func optionsFromViper(configFile string) (*Options, error) {
|
||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
func checkConfigKeysErrors(configFile string, unused []string) error {
|
||||||
// policy's embedded protobuf structs are decoded by separate hook and are unknown to mapstructure
|
checks := CheckUnknownConfigFields(unused)
|
||||||
routesEmbeddedFieldsRe = regexp.MustCompile(`(routes|policy)\[\.*`)
|
ctx := context.Background()
|
||||||
)
|
errInvalidConfigKeys := errors.New("some configuration options are no longer supported, please check logs for details")
|
||||||
|
var err error
|
||||||
|
|
||||||
func checkUnusedConfigFields(configFile string, unused []string) {
|
for _, check := range checks {
|
||||||
keys := make([]string, 0, len(unused))
|
var evt *zerolog.Event
|
||||||
for _, k := range unused {
|
switch check.KeyAction {
|
||||||
if !routesEmbeddedFieldsRe.MatchString(k) {
|
case KeyActionError:
|
||||||
keys = append(keys, k)
|
evt = log.Error(ctx)
|
||||||
|
err = errInvalidConfigKeys
|
||||||
|
default:
|
||||||
|
evt = log.Warn(ctx)
|
||||||
}
|
}
|
||||||
|
evt.Str("config_file", configFile).Str("key", check.Key)
|
||||||
|
if check.DocsURL != "" {
|
||||||
|
evt = evt.Str("help", check.DocsURL)
|
||||||
}
|
}
|
||||||
if len(keys) == 0 {
|
evt.Msg(string(check.FieldCheckMsg))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
log.Warn(context.Background()).Str("config_file", configFile).Strs("keys", keys).Msg("config contained unknown keys that were ignored")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// parsePolicy initializes policy to the options from either base64 environmental
|
// parsePolicy initializes policy to the options from either base64 environmental
|
||||||
|
|
82
config/options_check.go
Normal file
82
config/options_check.go
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KeyAction defines the Pomerium behavior when it encounters a deprecated config field
|
||||||
|
type KeyAction string
|
||||||
|
|
||||||
|
// FieldCheckMsg is a log message to print for a config option
|
||||||
|
type FieldCheckMsg string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// KeyActionWarn would result in warning to log
|
||||||
|
KeyActionWarn = KeyAction("warn")
|
||||||
|
// KeyActionError would result in error in log and possibly program stop
|
||||||
|
KeyActionError = KeyAction("error")
|
||||||
|
// UnknownFieldAction default behavior when observing an unknown field is to warn
|
||||||
|
UnknownFieldAction = KeyActionWarn
|
||||||
|
// FieldCheckMsgRemoved log message when field was removed
|
||||||
|
FieldCheckMsgRemoved = FieldCheckMsg("config option was removed")
|
||||||
|
// FieldCheckMsgUnknown log message for unrecognized / unhandled config option
|
||||||
|
FieldCheckMsgUnknown = FieldCheckMsg("unknown config option")
|
||||||
|
)
|
||||||
|
|
||||||
|
var reKeyPath = regexp.MustCompile(`\[\d+\]`)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// options that were deprecated in the config
|
||||||
|
removedConfigFields = map[string]string{
|
||||||
|
"idp_service_account": "https://docs.pomerium.com/docs/overview/upgrading#idp-directory-sync",
|
||||||
|
"idp_refresh_directory_timeout": "https://docs.pomerium.com/docs/overview/upgrading#idp-directory-sync",
|
||||||
|
"idp_refresh_directory_interval": "https://docs.pomerium.com/docs/overview/upgrading#idp-directory-sync",
|
||||||
|
"idp_qps": "https://docs.pomerium.com/docs/overview/upgrading#idp-directory-sync",
|
||||||
|
"routes.allowed_groups": "https://docs.pomerium.com/docs/overview/upgrading#idp-groups-policy",
|
||||||
|
}
|
||||||
|
|
||||||
|
// mapstructure has issues with embedded protobuf structs that we should ignore
|
||||||
|
ignoreConfigFields = map[string]struct{}{
|
||||||
|
"routes.outlier_detection": {},
|
||||||
|
"routes.health_checks": {},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// FieldMsg returns information
|
||||||
|
type FieldMsg struct {
|
||||||
|
Key string
|
||||||
|
DocsURL string
|
||||||
|
FieldCheckMsg
|
||||||
|
KeyAction
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckUnknownConfigFields returns list of messages to be emitted about unrecognized fields
|
||||||
|
func CheckUnknownConfigFields(fields []string) []FieldMsg {
|
||||||
|
out := make([]FieldMsg, 0, len(fields))
|
||||||
|
|
||||||
|
for _, key := range fields {
|
||||||
|
path := reKeyPath.ReplaceAllString(key, "")
|
||||||
|
|
||||||
|
if docsURL, ok := removedConfigFields[path]; ok {
|
||||||
|
out = append(out, FieldMsg{
|
||||||
|
Key: path,
|
||||||
|
DocsURL: docsURL,
|
||||||
|
KeyAction: KeyActionError,
|
||||||
|
FieldCheckMsg: FieldCheckMsgRemoved,
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := ignoreConfigFields[path]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
out = append(out, FieldMsg{
|
||||||
|
Key: path,
|
||||||
|
KeyAction: KeyActionWarn,
|
||||||
|
FieldCheckMsg: FieldCheckMsgUnknown,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue