@@ -0,0 +1,191 @@
1+package validation
2+
3+import (
4+ "time"
5+
6+ "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options"
7+ . "github.com/onsi/ginkgo"
8+ . "github.com/onsi/ginkgo/extensions/table"
9+ . "github.com/onsi/gomega"
10+)
11+
12+var _ = Describe("Upstreams", func() {
13+ type validateUpstreamTableInput struct {
14+ upstreams options.Upstreams
15+ errStrings []string
16+ }
17+
18+ flushInterval := 5 * time.Second
19+ staticCode200 := 200
20+
21+ validHTTPUpstream := options.Upstream{
22+ ID: "validHTTPUpstream",
23+ Path: "/validHTTPUpstream",
24+ URI: "http://localhost:8080",
25+ }
26+ validStaticUpstream := options.Upstream{
27+ ID: "validStaticUpstream",
28+ Path: "/validStaticUpstream",
29+ Static: true,
30+ PassHostHeader: true, // This would normally be defaulted
31+ ProxyWebSockets: true, // this would normally be defaulted
32+ }
33+ validFileUpstream := options.Upstream{
34+ ID: "validFileUpstream",
35+ Path: "/validFileUpstream",
36+ URI: "file://var/lib/foo",
37+ }
38+
39+ emptyIDMsg := "upstream has empty id: ids are required for all upstreams"
40+ emptyPathMsg := "upstream \"foo\" has empty path: paths are required for all upstreams"
41+ emptyURIMsg := "upstream \"foo\" has empty uri: uris are required for all non-static upstreams"
42+ invalidURIMsg := "upstream \"foo\" has invalid uri: parse \":\": missing protocol scheme"
43+ invalidURISchemeMsg := "upstream \"foo\" has invalid scheme: \"ftp\""
44+ staticWithURIMsg := "upstream \"foo\" has uri, but is a static upstream, this will have no effect."
45+ staticWithInsecureMsg := "upstream \"foo\" has insecureSkipTLSVerify, but is a static upstream, this will have no effect."
46+ staticWithFlushIntervalMsg := "upstream \"foo\" has flushInterval, but is a static upstream, this will have no effect."
47+ staticWithPassHostHeaderMsg := "upstream \"foo\" has passHostHeader, but is a static upstream, this will have no effect."
48+ staticWithProxyWebSocketsMsg := "upstream \"foo\" has proxyWebSockets, but is a static upstream, this will have no effect."
49+ multipleIDsMsg := "multiple upstreams found with id \"foo\": upstream ids must be unique"
50+ multiplePathsMsg := "multiple upstreams found with path \"/foo\": upstream paths must be unique"
51+ staticCodeMsg := "upstream \"foo\" has staticCode (200), but is not a static upstream, set 'static' for a static response"
52+
53+ DescribeTable("validateUpstreams",
54+ func(o *validateUpstreamTableInput) {
55+ Expect(validateUpstreams(o.upstreams)).To(ConsistOf(o.errStrings))
56+ },
57+ Entry("with no upstreams", &validateUpstreamTableInput{
58+ upstreams: options.Upstreams{},
59+ errStrings: []string{},
60+ }),
61+ Entry("with valid upstreams", &validateUpstreamTableInput{
62+ upstreams: options.Upstreams{
63+ validHTTPUpstream,
64+ validStaticUpstream,
65+ validFileUpstream,
66+ },
67+ errStrings: []string{},
68+ }),
69+ Entry("with an empty ID", &validateUpstreamTableInput{
70+ upstreams: options.Upstreams{
71+ {
72+ ID: "",
73+ Path: "/foo",
74+ URI: "http://localhost:8080",
75+ },
76+ },
77+ errStrings: []string{emptyIDMsg},
78+ }),
79+ Entry("with an empty Path", &validateUpstreamTableInput{
80+ upstreams: options.Upstreams{
81+ {
82+ ID: "foo",
83+ Path: "",
84+ URI: "http://localhost:8080",
85+ },
86+ },
87+ errStrings: []string{emptyPathMsg},
88+ }),
89+ Entry("with an empty Path", &validateUpstreamTableInput{
90+ upstreams: options.Upstreams{
91+ {
92+ ID: "foo",
93+ Path: "",
94+ URI: "http://localhost:8080",
95+ },
96+ },
97+ errStrings: []string{emptyPathMsg},
98+ }),
99+ Entry("with an empty URI", &validateUpstreamTableInput{
100+ upstreams: options.Upstreams{
101+ {
102+ ID: "foo",
103+ Path: "/foo",
104+ URI: "",
105+ },
106+ },
107+ errStrings: []string{emptyURIMsg},
108+ }),
109+ Entry("with an invalid URI", &validateUpstreamTableInput{
110+ upstreams: options.Upstreams{
111+ {
112+ ID: "foo",
113+ Path: "/foo",
114+ URI: ":",
115+ },
116+ },
117+ errStrings: []string{invalidURIMsg},
118+ }),
119+ Entry("with an invalid URI scheme", &validateUpstreamTableInput{
120+ upstreams: options.Upstreams{
121+ {
122+ ID: "foo",
123+ Path: "/foo",
124+ URI: "ftp://foo",
125+ },
126+ },
127+ errStrings: []string{invalidURISchemeMsg},
128+ }),
129+ Entry("with a static upstream and invalid optons", &validateUpstreamTableInput{
130+ upstreams: options.Upstreams{
131+ {
132+ ID: "foo",
133+ Path: "/foo",
134+ URI: "ftp://foo",
135+ Static: true,
136+ FlushInterval: &flushInterval,
137+ PassHostHeader: false,
138+ ProxyWebSockets: false,
139+ InsecureSkipTLSVerify: true,
140+ },
141+ },
142+ errStrings: []string{
143+ staticWithURIMsg,
144+ staticWithInsecureMsg,
145+ staticWithFlushIntervalMsg,
146+ staticWithPassHostHeaderMsg,
147+ staticWithProxyWebSocketsMsg,
148+ },
149+ }),
150+ Entry("with duplicate IDs", &validateUpstreamTableInput{
151+ upstreams: options.Upstreams{
152+ {
153+ ID: "foo",
154+ Path: "/foo1",
155+ URI: "http://foo",
156+ },
157+ {
158+ ID: "foo",
159+ Path: "/foo2",
160+ URI: "http://foo",
161+ },
162+ },
163+ errStrings: []string{multipleIDsMsg},
164+ }),
165+ Entry("with duplicate Paths", &validateUpstreamTableInput{
166+ upstreams: options.Upstreams{
167+ {
168+ ID: "foo1",
169+ Path: "/foo",
170+ URI: "http://foo",
171+ },
172+ {
173+ ID: "foo2",
174+ Path: "/foo",
175+ URI: "http://foo",
176+ },
177+ },
178+ errStrings: []string{multiplePathsMsg},
179+ }),
180+ Entry("when a static code is supplied without static", &validateUpstreamTableInput{
181+ upstreams: options.Upstreams{
182+ {
183+ ID: "foo",
184+ Path: "/foo",
185+ StaticCode: &staticCode200,
186+ },
187+ },
188+ errStrings: []string{emptyURIMsg, staticCodeMsg},
189+ }),
190+ )
191+})