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

Commit 0f0f33d

Browse files
committed
Adds impersonation e2e test
Signed-off-by: JoshVanL <[email protected]>
1 parent 977dd5a commit 0f0f33d

File tree

5 files changed

+150
-25
lines changed

5 files changed

+150
-25
lines changed

test/e2e/framework/framework.go

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
package framework
33

44
import (
5+
"fmt"
6+
57
. "github.com/onsi/ginkgo"
68
. "github.com/onsi/gomega"
79

@@ -78,28 +80,46 @@ func (f *Framework) BeforeEach() {
7880
Expect(err).NotTo(HaveOccurred())
7981

8082
By("Deploying kube-oidc-proxy")
81-
proxyKeyBundle, proxyURL, err := f.helper.DeployProxy(f.Namespace, issuerURL, clientID, issuerKeyBundle)
83+
proxyKeyBundle, proxyURL, err := f.helper.DeployProxy(f.Namespace,
84+
issuerURL, clientID, issuerKeyBundle)
8285
Expect(err).NotTo(HaveOccurred())
8386

8487
f.issuerURL, f.proxyURL = issuerURL, proxyURL
8588
f.issuerKeyBundle, f.proxyKeyBundle = issuerKeyBundle, proxyKeyBundle
8689

8790
By("Creating Proxy Client")
88-
f.ProxyClient, err = f.NewProxyClient()
89-
Expect(err).NotTo(HaveOccurred())
91+
f.ProxyClient = f.NewProxyClient()
9092
}
9193

9294
// AfterEach deletes the namespace, after reading its events.
9395
func (f *Framework) AfterEach() {
96+
By("Deleting kube-oidc-proxy deployment")
97+
err := f.Helper().DeleteProxy(f.Namespace.Name)
98+
Expect(err).NotTo(HaveOccurred())
99+
100+
By("Deleting mock OIDC issuer")
101+
err = f.Helper().DeleteIssuer(f.Namespace.Name)
102+
Expect(err).NotTo(HaveOccurred())
103+
94104
By("Deleting test namespace")
95-
err := f.DeleteKubeNamespace(f.Namespace.Name)
105+
err = f.DeleteKubeNamespace(f.Namespace.Name)
96106
Expect(err).NotTo(HaveOccurred())
97107

98108
By("Waiting for test namespace to no longer exist")
99109
err = f.WaitForKubeNamespaceNotExist(f.Namespace.Name)
100110
Expect(err).NotTo(HaveOccurred())
101111
}
102112

113+
func (f *Framework) DeployProxyWith(extraArgs ...string) {
114+
By("Deleting kube-oidc-proxy deployment")
115+
err := f.Helper().DeleteProxy(f.Namespace.Name)
116+
117+
By(fmt.Sprintf("Deploying kube-oidc-proxy with extra args %s", extraArgs))
118+
f.proxyKeyBundle, f.proxyURL, err = f.helper.DeployProxy(f.Namespace, f.issuerURL,
119+
clientID, f.issuerKeyBundle, extraArgs...)
120+
Expect(err).NotTo(HaveOccurred())
121+
}
122+
103123
func (f *Framework) Helper() *helper.Helper {
104124
return f.helper
105125
}
@@ -116,23 +136,21 @@ func (f *Framework) ClientID() string {
116136
return clientID
117137
}
118138

119-
func (f *Framework) NewProxyRestConfig() (*rest.Config, error) {
120-
return f.Helper().NewValidRestConfig(f.issuerKeyBundle, f.proxyKeyBundle,
139+
func (f *Framework) NewProxyRestConfig() *rest.Config {
140+
config, err := f.Helper().NewValidRestConfig(f.issuerKeyBundle, f.proxyKeyBundle,
121141
f.issuerURL, f.proxyURL, clientID)
142+
Expect(err).NotTo(HaveOccurred())
143+
144+
return config
122145
}
123146

124-
func (f *Framework) NewProxyClient() (kubernetes.Interface, error) {
125-
proxyConfig, err := f.NewProxyRestConfig()
126-
if err != nil {
127-
return nil, err
128-
}
147+
func (f *Framework) NewProxyClient() kubernetes.Interface {
148+
proxyConfig := f.NewProxyRestConfig()
129149

130150
proxyClient, err := kubernetes.NewForConfig(proxyConfig)
131-
if err != nil {
132-
return nil, err
133-
}
151+
Expect(err).NotTo(HaveOccurred())
134152

135-
return proxyClient, nil
153+
return proxyClient
136154
}
137155

138156
func CasesDescribe(text string, body func()) bool {

test/e2e/framework/helper/deploy.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ const (
2020
ProxyName = "kube-oidc-proxy-e2e"
2121
)
2222

23-
func (h *Helper) DeployProxy(ns *corev1.Namespace, issuerURL, clientID string, oidcKeyBundle *util.KeyBundle) (*util.KeyBundle, string, error) {
23+
func (h *Helper) DeployProxy(ns *corev1.Namespace, issuerURL, clientID string,
24+
oidcKeyBundle *util.KeyBundle, extraArgs ...string) (*util.KeyBundle, string, error) {
2425
cnt := corev1.Container{
2526
Name: ProxyName,
2627
Image: ProxyName,
2728
ImagePullPolicy: corev1.PullNever,
28-
Args: []string{
29+
Args: append([]string{
2930
"kube-oidc-proxy",
3031
"--secure-port=6443",
3132
"--tls-cert-file=/tls/cert.pem",
@@ -37,7 +38,7 @@ func (h *Helper) DeployProxy(ns *corev1.Namespace, issuerURL, clientID string, o
3738
"--oidc-ca-file=/oidc/ca.pem",
3839
"--oidc-ca-file=/oidc/ca.pem",
3940
"--v=10",
40-
},
41+
}, extraArgs...),
4142
VolumeMounts: []corev1.VolumeMount{
4243
corev1.VolumeMount{
4344
MountPath: "/tls",
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package impersonation
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"io/ioutil"
7+
"net/http"
8+
9+
. "github.com/onsi/ginkgo"
10+
. "github.com/onsi/gomega"
11+
12+
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
13+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14+
"k8s.io/client-go/rest"
15+
16+
"github.com/jetstack/kube-oidc-proxy/test/e2e/framework"
17+
)
18+
19+
var _ = framework.CasesDescribe("Impersonation", func() {
20+
f := framework.NewDefaultFramework("impersonation")
21+
22+
It("should error at proxy when impersonation enabled and impersonation is attempted on a request", func() {
23+
By("Impersonating as a user")
24+
tryImpersonationClient(f, rest.ImpersonationConfig{
25+
UserName: "[email protected]",
26+
})
27+
28+
By("Impersonating as a group")
29+
tryImpersonationClient(f, rest.ImpersonationConfig{
30+
Groups: []string{
31+
"group-1",
32+
"group-2",
33+
},
34+
})
35+
36+
By("Impersonating as a extra")
37+
tryImpersonationClient(f, rest.ImpersonationConfig{
38+
Extra: map[string][]string{
39+
"foo": {
40+
"k1", "k2", "k3",
41+
},
42+
"bar": {
43+
"k1", "k2", "k3",
44+
},
45+
},
46+
})
47+
48+
By("Impersonating as a user, group and extra")
49+
tryImpersonationClient(f, rest.ImpersonationConfig{
50+
UserName: "[email protected]",
51+
Groups: []string{
52+
"group-1",
53+
"group-2",
54+
},
55+
Extra: map[string][]string{
56+
"foo": {
57+
"k1", "k2", "k3",
58+
},
59+
"bar": {
60+
"k1", "k2", "k3",
61+
},
62+
},
63+
})
64+
})
65+
66+
It("should not error at proxy when impersonation is disabled impersonation is attempted on a request", func() {
67+
f.DeployProxyWith("--disable-impersonation")
68+
69+
// Should return a normal RBAC forbidden from Kubernetes. If is not a
70+
// Kubernetes error then it came from the kube-oidc-proxy so error
71+
client := f.NewProxyClient()
72+
_, err := client.CoreV1().Pods(f.Namespace.Name).List(metav1.ListOptions{})
73+
if !k8sErrors.IsForbidden(err) {
74+
Expect(err).NotTo(HaveOccurred())
75+
}
76+
})
77+
})
78+
79+
func tryImpersonationClient(f *framework.Framework, impConfig rest.ImpersonationConfig) {
80+
config := f.NewProxyRestConfig()
81+
config.Impersonate = impConfig
82+
83+
tranConfig, err := config.TransportConfig()
84+
Expect(err).NotTo(HaveOccurred())
85+
86+
client := http.DefaultClient
87+
client.Transport = tranConfig.Transport
88+
89+
// send request with signed token to proxy
90+
target := fmt.Sprintf("%s/api/v1/namespaces/%s/pods",
91+
config.Host, f.Namespace.Name)
92+
93+
resp, err := client.Get(target)
94+
Expect(err).NotTo(HaveOccurred())
95+
96+
body, err := ioutil.ReadAll(resp.Body)
97+
Expect(err).NotTo(HaveOccurred())
98+
99+
expRespBody := []byte("Impersonation requests are disabled when using kube-oidc-proxy\n")
100+
101+
// check body and status code the token was rejected
102+
if resp.StatusCode != http.StatusForbidden ||
103+
!bytes.Equal(body, expRespBody) {
104+
}
105+
Expect(fmt.Errorf("expected status code %d with body %q, got= %d %q",
106+
http.StatusForbidden, expRespBody, resp.StatusCode, body)).NotTo(HaveOccurred())
107+
}

test/e2e/suite/cases/token/token.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,10 @@ var _ = framework.CasesDescribe("Token", func() {
4949
f.IssuerURL(), f.ClientID(), time.Now()))
5050

5151
By("Valid token should return Kubernetes forbidden")
52-
client, err := f.NewProxyClient()
53-
Expect(err).NotTo(HaveOccurred())
52+
client := f.NewProxyClient()
5453

5554
// if does not return with Kubernetes forbidden error then error
56-
_, err = client.CoreV1().Pods(f.Namespace.Name).List(metav1.ListOptions{})
55+
_, err := client.CoreV1().Pods(f.Namespace.Name).List(metav1.ListOptions{})
5756
if !k8sErrors.IsForbidden(err) {
5857
Expect(err).NotTo(HaveOccurred())
5958
}
@@ -65,9 +64,7 @@ func expectProxyUnauthorized(f *framework.Framework, tokenPayload []byte) {
6564
signedToken, err := f.Helper().SignToken(f.IssuerKeyBundle(), tokenPayload)
6665
Expect(err).NotTo(HaveOccurred())
6766

68-
proxyConfig, err := f.NewProxyRestConfig()
69-
Expect(err).NotTo(HaveOccurred())
70-
67+
proxyConfig := f.NewProxyRestConfig()
7168
client := http.DefaultClient
7269
client.Transport = &wraperRT{
7370
transport: proxyConfig.Transport,
@@ -89,5 +86,5 @@ func expectProxyUnauthorized(f *framework.Framework, tokenPayload []byte) {
8986
!bytes.Equal(body, []byte("Unauthorized")) {
9087
}
9188
Expect(fmt.Errorf("expected status code %d with body Unauthorized, got= %d %q",
92-
resp.StatusCode, body)).NotTo(HaveOccurred())
89+
http.StatusForbidden, resp.StatusCode, body)).NotTo(HaveOccurred())
9390
}

test/e2e/suite/suite.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package suite
22

33
import (
4+
"path/filepath"
5+
46
. "github.com/onsi/ginkgo"
57
log "github.com/sirupsen/logrus"
68

0 commit comments

Comments
 (0)