From 12ab4ef52958ab18d1156cd1cee0618ed38efe32 Mon Sep 17 00:00:00 2001 From: Fabian Stelzer Date: Mon, 9 Aug 2021 13:32:15 +0000 Subject: [PATCH] Make the Upstreams mux configurable This commit changes Upstreams from []Upstream to a struct{} moving the previous []Upstream into .Configs and adjusts all uses of it. --- main_test.go | 21 ++-- oauthproxy_test.go | 82 ++++++++----- pkg/apis/options/legacy_options.go | 4 +- pkg/apis/options/legacy_options_test.go | 80 +++++++------ pkg/apis/options/load_test.go | 23 ++-- pkg/apis/options/upstreams.go | 6 +- pkg/upstream/proxy.go | 4 +- pkg/upstream/proxy_test.go | 152 ++++++++++++------------ pkg/validation/options_test.go | 2 +- pkg/validation/upstreams.go | 2 +- pkg/validation/upstreams_test.go | 138 ++++++++++++--------- 11 files changed, 283 insertions(+), 231 deletions(-) diff --git a/main_test.go b/main_test.go index e40243ef..b8f7b488 100644 --- a/main_test.go +++ b/main_test.go @@ -25,6 +25,7 @@ client_secret="b2F1dGgyLXByb3h5LWNsaWVudC1zZWNyZXQK" const testAlphaConfig = ` upstreams: + configs: - id: / path: / uri: http://httpbin @@ -101,13 +102,15 @@ redirect_url="http://localhost:4180/oauth2/callback" opts.RawRedirectURL = "http://localhost:4180/oauth2/callback" opts.UpstreamServers = options.Upstreams{ - { - ID: "/", - Path: "/", - URI: "http://httpbin", - FlushInterval: durationPtr(options.DefaultUpstreamFlushInterval), - PassHostHeader: boolPtr(true), - ProxyWebSockets: boolPtr(true), + Configs: []options.Upstream{ + { + ID: "/", + Path: "/", + URI: "http://httpbin", + FlushInterval: durationPtr(options.DefaultUpstreamFlushInterval), + PassHostHeader: boolPtr(true), + ProxyWebSockets: boolPtr(true), + }, }, } @@ -130,7 +133,7 @@ redirect_url="http://localhost:4180/oauth2/callback" opts.InjectResponseHeaders = append(opts.InjectResponseHeaders, authHeader) opts.Providers = options.Providers{ - { + options.Provider{ ID: "google=oauth2-proxy", Type: "google", ClientSecret: "b2F1dGgyLXByb3h5LWNsaWVudC1zZWNyZXQK", @@ -230,7 +233,7 @@ redirect_url="http://localhost:4180/oauth2/callback" configContent: testCoreConfig, alphaConfigContent: testAlphaConfig + ":", expectedOptions: func() *options.Options { return nil }, - expectedErr: errors.New("failed to load alpha options: error unmarshalling config: error converting YAML to JSON: yaml: line 49: did not find expected key"), + expectedErr: errors.New("failed to load alpha options: error unmarshalling config: error converting YAML to JSON: yaml: line 50: did not find expected key"), }), Entry("with alpha configuration and bad core configuration", loadConfigurationTableInput{ configContent: testCoreConfig + "unknown_field=\"something\"", diff --git a/oauthproxy_test.go b/oauthproxy_test.go index 3a795f18..d0eaaa4d 100644 --- a/oauthproxy_test.go +++ b/oauthproxy_test.go @@ -198,10 +198,12 @@ func TestBasicAuthPassword(t *testing.T) { basicAuthPassword := "This is a secure password" opts := baseTestOptions() opts.UpstreamServers = options.Upstreams{ - { - ID: providerServer.URL, - Path: "/", - URI: providerServer.URL, + Configs: []options.Upstream{ + { + ID: providerServer.URL, + Path: "/", + URI: providerServer.URL, + }, }, } @@ -347,14 +349,16 @@ func NewPassAccessTokenTest(opts PassAccessTokenTestOptions) (*PassAccessTokenTe patt.opts = baseTestOptions() patt.opts.UpstreamServers = options.Upstreams{ - { - ID: patt.providerServer.URL, - Path: "/", - URI: patt.providerServer.URL, + Configs: []options.Upstream{ + { + ID: patt.providerServer.URL, + Path: "/", + URI: patt.providerServer.URL, + }, }, } if opts.ProxyUpstream.ID != "" { - patt.opts.UpstreamServers = append(patt.opts.UpstreamServers, opts.ProxyUpstream) + patt.opts.UpstreamServers.Configs = append(patt.opts.UpstreamServers.Configs, opts.ProxyUpstream) } patt.opts.Cookie.Secure = false @@ -1270,10 +1274,12 @@ func TestAuthSkippedForPreflightRequests(t *testing.T) { opts := baseTestOptions() opts.UpstreamServers = options.Upstreams{ - { - ID: upstreamServer.URL, - Path: "/", - URI: upstreamServer.URL, + Configs: []options.Upstream{ + { + ID: upstreamServer.URL, + Path: "/", + URI: upstreamServer.URL, + }, }, } opts.SkipAuthPreflight = true @@ -1345,10 +1351,12 @@ func NewSignatureTest() (*SignatureTest, error) { return nil, err } opts.UpstreamServers = options.Upstreams{ - { - ID: upstreamServer.URL, - Path: "/", - URI: upstreamServer.URL, + Configs: []options.Upstream{ + { + ID: upstreamServer.URL, + Path: "/", + URI: upstreamServer.URL, + }, }, } @@ -1781,10 +1789,12 @@ func Test_noCacheHeaders(t *testing.T) { opts := baseTestOptions() opts.UpstreamServers = options.Upstreams{ - { - ID: upstreamServer.URL, - Path: "/", - URI: upstreamServer.URL, + Configs: []options.Upstream{ + { + ID: upstreamServer.URL, + Path: "/", + URI: upstreamServer.URL, + }, }, } opts.SkipAuthRegex = []string{".*"} @@ -2051,10 +2061,12 @@ func TestTrustedIPs(t *testing.T) { t.Run(tt.name, func(t *testing.T) { opts := baseTestOptions() opts.UpstreamServers = options.Upstreams{ - { - ID: "static", - Path: "/", - Static: true, + Configs: []options.Upstream{ + { + ID: "static", + Path: "/", + Static: true, + }, }, } opts.TrustedIPs = tt.trustedIPs @@ -2244,10 +2256,12 @@ func TestAllowedRequest(t *testing.T) { opts := baseTestOptions() opts.UpstreamServers = options.Upstreams{ - { - ID: upstreamServer.URL, - Path: "/", - URI: upstreamServer.URL, + Configs: []options.Upstream{ + { + ID: upstreamServer.URL, + Path: "/", + URI: upstreamServer.URL, + }, }, } opts.SkipAuthRegex = []string{ @@ -2359,10 +2373,12 @@ func TestProxyAllowedGroups(t *testing.T) { test, err := NewProcessCookieTestWithOptionsModifiers(func(opts *options.Options) { opts.Providers[0].AllowedGroups = tt.allowedGroups opts.UpstreamServers = options.Upstreams{ - { - ID: upstreamServer.URL, - Path: "/", - URI: upstreamServer.URL, + Configs: []options.Upstream{ + { + ID: upstreamServer.URL, + Path: "/", + URI: upstreamServer.URL, + }, }, } }) diff --git a/pkg/apis/options/legacy_options.go b/pkg/apis/options/legacy_options.go index cf67dedd..fb51feed 100644 --- a/pkg/apis/options/legacy_options.go +++ b/pkg/apis/options/legacy_options.go @@ -120,7 +120,7 @@ func (l *LegacyUpstreams) convert() (Upstreams, error) { for _, upstreamString := range l.Upstreams { u, err := url.Parse(upstreamString) if err != nil { - return nil, fmt.Errorf("could not parse upstream %q: %v", upstreamString, err) + return Upstreams{}, fmt.Errorf("could not parse upstream %q: %v", upstreamString, err) } if u.Path == "" { @@ -169,7 +169,7 @@ func (l *LegacyUpstreams) convert() (Upstreams, error) { upstream.FlushInterval = nil } - upstreams = append(upstreams, upstream) + upstreams.Configs = append(upstreams.Configs, upstream) } return upstreams, nil diff --git a/pkg/apis/options/legacy_options_test.go b/pkg/apis/options/legacy_options_test.go index fb5b816a..88c32817 100644 --- a/pkg/apis/options/legacy_options_test.go +++ b/pkg/apis/options/legacy_options_test.go @@ -27,34 +27,36 @@ var _ = Describe("Legacy Options", func() { truth := true staticCode := 204 opts.UpstreamServers = Upstreams{ - { - ID: "/baz", - Path: "/baz", - URI: "http://foo.bar/baz", - FlushInterval: &flushInterval, - InsecureSkipTLSVerify: true, - PassHostHeader: &truth, - ProxyWebSockets: &truth, - }, - { - ID: "/bar", - Path: "/bar", - URI: "file:///var/lib/website", - FlushInterval: &flushInterval, - InsecureSkipTLSVerify: true, - PassHostHeader: &truth, - ProxyWebSockets: &truth, - }, - { - ID: "static://204", - Path: "/", - URI: "", - Static: true, - StaticCode: &staticCode, - FlushInterval: nil, - InsecureSkipTLSVerify: false, - PassHostHeader: nil, - ProxyWebSockets: nil, + Configs: []Upstream{ + { + ID: "/baz", + Path: "/baz", + URI: "http://foo.bar/baz", + FlushInterval: &flushInterval, + InsecureSkipTLSVerify: true, + PassHostHeader: &truth, + ProxyWebSockets: &truth, + }, + { + ID: "/bar", + Path: "/bar", + URI: "file:///var/lib/website", + FlushInterval: &flushInterval, + InsecureSkipTLSVerify: true, + PassHostHeader: &truth, + ProxyWebSockets: &truth, + }, + { + ID: "static://204", + Path: "/", + URI: "", + Static: true, + StaticCode: &staticCode, + FlushInterval: nil, + InsecureSkipTLSVerify: false, + PassHostHeader: nil, + ProxyWebSockets: nil, + }, }, } @@ -124,7 +126,7 @@ var _ = Describe("Legacy Options", func() { Context("Legacy Upstreams", func() { type convertUpstreamsTableInput struct { upstreamStrings []string - expectedUpstreams Upstreams + expectedUpstreams []Upstream errMsg string } @@ -219,51 +221,51 @@ var _ = Describe("Legacy Options", func() { Expect(err).ToNot(HaveOccurred()) } - Expect(upstreams).To(ConsistOf(in.expectedUpstreams)) + Expect(upstreams.Configs).To(ConsistOf(in.expectedUpstreams)) }, Entry("with no upstreams", &convertUpstreamsTableInput{ upstreamStrings: []string{}, - expectedUpstreams: Upstreams{}, + expectedUpstreams: []Upstream{}, errMsg: "", }), Entry("with a valid HTTP upstream", &convertUpstreamsTableInput{ upstreamStrings: []string{validHTTP}, - expectedUpstreams: Upstreams{validHTTPUpstream}, + expectedUpstreams: []Upstream{validHTTPUpstream}, errMsg: "", }), Entry("with a HTTP upstream with an empty path", &convertUpstreamsTableInput{ upstreamStrings: []string{emptyPathHTTP}, - expectedUpstreams: Upstreams{emptyPathHTTPUpstream}, + expectedUpstreams: []Upstream{emptyPathHTTPUpstream}, errMsg: "", }), Entry("with a valid File upstream with a fragment", &convertUpstreamsTableInput{ upstreamStrings: []string{validFileWithFragment}, - expectedUpstreams: Upstreams{validFileWithFragmentUpstream}, + expectedUpstreams: []Upstream{validFileWithFragmentUpstream}, errMsg: "", }), Entry("with a valid static upstream", &convertUpstreamsTableInput{ upstreamStrings: []string{validStatic}, - expectedUpstreams: Upstreams{validStaticUpstream}, + expectedUpstreams: []Upstream{validStaticUpstream}, errMsg: "", }), Entry("with an invalid static upstream, code is 200", &convertUpstreamsTableInput{ upstreamStrings: []string{invalidStatic}, - expectedUpstreams: Upstreams{invalidStaticUpstream}, + expectedUpstreams: []Upstream{invalidStaticUpstream}, errMsg: "", }), Entry("with an invalid HTTP upstream", &convertUpstreamsTableInput{ upstreamStrings: []string{invalidHTTP}, - expectedUpstreams: Upstreams{}, + expectedUpstreams: []Upstream{}, errMsg: invalidHTTPErrMsg, }), Entry("with an invalid HTTP upstream and other upstreams", &convertUpstreamsTableInput{ upstreamStrings: []string{validHTTP, invalidHTTP}, - expectedUpstreams: Upstreams{}, + expectedUpstreams: []Upstream{}, errMsg: invalidHTTPErrMsg, }), Entry("with multiple valid upstreams", &convertUpstreamsTableInput{ upstreamStrings: []string{validHTTP, validFileWithFragment, validStatic}, - expectedUpstreams: Upstreams{validHTTPUpstream, validFileWithFragmentUpstream, validStaticUpstream}, + expectedUpstreams: []Upstream{validHTTPUpstream, validFileWithFragmentUpstream, validStaticUpstream}, errMsg: "", }), ) diff --git a/pkg/apis/options/load_test.go b/pkg/apis/options/load_test.go index dce5d2d9..ca4918b2 100644 --- a/pkg/apis/options/load_test.go +++ b/pkg/apis/options/load_test.go @@ -470,10 +470,11 @@ sub: It("should load a full example AlphaOptions", func() { config := []byte(` upstreams: -- id: httpbin - path: / - uri: http://httpbin - flushInterval: 500ms + configs: + - id: httpbin + path: / + uri: http://httpbin + flushInterval: 500ms injectRequestHeaders: - name: X-Forwarded-User values: @@ -502,12 +503,14 @@ injectResponseHeaders: flushInterval := Duration(500 * time.Millisecond) Expect(into).To(Equal(&AlphaOptions{ - Upstreams: []Upstream{ - { - ID: "httpbin", - Path: "/", - URI: "http://httpbin", - FlushInterval: &flushInterval, + Upstreams: Upstreams{ + Configs: []Upstream{ + { + ID: "httpbin", + Path: "/", + URI: "http://httpbin", + FlushInterval: &flushInterval, + }, }, }, InjectRequestHeaders: []Header{ diff --git a/pkg/apis/options/upstreams.go b/pkg/apis/options/upstreams.go index 1977c8da..368da3ed 100644 --- a/pkg/apis/options/upstreams.go +++ b/pkg/apis/options/upstreams.go @@ -8,7 +8,11 @@ const ( ) // Upstreams is a collection of definitions for upstream servers. -type Upstreams []Upstream +type Upstreams struct { + // Upstream represents the configuration for an upstream server. + // Requests will be proxied to this upstream if the path matches the request path. + Configs []Upstream `json:"configs,omitempty"` +} // Upstream represents the configuration for an upstream server. // Requests will be proxied to this upstream if the path matches the request path. diff --git a/pkg/upstream/proxy.go b/pkg/upstream/proxy.go index 594824e2..a7e19b63 100644 --- a/pkg/upstream/proxy.go +++ b/pkg/upstream/proxy.go @@ -27,7 +27,7 @@ func NewProxy(upstreams options.Upstreams, sigData *options.SignatureData, write serveMux: mux.NewRouter(), } - for _, upstream := range sortByPathLongest(upstreams) { + for _, upstream := range sortByPathLongest(upstreams.Configs) { if upstream.Static { if err := m.registerStaticResponseHandler(upstream, writer); err != nil { return nil, fmt.Errorf("could not register static upstream %q: %v", upstream.ID, err) @@ -153,7 +153,7 @@ func registerTrailingSlashHandler(serveMux *mux.Router) { // precedence (note this is the input to the rewrite logic). // This does not account for when a rewrite would actually make the path shorter. // This should maintain the sorting behaviour of the standard go serve mux. -func sortByPathLongest(in options.Upstreams) options.Upstreams { +func sortByPathLongest(in []options.Upstream) []options.Upstream { sort.Slice(in, func(i, j int) bool { iRW := in[i].RewriteTarget jRW := in[j].RewriteTarget diff --git a/pkg/upstream/proxy_test.go b/pkg/upstream/proxy_test.go index 597f5422..ae73f489 100644 --- a/pkg/upstream/proxy_test.go +++ b/pkg/upstream/proxy_test.go @@ -33,61 +33,63 @@ var _ = Describe("Proxy Suite", func() { accepted := http.StatusAccepted upstreams := options.Upstreams{ - { - ID: "http-backend", - Path: "/http/", - URI: serverAddr, - }, - { - ID: "file-backend", - Path: "/files/", - URI: fmt.Sprintf("file:///%s", filesDir), - }, - { - ID: "static-backend", - Path: "/static/", - Static: true, - StaticCode: &ok, - }, - { - ID: "static-backend-no-trailing-slash", - Path: "/static", - Static: true, - StaticCode: &accepted, - }, - { - ID: "static-backend-long", - Path: "/static/long", - Static: true, - StaticCode: &accepted, - }, - { - ID: "bad-http-backend", - Path: "/bad-http/", - URI: "http://::1", - }, - { - ID: "single-path-backend", - Path: "/single-path", - Static: true, - StaticCode: &ok, - }, - { - ID: "backend-with-rewrite-prefix", - Path: "^/rewrite-prefix/(.*)", - RewriteTarget: "/different/backend/path/$1", - URI: serverAddr, - }, - { - ID: "double-match-plain", - Path: "/double-match/", - URI: serverAddr, - }, - { - ID: "double-match-rewrite", - Path: "^/double-match/(.*)", - RewriteTarget: "/double-match/rewrite/$1", - URI: serverAddr, + Configs: []options.Upstream{ + { + ID: "http-backend", + Path: "/http/", + URI: serverAddr, + }, + { + ID: "file-backend", + Path: "/files/", + URI: fmt.Sprintf("file:///%s", filesDir), + }, + { + ID: "static-backend", + Path: "/static/", + Static: true, + StaticCode: &ok, + }, + { + ID: "static-backend-no-trailing-slash", + Path: "/static", + Static: true, + StaticCode: &accepted, + }, + { + ID: "static-backend-long", + Path: "/static/long", + Static: true, + StaticCode: &accepted, + }, + { + ID: "bad-http-backend", + Path: "/bad-http/", + URI: "http://::1", + }, + { + ID: "single-path-backend", + Path: "/single-path", + Static: true, + StaticCode: &ok, + }, + { + ID: "backend-with-rewrite-prefix", + Path: "^/rewrite-prefix/(.*)", + RewriteTarget: "/different/backend/path/$1", + URI: serverAddr, + }, + { + ID: "double-match-plain", + Path: "/double-match/", + URI: serverAddr, + }, + { + ID: "double-match-rewrite", + Path: "^/double-match/(.*)", + RewriteTarget: "/double-match/rewrite/$1", + URI: serverAddr, + }, }, } @@ -315,8 +317,8 @@ var _ = Describe("Proxy Suite", func() { Context("sortByPathLongest", func() { type sortByPathLongestTableInput struct { - input options.Upstreams - expectedOutput options.Upstreams + input []options.Upstream + expectedOutput []options.Upstream } var httpPath = options.Upstream{ @@ -346,40 +348,40 @@ var _ = Describe("Proxy Suite", func() { Expect(sortByPathLongest(in.input)).To(Equal(in.expectedOutput)) }, Entry("with a mix of paths registered", sortByPathLongestTableInput{ - input: options.Upstreams{httpPath, httpSubPath, shortSubPathWithRewrite, longerPath, shortPathWithRewrite}, - expectedOutput: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite, longerPath, httpSubPath, httpPath}, + input: []options.Upstream{httpPath, httpSubPath, shortSubPathWithRewrite, longerPath, shortPathWithRewrite}, + expectedOutput: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite, longerPath, httpSubPath, httpPath}, }), Entry("when a subpath is registered (in order)", sortByPathLongestTableInput{ - input: options.Upstreams{httpSubPath, httpPath}, - expectedOutput: options.Upstreams{httpSubPath, httpPath}, + input: []options.Upstream{httpSubPath, httpPath}, + expectedOutput: []options.Upstream{httpSubPath, httpPath}, }), Entry("when a subpath is registered (out of order)", sortByPathLongestTableInput{ - input: options.Upstreams{httpPath, httpSubPath}, - expectedOutput: options.Upstreams{httpSubPath, httpPath}, + input: []options.Upstream{httpPath, httpSubPath}, + expectedOutput: []options.Upstream{httpSubPath, httpPath}, }), Entry("when longer paths are registered (in order)", sortByPathLongestTableInput{ - input: options.Upstreams{longerPath, httpPath}, - expectedOutput: options.Upstreams{longerPath, httpPath}, + input: []options.Upstream{longerPath, httpPath}, + expectedOutput: []options.Upstream{longerPath, httpPath}, }), Entry("when longer paths are registered (out of order)", sortByPathLongestTableInput{ - input: options.Upstreams{httpPath, longerPath}, - expectedOutput: options.Upstreams{longerPath, httpPath}, + input: []options.Upstream{httpPath, longerPath}, + expectedOutput: []options.Upstream{longerPath, httpPath}, }), Entry("when a rewrite target is registered (in order)", sortByPathLongestTableInput{ - input: options.Upstreams{shortPathWithRewrite, longerPath}, - expectedOutput: options.Upstreams{shortPathWithRewrite, longerPath}, + input: []options.Upstream{shortPathWithRewrite, longerPath}, + expectedOutput: []options.Upstream{shortPathWithRewrite, longerPath}, }), Entry("when a rewrite target is registered (out of order)", sortByPathLongestTableInput{ - input: options.Upstreams{longerPath, shortPathWithRewrite}, - expectedOutput: options.Upstreams{shortPathWithRewrite, longerPath}, + input: []options.Upstream{longerPath, shortPathWithRewrite}, + expectedOutput: []options.Upstream{shortPathWithRewrite, longerPath}, }), Entry("with multiple rewrite targets registered (in order)", sortByPathLongestTableInput{ - input: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite}, - expectedOutput: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite}, + input: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite}, + expectedOutput: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite}, }), Entry("with multiple rewrite targets registered (out of order)", sortByPathLongestTableInput{ - input: options.Upstreams{shortPathWithRewrite, shortSubPathWithRewrite}, - expectedOutput: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite}, + input: []options.Upstream{shortPathWithRewrite, shortSubPathWithRewrite}, + expectedOutput: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite}, }), ) }) diff --git a/pkg/validation/options_test.go b/pkg/validation/options_test.go index 5f9e3716..70387a14 100644 --- a/pkg/validation/options_test.go +++ b/pkg/validation/options_test.go @@ -22,7 +22,7 @@ const ( func testOptions() *options.Options { o := options.NewOptions() - o.UpstreamServers = append(o.UpstreamServers, options.Upstream{ + o.UpstreamServers.Configs = append(o.UpstreamServers.Configs, options.Upstream{ ID: "upstream", Path: "/", URI: "http://127.0.0.1:8080/", diff --git a/pkg/validation/upstreams.go b/pkg/validation/upstreams.go index 7bd6b2d5..f45f3b94 100644 --- a/pkg/validation/upstreams.go +++ b/pkg/validation/upstreams.go @@ -12,7 +12,7 @@ func validateUpstreams(upstreams options.Upstreams) []string { ids := make(map[string]struct{}) paths := make(map[string]struct{}) - for _, upstream := range upstreams { + for _, upstream := range upstreams.Configs { msgs = append(msgs, validateUpstream(upstream, ids, paths)...) } diff --git a/pkg/validation/upstreams_test.go b/pkg/validation/upstreams_test.go index 122286ad..1c974024 100644 --- a/pkg/validation/upstreams_test.go +++ b/pkg/validation/upstreams_test.go @@ -59,83 +59,99 @@ var _ = Describe("Upstreams", func() { }), Entry("with valid upstreams", &validateUpstreamTableInput{ upstreams: options.Upstreams{ - validHTTPUpstream, - validStaticUpstream, - validFileUpstream, + Configs: []options.Upstream{ + validHTTPUpstream, + validStaticUpstream, + validFileUpstream, + }, }, errStrings: []string{}, }), Entry("with an empty ID", &validateUpstreamTableInput{ upstreams: options.Upstreams{ - { - ID: "", - Path: "/foo", - URI: "http://localhost:8080", + Configs: []options.Upstream{ + { + ID: "", + Path: "/foo", + URI: "http://localhost:8080", + }, }, }, errStrings: []string{emptyIDMsg}, }), Entry("with an empty Path", &validateUpstreamTableInput{ upstreams: options.Upstreams{ - { - ID: "foo", - Path: "", - URI: "http://localhost:8080", + Configs: []options.Upstream{ + { + ID: "foo", + Path: "", + URI: "http://localhost:8080", + }, }, }, errStrings: []string{emptyPathMsg}, }), Entry("with an empty Path", &validateUpstreamTableInput{ upstreams: options.Upstreams{ - { - ID: "foo", - Path: "", - URI: "http://localhost:8080", + Configs: []options.Upstream{ + { + ID: "foo", + Path: "", + URI: "http://localhost:8080", + }, }, }, errStrings: []string{emptyPathMsg}, }), Entry("with an empty URI", &validateUpstreamTableInput{ upstreams: options.Upstreams{ - { - ID: "foo", - Path: "/foo", - URI: "", + Configs: []options.Upstream{ + { + ID: "foo", + Path: "/foo", + URI: "", + }, }, }, errStrings: []string{emptyURIMsg}, }), Entry("with an invalid URI", &validateUpstreamTableInput{ upstreams: options.Upstreams{ - { - ID: "foo", - Path: "/foo", - URI: ":", + Configs: []options.Upstream{ + { + ID: "foo", + Path: "/foo", + URI: ":", + }, }, }, errStrings: []string{invalidURIMsg}, }), Entry("with an invalid URI scheme", &validateUpstreamTableInput{ upstreams: options.Upstreams{ - { - ID: "foo", - Path: "/foo", - URI: "ftp://foo", + Configs: []options.Upstream{ + { + ID: "foo", + Path: "/foo", + URI: "ftp://foo", + }, }, }, errStrings: []string{invalidURISchemeMsg}, }), Entry("with a static upstream and invalid optons", &validateUpstreamTableInput{ upstreams: options.Upstreams{ - { - ID: "foo", - Path: "/foo", - URI: "ftp://foo", - Static: true, - FlushInterval: &flushInterval, - PassHostHeader: &truth, - ProxyWebSockets: &truth, - InsecureSkipTLSVerify: true, + Configs: []options.Upstream{ + { + ID: "foo", + Path: "/foo", + URI: "ftp://foo", + Static: true, + FlushInterval: &flushInterval, + PassHostHeader: &truth, + ProxyWebSockets: &truth, + InsecureSkipTLSVerify: true, + }, }, }, errStrings: []string{ @@ -148,40 +164,46 @@ var _ = Describe("Upstreams", func() { }), Entry("with duplicate IDs", &validateUpstreamTableInput{ upstreams: options.Upstreams{ - { - ID: "foo", - Path: "/foo1", - URI: "http://foo", - }, - { - ID: "foo", - Path: "/foo2", - URI: "http://foo", + Configs: []options.Upstream{ + { + ID: "foo", + Path: "/foo1", + URI: "http://foo", + }, + { + ID: "foo", + Path: "/foo2", + URI: "http://foo", + }, }, }, errStrings: []string{multipleIDsMsg}, }), Entry("with duplicate Paths", &validateUpstreamTableInput{ upstreams: options.Upstreams{ - { - ID: "foo1", - Path: "/foo", - URI: "http://foo", - }, - { - ID: "foo2", - Path: "/foo", - URI: "http://foo", + Configs: []options.Upstream{ + { + ID: "foo1", + Path: "/foo", + URI: "http://foo", + }, + { + ID: "foo2", + Path: "/foo", + URI: "http://foo", + }, }, }, errStrings: []string{multiplePathsMsg}, }), Entry("when a static code is supplied without static", &validateUpstreamTableInput{ upstreams: options.Upstreams{ - { - ID: "foo", - Path: "/foo", - StaticCode: &staticCode200, + Configs: []options.Upstream{ + { + ID: "foo", + Path: "/foo", + StaticCode: &staticCode200, + }, }, }, errStrings: []string{emptyURIMsg, staticCodeMsg},