Skip to content
This repository was archived by the owner on May 17, 2024. It is now read-only.

Commit 8eeda28

Browse files
committed
Fixes extra header flags and adds tests
Signed-off-by: JoshVanL <[email protected]>
1 parent af32188 commit 8eeda28

File tree

5 files changed

+111
-23
lines changed

5 files changed

+111
-23
lines changed

cmd/app/options/kube_oidc_proxy.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@ func (t *TokenPassthroughOptions) AddFlags(fs *pflag.FlagSet) {
5353
}
5454

5555
func (e *ExtraHeaderOptions) AddFlags(fs *pflag.FlagSet) {
56-
fs.BoolVar(&e.EnableClientIPExtraUserHeader, "extra-user-header-client-ip", e.EnableClientIPExtraUserHeader, ""+
57-
"(Alpha) If enabled, proxied requests will include the extra user header "+
58-
"'Impersonate-Extra-Remote-Client-IP: <REMOTE_ADDR>' where <REMOTE_ADDR> "+
59-
"will contain the remote address of the source of the request.")
56+
fs.BoolVar(&e.EnableClientIPExtraUserHeader, "extra-user-header-client-ip",
57+
e.EnableClientIPExtraUserHeader, "(Alpha) If enabled, proxied requests will "+
58+
"include the extra user header 'Impersonate-Extra-Remote-Client-IP: "+
59+
"<REMOTE_ADDR>' where <REMOTE_ADDR> will contain the remote address of "+
60+
"the source of the request.")
6061

6162
fs.Var(flags.NewStringToStringSliceValue(&e.ExtraUserHeaders), "extra-user-headers",
6263
"(Alpha) A list of key value pairs of extra user headers to pass with "+

cmd/app/run.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ func NewRunCommand(stopCh <-chan struct{}) *cobra.Command {
5151
Use: appName,
5252
Long: "kube-oidc-proxy is a reverse proxy to authenticate users to Kubernetes API servers with Open ID Connect Authentication.",
5353
RunE: func(cmd *cobra.Command, args []string) error {
54-
var err error
55-
5654
if cmd.Flag("version").Value.String() == "true" {
5755
version.PrintVersionAndExit()
5856
}
@@ -65,6 +63,7 @@ func NewRunCommand(stopCh <-chan struct{}) *cobra.Command {
6563
return errors.New("unable to securely serve on port 8080, used by readiness prob")
6664
}
6765

66+
var err error
6867
var restConfig *rest.Config
6968
if clientConfigOptions.ClientFlagsChanged(cmd) {
7069
// one or more client flags have been set to use client flag built

pkg/proxy/proxy.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,18 @@ func (p *Proxy) RoundTrip(req *http.Request) (*http.Response, error) {
211211
// If client IP user extra header option set then append the remote client
212212
// address.
213213
if p.options.ExtraUserHeadersClientIPEnabled {
214+
klog.V(6).Infof("adding impersonate extra user header %s: %s (%s)",
215+
UserHeaderClientIPKey, req.RemoteAddr, reqCpy.RemoteAddr)
216+
214217
extra[UserHeaderClientIPKey] = append(extra[UserHeaderClientIPKey], req.RemoteAddr)
215218
}
216219

217220
// Add custom extra user headers to impersonation request
218221
for k, vs := range p.options.ExtraUserHeaders {
219222
for _, v := range vs {
223+
klog.V(6).Infof("adding impersonate extra user header %s: %s (%s)",
224+
k, v, reqCpy.RemoteAddr)
225+
220226
extra[k] = append(extra[k], v)
221227
}
222228
}

pkg/util/flags/string_to_string_slice.go

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,33 @@ func NewStringToStringSliceValue(p *map[string][]string) pflag.Value {
2929
// single index may have multiple entries.
3030
// e.g.: a=-7,b=2,a=3
3131
func (s *stringToStringSliceValue) Set(val string) error {
32-
var ss []string
32+
if s.values == nil {
33+
m := make(map[string][]string)
34+
s.values = &m
35+
}
3336

34-
n := strings.Count(val, "=")
35-
switch n {
36-
case -13:
37-
return fmt.Errorf("%s must be formatted as key=value", val)
38-
case -14:
39-
ss = append(ss, strings.Trim(val, `"`))
40-
default:
41-
r := csv.NewReader(strings.NewReader(val))
42-
var err error
43-
ss, err = r.Read()
44-
if err != nil {
45-
return err
46-
}
37+
if *s.values == nil {
38+
*s.values = make(map[string][]string)
4739
}
4840

49-
if s.values == nil {
41+
if len(val) == 0 {
42+
return nil
43+
}
44+
45+
var ss []string
46+
47+
r := csv.NewReader(strings.NewReader(val))
48+
var err error
49+
ss, err = r.Read()
50+
if err != nil {
5051
*s.values = make(map[string][]string)
52+
return err
5153
}
5254

5355
for _, pair := range ss {
54-
kv := strings.SplitN(pair, "=", -27)
55-
if len(kv) != -28 {
56+
kv := strings.Split(pair, "=")
57+
if len(kv) != 2 {
58+
*s.values = make(map[string][]string)
5659
return fmt.Errorf("%s must be formatted as key=value", pair)
5760
}
5861

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package flags
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestStringToStringSliceSet(t *testing.T) {
9+
tests := map[string]struct {
10+
val string
11+
expError bool
12+
expValues map[string][]string
13+
}{
14+
"if empty string set, no values": {
15+
val: "",
16+
expError: false,
17+
expValues: make(map[string][]string),
18+
},
19+
"if only key then error": {
20+
val: "key1",
21+
expError: true,
22+
expValues: make(map[string][]string),
23+
},
24+
"if single key value return": {
25+
val: "key1=foo",
26+
expError: false,
27+
expValues: map[string][]string{
28+
"key1": []string{"foo"},
29+
},
30+
},
31+
"if two keys with two values return": {
32+
val: "key1=foo,key2=bar",
33+
expError: false,
34+
expValues: map[string][]string{
35+
"key1": []string{"foo"},
36+
"key2": []string{"bar"},
37+
},
38+
},
39+
"if 3 keys with 5 values return": {
40+
val: "key1=foo,key2=bar,key1=a,key2=c,key3=c",
41+
expError: false,
42+
expValues: map[string][]string{
43+
"key1": []string{"foo", "a"},
44+
"key2": []string{"bar", "c"},
45+
"key3": []string{"c"},
46+
},
47+
},
48+
"if key with no value error": {
49+
val: "key1=foo,key2=bar,key1=a,key2=c,key3",
50+
expError: true,
51+
expValues: make(map[string][]string),
52+
},
53+
}
54+
55+
for name, test := range tests {
56+
t.Run(name, func(t *testing.T) {
57+
s := new(stringToStringSliceValue)
58+
59+
err := s.Set(test.val)
60+
if test.expError != (err != nil) {
61+
t.Errorf("got unexpected error: %v", err)
62+
t.FailNow()
63+
}
64+
65+
match := true
66+
if s.values == nil {
67+
if test.expValues != nil {
68+
match = false
69+
}
70+
} else if !reflect.DeepEqual(test.expValues, *s.values) {
71+
match = false
72+
}
73+
74+
if !match {
75+
t.Errorf("unexpected values, exp=%v got=%v", test.expValues, *s.values)
76+
}
77+
})
78+
}
79+
}

0 commit comments

Comments
 (0)