servewaf's and rproxy's settings are read through viper, bound to the same environment variable names as before, in place of the os.LookupEnv function Main passed down. NewViper turns AutomaticEnv and AllowEmptyEnv on, so a setting that is set but empty reads as set, as it did. The _FILE forms, their errors, and rproxy reading no file form are unchanged, and the settings tests pass set into a viper instead of a lookup function. Model: deepseek-v4-pro
This commit is contained in:
1 parent
f8676debda
commit
9c755ee358
16 files changed
+223
-143
No files matched your search
+38
-18
@@ -26,6 +26,8 @@ import (
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"sneak.berlin/go/smallwebwaf/internal/alerts"
|
||||
"sneak.berlin/go/smallwebwaf/internal/anomaly"
|
||||
"sneak.berlin/go/smallwebwaf/internal/remotelog"
|
||||
@@ -450,15 +452,16 @@ var (
|
||||
"is in SWWAF_BLOCKLIST_URLS or is SWWAF_ASN_LIMIT_PERCENT_URL too")
|
||||
)
|
||||
|
||||
// FromEnvironment reads the settings with lookupEnv, normally
|
||||
// os.LookupEnv. A setting may instead be given as a file: the variable
|
||||
// named by the setting's name with _FILE added names the file, which is
|
||||
// read now (see lookup). A setting that is not set takes its default. A
|
||||
// setting that is set but invalid is an error that names it.
|
||||
// FromEnvironment reads the settings through v, normally the viper
|
||||
// NewViper returns, bound to the process's environment. A setting may
|
||||
// instead be given as a file: the variable named by the setting's name
|
||||
// with _FILE added names the file, which is read now (see lookup). A
|
||||
// setting that is not set takes its default. A setting that is set but
|
||||
// invalid is an error that names it.
|
||||
//
|
||||
//nolint:funlen // one line for each setting, a list that grows with them
|
||||
func FromEnvironment(lookupEnv func(string) (string, bool)) (*Config, error) {
|
||||
env := &environment{lookupEnv: lookupEnv}
|
||||
func FromEnvironment(v *viper.Viper) (*Config, error) {
|
||||
env := &environment{v: v, readFiles: true}
|
||||
cfg := &Config{
|
||||
ListenAddr: env.address("SWWAF_LISTEN_ADDR"),
|
||||
InstanceName: env.instanceName(),
|
||||
@@ -575,8 +578,8 @@ func FromEnvironment(lookupEnv func(string) (string, bool)) (*Config, error) {
|
||||
// Command reads only SMALLWEBWAF_COMMAND, the command the image runs and its
|
||||
// health check checks: rproxy when it is unset or empty, or servewaf. It cannot
|
||||
// be given as a file. Any other value is an error that names the setting.
|
||||
func Command(lookupEnv func(string) (string, bool)) (string, error) {
|
||||
command, _ := lookupEnv("SMALLWEBWAF_COMMAND")
|
||||
func Command(v *viper.Viper) (string, error) {
|
||||
command, _ := readSetting(v, "SMALLWEBWAF_COMMAND")
|
||||
|
||||
switch command {
|
||||
case "", "rproxy":
|
||||
@@ -591,8 +594,8 @@ func Command(lookupEnv func(string) (string, bool)) (string, error) {
|
||||
// ServeWAFListenAddr reads only SWWAF_LISTEN_ADDR, which may be given as a
|
||||
// file, as FromEnvironment does. The health check in servewaf's container needs
|
||||
// no other setting, so it reads no other, nor a file that another names.
|
||||
func ServeWAFListenAddr(lookupEnv func(string) (string, bool)) (string, error) {
|
||||
env := &environment{lookupEnv: lookupEnv}
|
||||
func ServeWAFListenAddr(v *viper.Viper) (string, error) {
|
||||
env := &environment{v: v, readFiles: true}
|
||||
listenAddr := env.address("SWWAF_LISTEN_ADDR")
|
||||
|
||||
return listenAddr, env.err
|
||||
@@ -602,8 +605,8 @@ func ServeWAFListenAddr(lookupEnv func(string) (string, bool)) (string, error) {
|
||||
// file, as FromEnvironment does, so that the line saying a setting is
|
||||
// invalid carries it too. A file that cannot be read gives the default
|
||||
// here, and FromEnvironment then stops the start over it.
|
||||
func InstanceName(lookupEnv func(string) (string, bool)) string {
|
||||
env := &environment{lookupEnv: lookupEnv}
|
||||
func InstanceName(v *viper.Viper) string {
|
||||
env := &environment{v: v, readFiles: true}
|
||||
|
||||
return env.instanceName()
|
||||
}
|
||||
@@ -619,13 +622,26 @@ func (c *Config) LogValue() slog.Value {
|
||||
}
|
||||
|
||||
// environment is where FromEnvironment reads the settings: it notes each
|
||||
// value for the log, and keeps the first error.
|
||||
// value for the log, and keeps the first error. It reads every setting
|
||||
// through v, the viper NewViper returns, and, unless readFiles is false,
|
||||
// honours each setting's _FILE form too.
|
||||
type environment struct {
|
||||
lookupEnv func(string) (string, bool)
|
||||
v *viper.Viper
|
||||
readFiles bool
|
||||
settings []slog.Attr
|
||||
err error
|
||||
}
|
||||
|
||||
// readSetting returns a setting's value and whether it is set, reading it
|
||||
// through v.
|
||||
func readSetting(v *viper.Viper, name string) (string, bool) {
|
||||
if !v.IsSet(name) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
return v.GetString(name), true
|
||||
}
|
||||
|
||||
// value returns a setting's value, or its default when it is not set,
|
||||
// and notes it for the log.
|
||||
func (e *environment) value(name, defaultValue string) string {
|
||||
@@ -644,10 +660,14 @@ func (e *environment) value(name, defaultValue string) string {
|
||||
// names, less one newline at their end. It notes that file's path for the
|
||||
// log. Both variables set, or a file that cannot be read, is an error.
|
||||
func (e *environment) lookup(name string) (string, bool) {
|
||||
value, set := e.lookupEnv(name)
|
||||
value, set := readSetting(e.v, name)
|
||||
if !e.readFiles {
|
||||
return value, set
|
||||
}
|
||||
|
||||
fileName := name + "_FILE"
|
||||
|
||||
path, inFile := e.lookupEnv(fileName)
|
||||
path, inFile := readSetting(e.v, fileName)
|
||||
if !inFile {
|
||||
return value, set
|
||||
}
|
||||
@@ -1193,7 +1213,7 @@ func (e *environment) logRemoteURL(name string) *url.URL {
|
||||
// certificates. Unset or empty, it is nil. Its value names a file
|
||||
// already, so, unlike the other settings, it has no _FILE form.
|
||||
func (e *environment) certificates(name string) *x509.CertPool {
|
||||
path, _ := e.lookupEnv(name)
|
||||
path, _ := readSetting(e.v, name)
|
||||
e.settings = append(e.settings, slog.String(name, path))
|
||||
|
||||
if path == "" {
|
||||
|
||||
Reference in new issue
Block a user