1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2024-11-24 08:52:25 +02:00

Replace options loading with viper

This commit is contained in:
Joel Speed 2020-04-13 11:34:25 +01:00
parent 8749cbb424
commit c5be09ca48
No known key found for this signature in database
GPG Key ID: 6E80578D6751DEFB
9 changed files with 27 additions and 147 deletions

View File

@ -1,54 +0,0 @@
package main
import (
"os"
"reflect"
"strings"
)
// EnvOptions holds program options loaded from the process environment
type EnvOptions map[string]interface{}
// LoadEnvForStruct loads environment variables for each field in an options
// struct passed into it.
//
// Fields in the options struct must have an `env` and `cfg` tag to be read
// from the environment
func (cfg EnvOptions) LoadEnvForStruct(options interface{}) {
val := reflect.ValueOf(options)
var typ reflect.Type
if val.Kind() == reflect.Ptr {
typ = val.Elem().Type()
} else {
typ = val.Type()
}
for i := 0; i < typ.NumField(); i++ {
// pull out the struct tags:
// flag - the name of the command line flag
// deprecated - (optional) the name of the deprecated command line flag
// cfg - (optional, defaults to underscored flag) the name of the config file option
field := typ.Field(i)
fieldV := reflect.Indirect(val).Field(i)
if field.Type.Kind() == reflect.Struct {
cfg.LoadEnvForStruct(fieldV.Interface())
continue
}
flagName := field.Tag.Get("flag")
envName := field.Tag.Get("env")
cfgName := field.Tag.Get("cfg")
if cfgName == "" && flagName != "" {
cfgName = strings.ReplaceAll(flagName, "-", "_")
}
if envName == "" || cfgName == "" {
// resolvable fields must have the `env` and `cfg` struct tag
continue
}
v := os.Getenv(envName)
if v != "" {
cfg[cfgName] = v
}
}
}

View File

@ -1,64 +0,0 @@
package main_test
import (
"os"
"testing"
proxy "github.com/oauth2-proxy/oauth2-proxy"
"github.com/stretchr/testify/assert"
)
type EnvTest struct {
TestField string `cfg:"target_field" env:"TEST_ENV_FIELD"`
EnvTestEmbed
Named EnvTestNamed
}
type EnvTestEmbed struct {
TestFieldEmbed string `cfg:"target_field_embed" env:"TEST_ENV_FIELD_EMBED"`
}
type EnvTestNamed struct {
TestFieldNamed string `cfg:"target_field_named" env:"TEST_ENV_FIELD_NAMED"`
}
func TestLoadEnvForStruct(t *testing.T) {
cfg := make(proxy.EnvOptions)
cfg.LoadEnvForStruct(&EnvTest{})
_, ok := cfg["target_field"]
assert.Equal(t, ok, false)
os.Setenv("TEST_ENV_FIELD", "1234abcd")
cfg.LoadEnvForStruct(&EnvTest{})
v := cfg["target_field"]
assert.Equal(t, v, "1234abcd")
}
func TestLoadEnvForStructWithEmbeddedFields(t *testing.T) {
cfg := make(proxy.EnvOptions)
cfg.LoadEnvForStruct(&EnvTest{})
_, ok := cfg["target_field_embed"]
assert.Equal(t, ok, false)
os.Setenv("TEST_ENV_FIELD_EMBED", "1234abcd")
cfg.LoadEnvForStruct(&EnvTest{})
v := cfg["target_field_embed"]
assert.Equal(t, v, "1234abcd")
}
func TestLoadEnvForStructWithNamedStructFields(t *testing.T) {
cfg := make(proxy.EnvOptions)
cfg.LoadEnvForStruct(&EnvTest{})
_, ok := cfg["target_field_named"]
assert.Equal(t, ok, false)
os.Setenv("TEST_ENV_FIELD_NAMED", "1234abcd")
cfg.LoadEnvForStruct(&EnvTest{})
v := cfg["target_field_named"]
assert.Equal(t, v, "1234abcd")
}

2
go.mod
View File

@ -3,7 +3,6 @@ module github.com/oauth2-proxy/oauth2-proxy
go 1.14
require (
github.com/BurntSushi/toml v0.3.1
github.com/alicebob/miniredis/v2 v2.11.2
github.com/bitly/go-simplejson v0.5.0
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
@ -14,7 +13,6 @@ require (
github.com/kr/pretty v0.2.0 // indirect
github.com/mbland/hmacauth v0.0.0-20170912233209-44256dfd4bfa
github.com/mitchellh/mapstructure v1.1.2
github.com/mreiferson/go-options v1.0.0
github.com/onsi/ginkgo v1.12.0
github.com/onsi/gomega v1.9.0
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect

7
go.sum
View File

@ -33,6 +33,7 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
@ -74,6 +75,7 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
@ -89,6 +91,7 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
@ -111,8 +114,6 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mreiferson/go-options v1.0.0 h1:RMLidydGlDWpL+lQTXo0bVIf/XT2CTq7AEJMoz5/VWs=
github.com/mreiferson/go-options v1.0.0/go.mod h1:zHtCks/HQvOt8ATyfwVe3JJq2PPuImzXINPRTC03+9w=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -142,7 +143,9 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=

24
main.go
View File

@ -12,9 +12,9 @@ import (
"syscall"
"time"
"github.com/BurntSushi/toml"
options "github.com/mreiferson/go-options"
"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options"
"github.com/oauth2-proxy/oauth2-proxy/pkg/logger"
"github.com/spf13/pflag"
)
func main() {
@ -149,7 +149,10 @@ func main() {
flagSet.String("user-id-claim", "email", "which claim contains the user ID")
flagSet.Parse(os.Args[1:])
pflagSet := pflag.NewFlagSet("oauth2-proxy", pflag.ExitOnError)
pflagSet.AddGoFlagSet(flagSet)
pflagSet.Parse(os.Args[1:])
if *showVersion {
fmt.Printf("oauth2-proxy %s (built with %s)\n", VERSION, runtime.Version())
@ -157,18 +160,13 @@ func main() {
}
opts := NewOptions()
cfg := make(EnvOptions)
if *config != "" {
_, err := toml.DecodeFile(*config, &cfg)
if err != nil {
logger.Fatalf("ERROR: failed to load config file %s - %s", *config, err)
}
err := options.Load(*config, pflagSet, opts)
if err != nil {
logger.Printf("ERROR: Failed to load config: %v", err)
os.Exit(1)
}
cfg.LoadEnvForStruct(opts)
options.Resolve(opts, flagSet, cfg)
err := opts.Validate()
err = opts.Validate()
if err != nil {
logger.Printf("%s", err)
os.Exit(1)

View File

@ -247,7 +247,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
panic(fmt.Sprintf("unknown upstream protocol %s", u.Scheme))
}
}
for _, u := range opts.CompiledRegex {
for _, u := range opts.compiledRegex {
logger.Printf("compiled skip-auth-regex => %q", u)
}
@ -303,7 +303,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
skipAuthPreflight: opts.SkipAuthPreflight,
skipJwtBearerTokens: opts.SkipJwtBearerTokens,
jwtBearerVerifiers: opts.jwtBearerVerifiers,
compiledRegex: opts.CompiledRegex,
compiledRegex: opts.compiledRegex,
SetXAuthRequest: opts.SetXAuthRequest,
PassBasicAuth: opts.PassBasicAuth,
SetBasicAuth: opts.SetBasicAuth,

View File

@ -64,9 +64,8 @@ type Options struct {
Banner string `flag:"banner" cfg:"banner" env:"OAUTH2_PROXY_BANNER"`
Footer string `flag:"footer" cfg:"footer" env:"OAUTH2_PROXY_FOOTER"`
Cookie options.CookieOptions
Session options.SessionOptions
Cookie options.CookieOptions `cfg:",squash"`
Session options.SessionOptions `cfg:",squash"`
Upstreams []string `flag:"upstream" cfg:"upstreams" env:"OAUTH2_PROXY_UPSTREAMS"`
SkipAuthRegex []string `flag:"skip-auth-regex" cfg:"skip_auth_regex" env:"OAUTH2_PROXY_SKIP_AUTH_REGEX"`
@ -132,7 +131,7 @@ type Options struct {
// internal values that are set after config validation
redirectURL *url.URL
proxyURLs []*url.URL
CompiledRegex []*regexp.Regexp
compiledRegex []*regexp.Regexp
provider providers.Provider
sessionStore sessionsapi.SessionStore
signatureData *SignatureData
@ -370,12 +369,12 @@ func (o *Options) Validate() error {
}
for _, u := range o.SkipAuthRegex {
CompiledRegex, err := regexp.Compile(u)
compiledRegex, err := regexp.Compile(u)
if err != nil {
msgs = append(msgs, fmt.Sprintf("error compiling regex=%q %s", u, err))
continue
}
o.CompiledRegex = append(o.CompiledRegex, CompiledRegex)
o.compiledRegex = append(o.compiledRegex, compiledRegex)
}
msgs = parseProviderInfo(o, msgs)

View File

@ -165,7 +165,7 @@ func TestCompiledRegex(t *testing.T) {
o.SkipAuthRegex = regexps
assert.Equal(t, nil, o.Validate())
actual := make([]string, 0)
for _, regex := range o.CompiledRegex {
for _, regex := range o.compiledRegex {
actual = append(actual, regex.String())
}
assert.Equal(t, regexps, actual)

View File

@ -4,9 +4,9 @@ import "github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
// SessionOptions contains configuration options for the SessionStore providers.
type SessionOptions struct {
Type string `flag:"session-store-type" cfg:"session_store_type" env:"OAUTH2_PROXY_SESSION_STORE_TYPE"`
Cipher *encryption.Cipher
Redis RedisStoreOptions
Type string `flag:"session-store-type" cfg:"session_store_type" env:"OAUTH2_PROXY_SESSION_STORE_TYPE"`
Cipher *encryption.Cipher `cfg:",internal"`
Redis RedisStoreOptions `cfg:",squash"`
}
// CookieSessionStoreType is used to indicate the CookieSessionStore should be