Convert CLI tests to work through an HTTP forward proxy.
This change deploys a small Squid-based proxy into the `dex` namespace in our integration test environment. This lets us use the cluster-local DNS name (`http://dex.dex.svc.cluster.local/dex`) as the OIDC issuer. It will make generating certificates easier, and most importantly it will mean that our CLI can see Dex at the same name/URL as the supervisor running inside the cluster. Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
parent
a4733025ce
commit
c8b17978a9
@ -286,7 +286,8 @@ export PINNIPED_TEST_SUPERVISOR_APP_NAME=${supervisor_app_name}
|
|||||||
export PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS='${supervisor_custom_labels}'
|
export PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS='${supervisor_custom_labels}'
|
||||||
export PINNIPED_TEST_SUPERVISOR_HTTP_ADDRESS="127.0.0.1:12345"
|
export PINNIPED_TEST_SUPERVISOR_HTTP_ADDRESS="127.0.0.1:12345"
|
||||||
export PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS="localhost:12344"
|
export PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS="localhost:12344"
|
||||||
export PINNIPED_TEST_CLI_OIDC_ISSUER=http://127.0.0.1:12346/dex
|
export PINNIPED_TEST_PROXY=http://127.0.0.1:12346
|
||||||
|
export PINNIPED_TEST_CLI_OIDC_ISSUER=http://dex.dex.svc.cluster.local/dex
|
||||||
export PINNIPED_TEST_CLI_OIDC_CLIENT_ID=pinniped-cli
|
export PINNIPED_TEST_CLI_OIDC_CLIENT_ID=pinniped-cli
|
||||||
export PINNIPED_TEST_CLI_OIDC_LOCALHOST_PORT=48095
|
export PINNIPED_TEST_CLI_OIDC_LOCALHOST_PORT=48095
|
||||||
export PINNIPED_TEST_CLI_OIDC_USERNAME=pinny@example.com
|
export PINNIPED_TEST_CLI_OIDC_USERNAME=pinny@example.com
|
||||||
|
@ -6,13 +6,13 @@
|
|||||||
#@ load("@ytt:yaml", "yaml")
|
#@ load("@ytt:yaml", "yaml")
|
||||||
|
|
||||||
#@ def dexConfig():
|
#@ def dexConfig():
|
||||||
issuer: #@ "http://127.0.0.1:" + str(data.values.ports.local) + "/dex"
|
issuer: http://dex.dex.svc.cluster.local/dex
|
||||||
storage:
|
storage:
|
||||||
type: sqlite3
|
type: sqlite3
|
||||||
config:
|
config:
|
||||||
file: ":memory:"
|
file: ":memory:"
|
||||||
web:
|
web:
|
||||||
http: 0.0.0.0:5556
|
http: 0.0.0.0:80
|
||||||
oauth2:
|
oauth2:
|
||||||
skipApprovalScreen: true
|
skipApprovalScreen: true
|
||||||
staticClients:
|
staticClients:
|
||||||
@ -77,7 +77,7 @@ spec:
|
|||||||
- /etc/dex/cfg/config.yaml
|
- /etc/dex/cfg/config.yaml
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
containerPort: 5556
|
containerPort: 80
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: config
|
- name: config
|
||||||
mountPath: /etc/dex/cfg
|
mountPath: /etc/dex/cfg
|
||||||
@ -94,9 +94,8 @@ metadata:
|
|||||||
labels:
|
labels:
|
||||||
app: dex
|
app: dex
|
||||||
spec:
|
spec:
|
||||||
type: NodePort
|
type: ClusterIP
|
||||||
selector:
|
selector:
|
||||||
app: dex
|
app: dex
|
||||||
ports:
|
ports:
|
||||||
- port: 5556
|
- port: 80
|
||||||
nodePort: #@ data.values.ports.node
|
|
||||||
|
58
test/deploy/dex/proxy.yaml
Normal file
58
test/deploy/dex/proxy.yaml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#! Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||||||
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#@ load("@ytt:data", "data")
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: proxy
|
||||||
|
namespace: dex
|
||||||
|
labels:
|
||||||
|
app: proxy
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: proxy
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: proxy
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: proxy
|
||||||
|
image: docker.io/getpinniped/test-forward-proxy
|
||||||
|
imagePullPolicy: Always
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 3128
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "10m"
|
||||||
|
memory: "64Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "10m"
|
||||||
|
memory: "64Mi"
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
failureThreshold: 2
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: proxy
|
||||||
|
namespace: dex
|
||||||
|
labels:
|
||||||
|
app: proxy
|
||||||
|
spec:
|
||||||
|
type: NodePort
|
||||||
|
selector:
|
||||||
|
app: proxy
|
||||||
|
ports:
|
||||||
|
- port: 3128
|
||||||
|
nodePort: #@ data.values.ports.node
|
@ -8,10 +8,10 @@ ports:
|
|||||||
#! Used in the Dex configuration to form the valid redirect URIs for our test client.
|
#! Used in the Dex configuration to form the valid redirect URIs for our test client.
|
||||||
cli: 48095
|
cli: 48095
|
||||||
|
|
||||||
#! Kubernetes NodePort that should be forwarded to the Dex service.
|
#! Kubernetes NodePort that should be forwarded to the proxy service.
|
||||||
#! Used to create a Service of type: NodePort
|
#! Used to create a Service of type: NodePort
|
||||||
node: 31235
|
node: 31235
|
||||||
|
|
||||||
#! External port where Dex ends up exposed on localhost during tests. This value comes from our
|
#! External port where the proxy ends up exposed on localhost during tests. This value comes from
|
||||||
#! Kind configuration which maps 127.0.0.1:12346 to port 31235 on the Kind worker node.
|
#! our Kind configuration which maps 127.0.0.1:12346 to port 31235 on the Kind worker node.
|
||||||
local: 12346
|
local: 12346
|
||||||
|
@ -130,8 +130,8 @@ func getLoginProvider(t *testing.T) *loginProviderPatterns {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Dex",
|
Name: "Dex",
|
||||||
IssuerPattern: regexp.MustCompile(`\Ahttp://127\.0\.0\.1.+/dex.*\z`),
|
IssuerPattern: regexp.MustCompile(`\Ahttp://dex\.dex\.svc\.cluster\.local/dex.*\z`),
|
||||||
LoginPagePattern: regexp.MustCompile(`\Ahttp://127\.0\.0\.1.+/dex/auth/local.+\z`),
|
LoginPagePattern: regexp.MustCompile(`\Ahttp://dex\.dex\.svc\.cluster\.local/dex/auth/local.+\z`),
|
||||||
UsernameSelector: "input#login",
|
UsernameSelector: "input#login",
|
||||||
PasswordSelector: "input#password",
|
PasswordSelector: "input#password",
|
||||||
LoginButtonSelector: "button#submit-login",
|
LoginButtonSelector: "button#submit-login",
|
||||||
@ -156,7 +156,18 @@ func TestCLILoginOIDC(t *testing.T) {
|
|||||||
|
|
||||||
// Start the browser driver.
|
// Start the browser driver.
|
||||||
t.Logf("opening browser driver")
|
t.Logf("opening browser driver")
|
||||||
|
caps := agouti.NewCapabilities()
|
||||||
|
if env.Proxy != "" {
|
||||||
|
t.Logf("configuring Chrome to use proxy %q", env.Proxy)
|
||||||
|
caps = caps.Proxy(agouti.ProxyConfig{
|
||||||
|
ProxyType: "manual",
|
||||||
|
HTTPProxy: env.Proxy,
|
||||||
|
SSLProxy: env.Proxy,
|
||||||
|
NoProxy: "127.0.0.1",
|
||||||
|
})
|
||||||
|
}
|
||||||
agoutiDriver := agouti.ChromeDriver(
|
agoutiDriver := agouti.ChromeDriver(
|
||||||
|
agouti.Desired(caps),
|
||||||
agouti.ChromeOptions("args", []string{
|
agouti.ChromeOptions("args", []string{
|
||||||
"--no-sandbox",
|
"--no-sandbox",
|
||||||
"--headless", // Comment out this line to see the tests happen in a visible browser window.
|
"--headless", // Comment out this line to see the tests happen in a visible browser window.
|
||||||
@ -395,11 +406,19 @@ func spawnTestGoroutine(t *testing.T, f func() error) {
|
|||||||
|
|
||||||
func oidcLoginCommand(ctx context.Context, t *testing.T, pinnipedExe string, sessionCachePath string) *exec.Cmd {
|
func oidcLoginCommand(ctx context.Context, t *testing.T, pinnipedExe string, sessionCachePath string) *exec.Cmd {
|
||||||
env := library.IntegrationEnv(t)
|
env := library.IntegrationEnv(t)
|
||||||
return exec.CommandContext(ctx, pinnipedExe, "login", "oidc",
|
cmd := exec.CommandContext(ctx, pinnipedExe, "login", "oidc",
|
||||||
"--issuer", env.OIDCUpstream.Issuer,
|
"--issuer", env.OIDCUpstream.Issuer,
|
||||||
"--client-id", env.OIDCUpstream.ClientID,
|
"--client-id", env.OIDCUpstream.ClientID,
|
||||||
"--listen-port", strconv.Itoa(env.OIDCUpstream.LocalhostPort),
|
"--listen-port", strconv.Itoa(env.OIDCUpstream.LocalhostPort),
|
||||||
"--session-cache", sessionCachePath,
|
"--session-cache", sessionCachePath,
|
||||||
"--skip-browser",
|
"--skip-browser",
|
||||||
)
|
)
|
||||||
|
if env.Proxy != "" {
|
||||||
|
cmd.Env = append(os.Environ(),
|
||||||
|
"http_proxy="+env.Proxy,
|
||||||
|
"https_proxy="+env.Proxy,
|
||||||
|
"no_proxy=127.0.0.1",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ type TestEnv struct {
|
|||||||
SupervisorHTTPSAddress string `json:"supervisorHttpsAddress"`
|
SupervisorHTTPSAddress string `json:"supervisorHttpsAddress"`
|
||||||
SupervisorHTTPSIngressAddress string `json:"supervisorHttpsIngressAddress"`
|
SupervisorHTTPSIngressAddress string `json:"supervisorHttpsIngressAddress"`
|
||||||
SupervisorHTTPSIngressCABundle string `json:"supervisorHttpsIngressCABundle"`
|
SupervisorHTTPSIngressCABundle string `json:"supervisorHttpsIngressCABundle"`
|
||||||
|
Proxy string `json:"proxy"`
|
||||||
|
|
||||||
TestUser struct {
|
TestUser struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
@ -126,6 +127,7 @@ func loadEnvVars(t *testing.T, result *TestEnv) {
|
|||||||
require.NoErrorf(t, err, "PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS must be a YAML map of string to string")
|
require.NoErrorf(t, err, "PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS must be a YAML map of string to string")
|
||||||
result.SupervisorCustomLabels = supervisorCustomLabels
|
result.SupervisorCustomLabels = supervisorCustomLabels
|
||||||
require.NotEmpty(t, result.SupervisorCustomLabels, "PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS cannot be empty")
|
require.NotEmpty(t, result.SupervisorCustomLabels, "PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS cannot be empty")
|
||||||
|
result.Proxy = os.Getenv("PINNIPED_TEST_PROXY")
|
||||||
|
|
||||||
result.OIDCUpstream.Issuer = needEnv(t, "PINNIPED_TEST_CLI_OIDC_ISSUER")
|
result.OIDCUpstream.Issuer = needEnv(t, "PINNIPED_TEST_CLI_OIDC_ISSUER")
|
||||||
result.OIDCUpstream.ClientID = needEnv(t, "PINNIPED_TEST_CLI_OIDC_CLIENT_ID")
|
result.OIDCUpstream.ClientID = needEnv(t, "PINNIPED_TEST_CLI_OIDC_CLIENT_ID")
|
||||||
|
Loading…
Reference in New Issue
Block a user