Use gorilla websocket library so squid proxy works
This commit is contained in:
parent
006dc8aa79
commit
24396b6af1
1
go.mod
1
go.mod
@ -15,6 +15,7 @@ require (
|
|||||||
github.com/google/go-cmp v0.5.5
|
github.com/google/go-cmp v0.5.5
|
||||||
github.com/google/gofuzz v1.2.0
|
github.com/google/gofuzz v1.2.0
|
||||||
github.com/gorilla/securecookie v1.1.1
|
github.com/gorilla/securecookie v1.1.1
|
||||||
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
github.com/oleiade/reflections v1.0.1 // indirect
|
github.com/oleiade/reflections v1.0.1 // indirect
|
||||||
github.com/onsi/ginkgo v1.13.0 // indirect
|
github.com/onsi/ginkgo v1.13.0 // indirect
|
||||||
github.com/ory/fosite v0.38.0
|
github.com/ory/fosite v0.38.0
|
||||||
|
@ -6,7 +6,6 @@ package integration
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -22,8 +21,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/net/websocket"
|
|
||||||
v1 "k8s.io/api/authorization/v1"
|
v1 "k8s.io/api/authorization/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
rbacv1 "k8s.io/api/rbac/v1"
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
@ -558,30 +558,44 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("websocket client", func(t *testing.T) {
|
t.Run("websocket client", func(t *testing.T) {
|
||||||
|
library.CreateTestClusterRoleBinding(t,
|
||||||
|
rbacv1.Subject{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: env.TestUser.ExpectedUsername},
|
||||||
|
rbacv1.RoleRef{Kind: "ClusterRole", APIGroup: rbacv1.GroupName, Name: "cluster-admin"},
|
||||||
|
)
|
||||||
|
// Wait for the above RBAC rule to take effect.
|
||||||
|
library.WaitForUserToHaveAccess(t, env.TestUser.ExpectedUsername, []string{}, &v1.ResourceAttributes{
|
||||||
|
Namespace: namespace.Name, Verb: "create", Group: "", Version: "v1", Resource: "configmaps",
|
||||||
|
})
|
||||||
|
|
||||||
|
impersonationRestConfig := impersonationProxyRestConfig(refreshCredential(), impersonationProxyURL, impersonationProxyCACertPEM, "")
|
||||||
|
tlsConfig, err := rest.TLSConfigFor(impersonationRestConfig)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
dest, _ := url.Parse(impersonationProxyURL)
|
dest, _ := url.Parse(impersonationProxyURL)
|
||||||
dest.Scheme = "wss"
|
dest.Scheme = "wss"
|
||||||
dest.Path = "/api/v1/namespaces/" + namespace.Name + "/configmaps"
|
dest.Path = "/api/v1/namespaces/" + namespace.Name + "/configmaps"
|
||||||
dest.RawQuery = "watch=1&resourceVersion=0"
|
dest.RawQuery = "watch=1&resourceVersion=0"
|
||||||
origin, _ := url.Parse("http://localhost")
|
|
||||||
|
|
||||||
rootCAs := x509.NewCertPool()
|
dialer := websocket.Dialer{
|
||||||
rootCAs.AppendCertsFromPEM(impersonationProxyCACertPEM)
|
TLSClientConfig: tlsConfig,
|
||||||
tlsConfig := &tls.Config{
|
|
||||||
MinVersion: tls.VersionTLS12,
|
|
||||||
RootCAs: rootCAs,
|
|
||||||
}
|
}
|
||||||
|
if !env.HasCapability(library.HasExternalLoadBalancerProvider) {
|
||||||
websocketConfig := websocket.Config{
|
dialer.Proxy = func(req *http.Request) (*url.URL, error) {
|
||||||
Location: dest,
|
proxyURL, err := url.Parse(env.Proxy)
|
||||||
Origin: origin,
|
require.NoError(t, err)
|
||||||
TlsConfig: tlsConfig,
|
t.Logf("passing request for %s through proxy %s", req.URL, proxyURL.String())
|
||||||
Version: 13,
|
return proxyURL, nil
|
||||||
Header: http.Header(make(map[string][]string)),
|
}
|
||||||
}
|
}
|
||||||
ws, err := websocket.DialConfig(&websocketConfig)
|
c, r, err := dialer.Dial(dest.String(), nil)
|
||||||
if err != nil {
|
if r != nil {
|
||||||
t.Fatalf("failed to dial websocket: %v", err)
|
defer r.Body.Close()
|
||||||
}
|
}
|
||||||
|
if err != nil && r != nil {
|
||||||
|
body, _ := ioutil.ReadAll(r.Body)
|
||||||
|
t.Logf("websocket dial failed: %d:%s", r.StatusCode, body)
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
// perform a create through the admin client
|
// perform a create through the admin client
|
||||||
_, err = adminClient.CoreV1().ConfigMaps(namespace.Name).Create(ctx,
|
_, err = adminClient.CoreV1().ConfigMaps(namespace.Name).Create(ctx,
|
||||||
@ -589,17 +603,22 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
|
|||||||
metav1.CreateOptions{},
|
metav1.CreateOptions{},
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
t.Cleanup(func() {
|
||||||
|
err = adminClient.CoreV1().ConfigMaps(namespace.Name).DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
// see if the websocket client received an event for the create
|
// see if the websocket client received an event for the create
|
||||||
var got watchJSON
|
_, message, err := c.ReadMessage()
|
||||||
err = websocket.JSON.Receive(ws, &got)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
var got watchJSON
|
||||||
|
err = json.Unmarshal(message, &got)
|
||||||
|
require.NoError(t, err)
|
||||||
if got.Type != watch.Added {
|
if got.Type != watch.Added {
|
||||||
t.Errorf("Unexpected type: %v", got.Type)
|
t.Errorf("Unexpected type: %v", got.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
var createConfigMap corev1.ConfigMap
|
var createConfigMap corev1.ConfigMap
|
||||||
err = json.Unmarshal(got.Object, &createConfigMap)
|
err = json.Unmarshal(got.Object, &createConfigMap)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
Loading…
Reference in New Issue
Block a user