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

Commit 03147a7

Browse files
committed
Creates unit test for readiness probe
Signed-off-by: JoshVanL <[email protected]>
1 parent 77c5c69 commit 03147a7

File tree

6 files changed

+75
-36
lines changed

6 files changed

+75
-36
lines changed

cmd/app/options/kube_oidc_proxy.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ type TokenPassthroughOptions struct {
1313
type KubeOIDCProxyOptions struct {
1414
DisableImpersonation bool
1515
TokenPassthrough TokenPassthroughOptions
16+
17+
ReadinessProbePort int
1618
}
1719

1820
func (t *TokenPassthroughOptions) AddFlags(fs *pflag.FlagSet) {
@@ -34,5 +36,8 @@ func (k *KubeOIDCProxyOptions) AddFlags(fs *pflag.FlagSet) {
3436
"(Alpha) Disable the impersonation of authenticated requests. All "+
3537
"authenticated requests will be forwarded as is.")
3638

39+
fs.IntVarP(&k.ReadinessProbePort, "readiness-probe-port", "P", 8080,
40+
"Port to expose readiness probe.")
41+
3742
k.TokenPassthrough.AddFlags(fs)
3843
}

cmd/app/run.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
)
2525

2626
const (
27-
readinessProbePort = 8080
27+
appName = "kube-oidc-proxy"
2828
)
2929

3030
func NewRunCommand(stopCh <-chan struct{}) *cobra.Command {
@@ -36,7 +36,7 @@ func NewRunCommand(stopCh <-chan struct{}) *cobra.Command {
3636
BindPort: 6443,
3737
Required: true,
3838
ServerCert: apiserveroptions.GeneratableKeyCert{
39-
PairName: "kube-oidc-proxy",
39+
PairName: appName,
4040
CertDirectory: "/var/run/kubernetes",
4141
},
4242
}
@@ -48,7 +48,7 @@ func NewRunCommand(stopCh <-chan struct{}) *cobra.Command {
4848

4949
// proxy command
5050
cmd := &cobra.Command{
51-
Use: "kube-oidc-proxy",
51+
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 {
5454
var err error
@@ -61,7 +61,7 @@ func NewRunCommand(stopCh <-chan struct{}) *cobra.Command {
6161
return err
6262
}
6363

64-
if ssoptionsWithLB.SecureServingOptions.BindPort == readinessProbePort {
64+
if ssoptionsWithLB.SecureServingOptions.BindPort == kopOptions.ReadinessProbePort {
6565
return errors.New("unable to securely serve on port 8080, used by readiness prob")
6666
}
6767

@@ -116,8 +116,8 @@ func NewRunCommand(stopCh <-chan struct{}) *cobra.Command {
116116
}
117117

118118
// Start readiness probe
119-
if err := probe.Run(strconv.Itoa(readinessProbePort),
120-
fakeJWT, p.OIDCAuthenticator()); err != nil {
119+
if err := probe.Run(strconv.Itoa(kopOptions.ReadinessProbePort),
120+
fakeJWT, p.OIDCTokenAuthenticator()); err != nil {
121121
return err
122122
}
123123

pkg/probe/probe.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,33 @@
22
package probe
33

44
import (
5+
"context"
56
"fmt"
67
"net"
78
"net/http"
89
"strings"
910
"time"
1011

1112
"github.com/heptiolabs/healthcheck"
12-
"k8s.io/apiserver/pkg/authentication/request/bearertoken"
13+
"k8s.io/apiserver/pkg/authentication/authenticator"
14+
//"k8s.io/apiserver/pkg/authentication/request/bearertoken"
1315
"k8s.io/klog"
1416
)
1517

1618
type HealthCheck struct {
1719
handler healthcheck.Handler
1820

19-
oidcAuther *bearertoken.Authenticator
20-
req *http.Request
21+
oidcAuther authenticator.Token
22+
fakeJWT string
2123

2224
ready bool
2325
}
2426

25-
func Run(port, fakeJWT string, oidcAuther *bearertoken.Authenticator) error {
26-
req, err := http.NewRequest("GET", "http://fake", nil)
27-
if err != nil {
28-
return fmt.Errorf("failed to build fake probe request: %s", err)
29-
}
30-
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", fakeJWT))
31-
27+
func Run(port, fakeJWT string, oidcAuther authenticator.Token) error {
3228
h := &HealthCheck{
3329
handler: healthcheck.NewHandler(),
3430
oidcAuther: oidcAuther,
35-
req: req,
31+
fakeJWT: fakeJWT,
3632
}
3733

3834
h.handler.AddReadinessCheck("secure serving", h.Check)
@@ -55,7 +51,7 @@ func (h *HealthCheck) Check() error {
5551
return nil
5652
}
5753

58-
_, _, err := h.oidcAuther.AuthenticateRequest(h.req)
54+
_, _, err := h.oidcAuther.AuthenticateToken(context.Background(), h.fakeJWT)
5955
if err != nil && strings.HasSuffix(err.Error(), "authenticator not initialized") {
6056
err = fmt.Errorf("OIDC provider not yet initialized: %s", err)
6157
klog.V(4).Infof(err.Error())

pkg/probe/probe_test.go

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,55 @@
22
package probe
33

44
import (
5+
"context"
6+
"errors"
57
"fmt"
68
"net/http"
79
"testing"
810
"time"
911

12+
"k8s.io/apiserver/pkg/authentication/authenticator"
13+
1014
"github.com/jetstack/kube-oidc-proxy/pkg/util"
1115
)
1216

13-
func Test_Check(t *testing.T) {
17+
type fakeTokenAuthenticator struct {
18+
returnErr bool
19+
}
20+
21+
var _ authenticator.Token = &fakeTokenAuthenticator{}
22+
23+
func (f *fakeTokenAuthenticator) AuthenticateToken(context.Context, string) (*authenticator.Response, bool, error) {
24+
if f.returnErr {
25+
return nil, false, errors.New("foo bar authenticator not initialized")
26+
}
27+
28+
return nil, false, errors.New("some other error")
29+
}
30+
31+
func TestRun(t *testing.T) {
32+
f := &fakeTokenAuthenticator{
33+
returnErr: true,
34+
}
35+
1436
port, err := util.FreePort()
1537
if err != nil {
16-
t.Fatalf("unexpected error: %s", err)
38+
t.Error(err.Error())
39+
t.FailNow()
1740
}
1841

19-
p := New(port)
42+
fakeJWT, err := util.FakeJWT("issuer", nil)
43+
if err != nil {
44+
t.Error(err.Error())
45+
t.FailNow()
46+
}
47+
48+
if err := Run(port, fakeJWT, f); err != nil {
49+
t.Error(err.Error())
50+
t.FailNow()
51+
}
52+
53+
// Wait for probe to become ready
2054
time.Sleep(time.Second)
2155

2256
url := fmt.Sprintf("http://0.0.0.0:%s", port)
@@ -31,7 +65,7 @@ func Test_Check(t *testing.T) {
3165
503, resp.StatusCode)
3266
}
3367

34-
p.SetReady()
68+
f.returnErr = false
3569

3670
resp, err = http.Get(url + "/ready")
3771
if err != nil {
@@ -43,15 +77,18 @@ func Test_Check(t *testing.T) {
4377
200, resp.StatusCode)
4478
}
4579

46-
p.SetNotReady()
80+
// Once the authenticator has returned with an non-initialised error, then
81+
// should always return ready
82+
83+
f.returnErr = true
4784

4885
resp, err = http.Get(url + "/ready")
4986
if err != nil {
5087
t.Fatalf("unexpected error: %s", err)
5188
}
5289

53-
if resp.StatusCode != 503 {
54-
t.Errorf("expected ready probe to be responding and not ready, exp=%d got=%d",
55-
503, resp.StatusCode)
90+
if resp.StatusCode != 200 {
91+
t.Errorf("expected ready probe to be responding and ready, exp=%d got=%d",
92+
200, resp.StatusCode)
5693
}
5794
}

pkg/proxy/proxy.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"time"
1212

1313
utilnet "k8s.io/apimachinery/pkg/util/net"
14+
"k8s.io/apiserver/pkg/authentication/authenticator"
1415
"k8s.io/apiserver/pkg/authentication/request/bearertoken"
1516
authuser "k8s.io/apiserver/pkg/authentication/user"
1617
"k8s.io/apiserver/pkg/server"
@@ -40,7 +41,8 @@ type Options struct {
4041
}
4142

4243
type Proxy struct {
43-
oidcAuther *bearertoken.Authenticator
44+
oidcRequestAuther *bearertoken.Authenticator
45+
tokenAuther authenticator.Token
4446
tokenReviewer *tokenreview.TokenReview
4547
secureServingInfo *server.SecureServingInfo
4648

@@ -72,14 +74,13 @@ func New(restConfig *rest.Config, oidcOptions *options.OIDCAuthenticationOptions
7274
return nil, err
7375
}
7476

75-
oidcAuther := bearertoken.New(tokenAuther)
76-
7777
return &Proxy{
7878
restConfig: restConfig,
7979
tokenReviewer: tokenReviewer,
8080
secureServingInfo: ssinfo,
8181
options: options,
82-
oidcAuther: oidcAuther,
82+
oidcRequestAuther: bearertoken.New(tokenAuther),
83+
tokenAuther: tokenAuther,
8384
}, nil
8485
}
8586

@@ -144,7 +145,7 @@ func (p *Proxy) RoundTrip(req *http.Request) (*http.Response, error) {
144145
reqCpy := utilnet.CloneRequest(req)
145146

146147
// auth request and handle unauthed
147-
info, ok, err := p.oidcAuther.AuthenticateRequest(reqCpy)
148+
info, ok, err := p.oidcRequestAuther.AuthenticateRequest(reqCpy)
148149
if err != nil {
149150

150151
// attempt to passthrough request if valid token
@@ -306,6 +307,6 @@ func (p *Proxy) roundTripperForRestConfig(config *rest.Config) (http.RoundTrippe
306307
}
307308

308309
// Return the proxy OIDC token authenticator
309-
func (p *Proxy) OIDCAuthenticator() *bearertoken.Authenticator {
310-
return p.oidcAuther
310+
func (p *Proxy) OIDCTokenAuthenticator() authenticator.Token {
311+
return p.tokenAuther
311312
}

pkg/proxy/proxy_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,9 @@ func newTestProxy(t *testing.T) *fakeProxy {
257257
fakeToken: fakeToken,
258258
fakeRT: fakeRT,
259259
Proxy: &Proxy{
260-
oidcAuther: bearertoken.New(fakeToken),
261-
clientTransport: fakeRT,
262-
options: new(Options),
260+
oidcRequestAuther: bearertoken.New(fakeToken),
261+
clientTransport: fakeRT,
262+
options: new(Options),
263263
},
264264
}
265265
}

0 commit comments

Comments
 (0)