Fix bad test package name

Signed-off-by: Monis Khan <mok@vmware.com>
This commit is contained in:
Monis Khan 2021-06-22 11:23:19 -04:00
parent 1929b47dda
commit d78b845575
No known key found for this signature in database
GPG Key ID: 52C90ADA01B269B8
36 changed files with 336 additions and 336 deletions

View File

@ -16,13 +16,13 @@ import (
"go.pinniped.dev/internal/controllerlib/test/integration/examplecontroller/api" "go.pinniped.dev/internal/controllerlib/test/integration/examplecontroller/api"
examplestart "go.pinniped.dev/internal/controllerlib/test/integration/examplecontroller/starter" examplestart "go.pinniped.dev/internal/controllerlib/test/integration/examplecontroller/starter"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestExampleController(t *testing.T) { func TestExampleController(t *testing.T) {
library.SkipUnlessIntegration(t) testlib.SkipUnlessIntegration(t)
config := library.NewClientConfig(t) config := testlib.NewClientConfig(t)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
@ -93,7 +93,7 @@ done:
expectedData := map[string][]byte{ expectedData := map[string][]byte{
api.SecretDataKey: []byte(secretData), api.SecretDataKey: []byte(secretData),
} }
require.Equal(t, expectedData, secret.Data, "expected to see new secret data: %s", library.Sdump(secret)) require.Equal(t, expectedData, secret.Data, "expected to see new secret data: %s", testlib.Sdump(secret))
break done // immediately stop consuming events because we want to check for updated events below break done // immediately stop consuming events because we want to check for updated events below
case <-timeout: case <-timeout:
@ -132,7 +132,7 @@ done2:
expectedData := map[string][]byte{ expectedData := map[string][]byte{
api.SecretDataKey: []byte(secretData2), api.SecretDataKey: []byte(secretData2),
} }
require.Equal(t, expectedData, secret.Data, "expected to see updated secret data: %s", library.Sdump(secret)) require.Equal(t, expectedData, secret.Data, "expected to see updated secret data: %s", testlib.Sdump(secret))
break done2 // immediately stop consuming events because we want to check for hot loops below break done2 // immediately stop consuming events because we want to check for hot loops below
case <-timeout: case <-timeout:
@ -154,7 +154,7 @@ done3:
} }
// this assumes that no other actor in the system is trying to mutate this secret // this assumes that no other actor in the system is trying to mutate this secret
t.Errorf("unexpected event seen for secret: %s", library.Sdump(event)) t.Errorf("unexpected event seen for secret: %s", testlib.Sdump(event))
case <-timeout: case <-timeout:
break done3 // we saw no events matching our secret meaning that we are not hot looping break done3 // we saw no events matching our secret meaning that we are not hot looping

View File

@ -18,7 +18,7 @@ import (
"k8s.io/apiserver/pkg/storage/names" "k8s.io/apiserver/pkg/storage/names"
"go.pinniped.dev/internal/certauthority" "go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestProviderWithDynamicServingCertificateController(t *testing.T) { func TestProviderWithDynamicServingCertificateController(t *testing.T) {
@ -205,12 +205,12 @@ func TestProviderWithDynamicServingCertificateController(t *testing.T) {
if err != nil && lastTLSConfig != nil { if err != nil && lastTLSConfig != nil {
// for debugging failures // for debugging failures
t.Log("diff between client CAs:\n", cmp.Diff( t.Log("diff between client CAs:\n", cmp.Diff(
library.Sdump(wantClientCASubjects), testlib.Sdump(wantClientCASubjects),
library.Sdump(poolSubjects(lastTLSConfig.ClientCAs)), testlib.Sdump(poolSubjects(lastTLSConfig.ClientCAs)),
)) ))
t.Log("diff between serving certs:\n", cmp.Diff( t.Log("diff between serving certs:\n", cmp.Diff(
library.Sdump(wantCerts), testlib.Sdump(wantCerts),
library.Sdump(lastTLSConfig.Certificates), testlib.Sdump(lastTLSConfig.Certificates),
)) ))
} }
require.NoError(t, err) require.NoError(t, err)

View File

@ -12,13 +12,13 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func runTestKubectlCommand(t *testing.T, args ...string) (string, string) { func runTestKubectlCommand(t *testing.T, args ...string) (string, string) {
t.Helper() t.Helper()
var stdOut, stdErr bytes.Buffer var stdOut, stdErr bytes.Buffer
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
stdOut.Reset() stdOut.Reset()
stdErr.Reset() stdErr.Reset()
cmd := exec.Command("kubectl", args...) cmd := exec.Command("kubectl", args...)
@ -47,7 +47,7 @@ func requireCleanKubectlStderr(t *testing.T, stderr string) {
} }
func TestGetPinnipedCategory(t *testing.T) { func TestGetPinnipedCategory(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
dotSuffix := "." + env.APIGroupSuffix dotSuffix := "." + env.APIGroupSuffix
t.Run("category, no special params", func(t *testing.T) { t.Run("category, no special params", func(t *testing.T) {

View File

@ -33,21 +33,21 @@ import (
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/pkg/oidcclient" "go.pinniped.dev/pkg/oidcclient"
"go.pinniped.dev/pkg/oidcclient/filesession" "go.pinniped.dev/pkg/oidcclient/filesession"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
"go.pinniped.dev/test/library/browsertest" "go.pinniped.dev/test/testlib/browsertest"
) )
func TestCLIGetKubeconfigStaticToken(t *testing.T) { func TestCLIGetKubeconfigStaticToken(t *testing.T) {
env := library.IntegrationEnv(t).WithCapability(library.ClusterSigningKeyIsAvailable) env := testlib.IntegrationEnv(t).WithCapability(testlib.ClusterSigningKeyIsAvailable)
// Create a test webhook configuration to use with the CLI. // Create a test webhook configuration to use with the CLI.
ctx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Minute) ctx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancelFunc() defer cancelFunc()
authenticator := library.CreateTestWebhookAuthenticator(ctx, t) authenticator := testlib.CreateTestWebhookAuthenticator(ctx, t)
// Build pinniped CLI. // Build pinniped CLI.
pinnipedExe := library.PinnipedCLIPath(t) pinnipedExe := testlib.PinnipedCLIPath(t)
credCacheDir := testutil.TempDir(t) credCacheDir := testutil.TempDir(t)
stdout, stderr := runPinnipedCLI(t, nil, pinnipedExe, "get", "kubeconfig", stdout, stderr := runPinnipedCLI(t, nil, pinnipedExe, "get", "kubeconfig",
@ -63,7 +63,7 @@ func TestCLIGetKubeconfigStaticToken(t *testing.T) {
assert.Contains(t, stderr, "validated connection to the cluster") assert.Contains(t, stderr, "validated connection to the cluster")
// Even the deprecated command should now generate a kubeconfig with the new "pinniped login static" command. // Even the deprecated command should now generate a kubeconfig with the new "pinniped login static" command.
restConfig := library.NewRestConfigFromKubeconfig(t, stdout) restConfig := testlib.NewRestConfigFromKubeconfig(t, stdout)
require.NotNil(t, restConfig.ExecProvider) require.NotNil(t, restConfig.ExecProvider)
require.Equal(t, []string{"login", "static"}, restConfig.ExecProvider.Args[:2]) require.Equal(t, []string{"login", "static"}, restConfig.ExecProvider.Args[:2])
@ -71,24 +71,24 @@ func TestCLIGetKubeconfigStaticToken(t *testing.T) {
// with kubectl to validate that it works. // with kubectl to validate that it works.
t.Run( t.Run(
"access as user with kubectl", "access as user with kubectl",
library.AccessAsUserWithKubectlTest(stdout, env.TestUser.ExpectedUsername, env.ConciergeNamespace), testlib.AccessAsUserWithKubectlTest(stdout, env.TestUser.ExpectedUsername, env.ConciergeNamespace),
) )
for _, group := range env.TestUser.ExpectedGroups { for _, group := range env.TestUser.ExpectedGroups {
group := group group := group
t.Run( t.Run(
"access as group "+group+" with kubectl", "access as group "+group+" with kubectl",
library.AccessAsGroupWithKubectlTest(stdout, group, env.ConciergeNamespace), testlib.AccessAsGroupWithKubectlTest(stdout, group, env.ConciergeNamespace),
) )
} }
// Create Kubernetes client with kubeconfig from pinniped CLI. // Create Kubernetes client with kubeconfig from pinniped CLI.
kubeClient := library.NewClientsetForKubeConfig(t, stdout) kubeClient := testlib.NewClientsetForKubeConfig(t, stdout)
// Validate that we can auth to the API via our user. // Validate that we can auth to the API via our user.
t.Run("access as user with client-go", library.AccessAsUserTest(ctx, env.TestUser.ExpectedUsername, kubeClient)) t.Run("access as user with client-go", testlib.AccessAsUserTest(ctx, env.TestUser.ExpectedUsername, kubeClient))
for _, group := range env.TestUser.ExpectedGroups { for _, group := range env.TestUser.ExpectedGroups {
group := group group := group
t.Run("access as group "+group+" with client-go", library.AccessAsGroupTest(ctx, group, kubeClient)) t.Run("access as group "+group+" with client-go", testlib.AccessAsGroupTest(ctx, group, kubeClient))
} }
t.Run("whoami", func(t *testing.T) { t.Run("whoami", func(t *testing.T) {
@ -116,14 +116,14 @@ func runPinnipedCLI(t *testing.T, envVars []string, pinnipedExe string, args ...
cmd.Stderr = &stderr cmd.Stderr = &stderr
cmd.Env = envVars cmd.Env = envVars
require.NoErrorf(t, cmd.Run(), "stderr:\n%s\n\nstdout:\n%s\n\n", stderr.String(), stdout.String()) require.NoErrorf(t, cmd.Run(), "stderr:\n%s\n\nstdout:\n%s\n\n", stderr.String(), stdout.String())
t.Logf("ran %q in %s", library.MaskTokens("pinniped "+strings.Join(args, " ")), time.Since(start).Round(time.Millisecond)) t.Logf("ran %q in %s", testlib.MaskTokens("pinniped "+strings.Join(args, " ")), time.Since(start).Round(time.Millisecond))
return stdout.String(), stderr.String() return stdout.String(), stderr.String()
} }
func assertWhoami(ctx context.Context, t *testing.T, useProxy bool, pinnipedExe, kubeconfigPath, wantUsername string, wantGroups []string) { func assertWhoami(ctx context.Context, t *testing.T, useProxy bool, pinnipedExe, kubeconfigPath, wantUsername string, wantGroups []string) {
t.Helper() t.Helper()
apiGroupSuffix := library.IntegrationEnv(t).APIGroupSuffix apiGroupSuffix := testlib.IntegrationEnv(t).APIGroupSuffix
var stdout, stderr bytes.Buffer var stdout, stderr bytes.Buffer
cmd := exec.CommandContext( cmd := exec.CommandContext(
@ -138,7 +138,7 @@ func assertWhoami(ctx context.Context, t *testing.T, useProxy bool, pinnipedExe,
apiGroupSuffix, apiGroupSuffix,
) )
if useProxy { if useProxy {
cmd.Env = append(os.Environ(), library.IntegrationEnv(t).ProxyEnv()...) cmd.Env = append(os.Environ(), testlib.IntegrationEnv(t).ProxyEnv()...)
} }
cmd.Stdout = &stdout cmd.Stdout = &stdout
cmd.Stderr = &stderr cmd.Stderr = &stderr
@ -164,13 +164,13 @@ func deserializeWhoAmIRequest(t *testing.T, data string, apiGroupSuffix string)
} }
func TestCLILoginOIDC(t *testing.T) { func TestCLILoginOIDC(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel() defer cancel()
// Build pinniped CLI. // Build pinniped CLI.
pinnipedExe := library.PinnipedCLIPath(t) pinnipedExe := testlib.PinnipedCLIPath(t)
// Run "pinniped login oidc" to get an ExecCredential struct with an OIDC ID token. // Run "pinniped login oidc" to get an ExecCredential struct with an OIDC ID token.
credOutput, sessionCachePath := runPinnipedLoginOIDC(ctx, t, pinnipedExe) credOutput, sessionCachePath := runPinnipedLoginOIDC(ctx, t, pinnipedExe)
@ -268,7 +268,7 @@ func runPinnipedLoginOIDC(
) (clientauthenticationv1beta1.ExecCredential, string) { ) (clientauthenticationv1beta1.ExecCredential, string) {
t.Helper() t.Helper()
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
// Make a temp directory to hold the session cache for this test. // Make a temp directory to hold the session cache for this test.
sessionCachePath := testutil.TempDir(t) + "/sessions.yaml" sessionCachePath := testutil.TempDir(t) + "/sessions.yaml"
@ -304,7 +304,7 @@ func runPinnipedLoginOIDC(
} }
}() }()
reader := bufio.NewReader(library.NewLoggerReader(t, "stderr", stderr)) reader := bufio.NewReader(testlib.NewLoggerReader(t, "stderr", stderr))
scanner := bufio.NewScanner(reader) scanner := bufio.NewScanner(reader)
const prompt = "Please log in: " const prompt = "Please log in: "
@ -331,7 +331,7 @@ func runPinnipedLoginOIDC(
err = fmt.Errorf("stdout stream closed with error: %w", closeErr) err = fmt.Errorf("stdout stream closed with error: %w", closeErr)
} }
}() }()
reader := bufio.NewReader(library.NewLoggerReader(t, "stdout", stdout)) reader := bufio.NewReader(testlib.NewLoggerReader(t, "stdout", stdout))
var out clientauthenticationv1beta1.ExecCredential var out clientauthenticationv1beta1.ExecCredential
if err := json.NewDecoder(reader).Decode(&out); err != nil { if err := json.NewDecoder(reader).Decode(&out); err != nil {
return fmt.Errorf("could not read ExecCredential from stdout: %w", err) return fmt.Errorf("could not read ExecCredential from stdout: %w", err)
@ -401,7 +401,7 @@ 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 := testlib.IntegrationEnv(t)
callbackURL, err := url.Parse(env.CLIUpstreamOIDC.CallbackURL) callbackURL, err := url.Parse(env.CLIUpstreamOIDC.CallbackURL)
require.NoError(t, err) require.NoError(t, err)
cmd := exec.CommandContext(ctx, pinnipedExe, "login", "oidc", cmd := exec.CommandContext(ctx, pinnipedExe, "login", "oidc",

View File

@ -14,11 +14,11 @@ import (
loginv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/login/v1alpha1" loginv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/login/v1alpha1"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestAPIServingCertificateAutoCreationAndRotation(t *testing.T) { func TestAPIServingCertificateAutoCreationAndRotation(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
defaultServingCertResourceName := env.ConciergeAppName + "-api-tls-serving-certificate" defaultServingCertResourceName := env.ConciergeAppName + "-api-tls-serving-certificate"
tests := []struct { tests := []struct {
@ -72,9 +72,9 @@ func TestAPIServingCertificateAutoCreationAndRotation(t *testing.T) {
for _, test := range tests { for _, test := range tests {
test := test test := test
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
kubeClient := library.NewKubernetesClientset(t) kubeClient := testlib.NewKubernetesClientset(t)
aggregatedClient := library.NewAggregatedClientset(t) aggregatedClient := testlib.NewAggregatedClientset(t)
conciergeClient := library.NewConciergeClientset(t) conciergeClient := testlib.NewConciergeClientset(t)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel() defer cancel()
@ -82,7 +82,7 @@ func TestAPIServingCertificateAutoCreationAndRotation(t *testing.T) {
// Create a testWebhook so we have a legitimate authenticator to pass to the // Create a testWebhook so we have a legitimate authenticator to pass to the
// TokenCredentialRequest API. // TokenCredentialRequest API.
testWebhook := library.CreateTestWebhookAuthenticator(ctx, t) testWebhook := testlib.CreateTestWebhookAuthenticator(ctx, t)
// Get the initial auto-generated version of the Secret. // Get the initial auto-generated version of the Secret.
secret, err := kubeClient.CoreV1().Secrets(env.ConciergeNamespace).Get(ctx, defaultServingCertResourceName, metav1.GetOptions{}) secret, err := kubeClient.CoreV1().Secrets(env.ConciergeNamespace).Get(ctx, defaultServingCertResourceName, metav1.GetOptions{})
@ -107,7 +107,7 @@ func TestAPIServingCertificateAutoCreationAndRotation(t *testing.T) {
require.NoError(t, test.forceRotation(ctx, kubeClient, env.ConciergeNamespace)) require.NoError(t, test.forceRotation(ctx, kubeClient, env.ConciergeNamespace))
// Expect that the Secret comes back right away with newly minted certs. // Expect that the Secret comes back right away with newly minted certs.
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
var err error var err error
secret, err = kubeClient.CoreV1().Secrets(env.ConciergeNamespace).Get(ctx, defaultServingCertResourceName, metav1.GetOptions{}) secret, err = kubeClient.CoreV1().Secrets(env.ConciergeNamespace).Get(ctx, defaultServingCertResourceName, metav1.GetOptions{})
requireEventually.NoError(err) requireEventually.NoError(err)
@ -127,7 +127,7 @@ func TestAPIServingCertificateAutoCreationAndRotation(t *testing.T) {
require.Equal(t, env.ConciergeAppName, secret.Labels["app"]) require.Equal(t, env.ConciergeAppName, secret.Labels["app"])
// Expect that the APIService was also updated with the new CA. // Expect that the APIService was also updated with the new CA.
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
apiService, err := aggregatedClient.ApiregistrationV1().APIServices().Get(ctx, apiServiceName, metav1.GetOptions{}) apiService, err := aggregatedClient.ApiregistrationV1().APIServices().Get(ctx, apiServiceName, metav1.GetOptions{})
requireEventually.NoErrorf(err, "get for APIService %q returned error", apiServiceName) requireEventually.NoErrorf(err, "get for APIService %q returned error", apiServiceName)
requireEventually.Equalf(regeneratedCACert, apiService.Spec.CABundle, "CA bundle in APIService %q does not yet have the expected value", apiServiceName) requireEventually.Equalf(regeneratedCACert, apiService.Spec.CABundle, "CA bundle in APIService %q does not yet have the expected value", apiServiceName)
@ -141,7 +141,7 @@ func TestAPIServingCertificateAutoCreationAndRotation(t *testing.T) {
// //
// our code changes all the certs immediately thus this should be healthy fairly quickly // our code changes all the certs immediately thus this should be healthy fairly quickly
// if this starts flaking, check for bugs in our dynamiccertificates.Notifier implementation // if this starts flaking, check for bugs in our dynamiccertificates.Notifier implementation
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
_, err := conciergeClient.LoginV1alpha1().TokenCredentialRequests().Create(ctx, &loginv1alpha1.TokenCredentialRequest{ _, err := conciergeClient.LoginV1alpha1().TokenCredentialRequests().Create(ctx, &loginv1alpha1.TokenCredentialRequest{
TypeMeta: metav1.TypeMeta{}, TypeMeta: metav1.TypeMeta{},

View File

@ -13,12 +13,12 @@ import (
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestGetDeployment(t *testing.T) { func TestGetDeployment(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
client := library.NewKubernetesClientset(t) client := testlib.NewKubernetesClientset(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
@ -28,7 +28,7 @@ func TestGetDeployment(t *testing.T) {
cond := getDeploymentCondition(appDeployment.Status, appsv1.DeploymentAvailable) cond := getDeploymentCondition(appDeployment.Status, appsv1.DeploymentAvailable)
require.NotNil(t, cond) require.NotNil(t, cond)
require.Equalf(t, corev1.ConditionTrue, cond.Status, "app should be available: %s", library.Sdump(appDeployment)) require.Equalf(t, corev1.ConditionTrue, cond.Status, "app should be available: %s", testlib.Sdump(appDeployment))
} }
// getDeploymentCondition returns the condition with the provided type. // getDeploymentCondition returns the condition with the provided type.

View File

@ -13,7 +13,7 @@ import (
"go.pinniped.dev/internal/here" "go.pinniped.dev/internal/here"
"go.pinniped.dev/pkg/conciergeclient" "go.pinniped.dev/pkg/conciergeclient"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
// Test certificate and private key that should get an authentication error. Generated with cfssl [1], like this: // Test certificate and private key that should get an authentication error. Generated with cfssl [1], like this:
@ -53,20 +53,20 @@ var (
var maskKey = func(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") } var maskKey = func(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }
func TestClient(t *testing.T) { func TestClient(t *testing.T) {
env := library.IntegrationEnv(t).WithCapability(library.ClusterSigningKeyIsAvailable) env := testlib.IntegrationEnv(t).WithCapability(testlib.ClusterSigningKeyIsAvailable)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
webhook := library.CreateTestWebhookAuthenticator(ctx, t) webhook := testlib.CreateTestWebhookAuthenticator(ctx, t)
// Use an invalid certificate/key to validate that the ServerVersion API fails like we assume. // Use an invalid certificate/key to validate that the ServerVersion API fails like we assume.
invalidClient := library.NewClientsetWithCertAndKey(t, testCert, testKey) invalidClient := testlib.NewClientsetWithCertAndKey(t, testCert, testKey)
_, err := invalidClient.Discovery().ServerVersion() _, err := invalidClient.Discovery().ServerVersion()
require.EqualError(t, err, "the server has asked for the client to provide credentials") require.EqualError(t, err, "the server has asked for the client to provide credentials")
// Using the CA bundle and host from the current (admin) kubeconfig, do the token exchange. // Using the CA bundle and host from the current (admin) kubeconfig, do the token exchange.
clientConfig := library.NewClientConfig(t) clientConfig := testlib.NewClientConfig(t)
client, err := conciergeclient.New( client, err := conciergeclient.New(
conciergeclient.WithCABundle(string(clientConfig.CAData)), conciergeclient.WithCABundle(string(clientConfig.CAData)),
conciergeclient.WithEndpoint(clientConfig.Host), conciergeclient.WithEndpoint(clientConfig.Host),
@ -75,14 +75,14 @@ func TestClient(t *testing.T) {
) )
require.NoError(t, err) require.NoError(t, err)
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
resp, err := client.ExchangeToken(ctx, env.TestUser.Token) resp, err := client.ExchangeToken(ctx, env.TestUser.Token)
requireEventually.NoError(err) requireEventually.NoError(err)
requireEventually.NotNil(resp.Status.ExpirationTimestamp) requireEventually.NotNil(resp.Status.ExpirationTimestamp)
requireEventually.InDelta(5*time.Minute, time.Until(resp.Status.ExpirationTimestamp.Time), float64(time.Minute)) requireEventually.InDelta(5*time.Minute, time.Until(resp.Status.ExpirationTimestamp.Time), float64(time.Minute))
// Create a client using the certificate and key returned by the token exchange. // Create a client using the certificate and key returned by the token exchange.
validClient := library.NewClientsetWithCertAndKey(t, resp.Status.ClientCertificateData, resp.Status.ClientKeyData) validClient := testlib.NewClientsetWithCertAndKey(t, resp.Status.ClientCertificateData, resp.Status.ClientKeyData)
// Make a version request, which should succeed even without any authorization. // Make a version request, which should succeed even without any authorization.
_, err = validClient.Discovery().ServerVersion() _, err = validClient.Discovery().ServerVersion()

View File

@ -14,14 +14,14 @@ import (
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1" configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestCredentialIssuer(t *testing.T) { func TestCredentialIssuer(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
config := library.NewClientConfig(t) config := testlib.NewClientConfig(t)
client := library.NewConciergeClientset(t) client := testlib.NewConciergeClientset(t)
aggregatedClientset := library.NewAggregatedClientset(t) aggregatedClientset := testlib.NewAggregatedClientset(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
@ -66,7 +66,7 @@ func TestCredentialIssuer(t *testing.T) {
} }
require.NotNil(t, actualStatusStrategy) require.NotNil(t, actualStatusStrategy)
if env.HasCapability(library.ClusterSigningKeyIsAvailable) { if env.HasCapability(testlib.ClusterSigningKeyIsAvailable) {
require.Equal(t, configv1alpha1.SuccessStrategyStatus, actualStatusStrategy.Status) require.Equal(t, configv1alpha1.SuccessStrategyStatus, actualStatusStrategy.Status)
require.Equal(t, configv1alpha1.FetchedKeyStrategyReason, actualStatusStrategy.Reason) require.Equal(t, configv1alpha1.FetchedKeyStrategyReason, actualStatusStrategy.Reason)
require.Equal(t, "key was fetched successfully", actualStatusStrategy.Message) require.Equal(t, "key was fetched successfully", actualStatusStrategy.Message)

View File

@ -19,16 +19,16 @@ import (
auth1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1" auth1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
loginv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/login/v1alpha1" loginv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/login/v1alpha1"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestUnsuccessfulCredentialRequest(t *testing.T) { func TestUnsuccessfulCredentialRequest(t *testing.T) {
env := library.IntegrationEnv(t).WithCapability(library.AnonymousAuthenticationSupported) env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
response, err := library.CreateTokenCredentialRequest(ctx, t, response, err := testlib.CreateTokenCredentialRequest(ctx, t,
loginv1alpha1.TokenCredentialRequestSpec{ loginv1alpha1.TokenCredentialRequestSpec{
Token: env.TestUser.Token, Token: env.TestUser.Token,
Authenticator: corev1.TypedLocalObjectReference{ Authenticator: corev1.TypedLocalObjectReference{
@ -45,7 +45,7 @@ func TestUnsuccessfulCredentialRequest(t *testing.T) {
} }
func TestSuccessfulCredentialRequest(t *testing.T) { func TestSuccessfulCredentialRequest(t *testing.T) {
env := library.IntegrationEnv(t).WithCapability(library.ClusterSigningKeyIsAvailable) env := testlib.IntegrationEnv(t).WithCapability(testlib.ClusterSigningKeyIsAvailable)
ctx, cancel := context.WithTimeout(context.Background(), 6*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 6*time.Minute)
defer cancel() defer cancel()
@ -57,16 +57,16 @@ func TestSuccessfulCredentialRequest(t *testing.T) {
}{ }{
{ {
name: "webhook", name: "webhook",
authenticator: library.CreateTestWebhookAuthenticator, authenticator: testlib.CreateTestWebhookAuthenticator,
token: func(t *testing.T) (string, string, []string) { token: func(t *testing.T) (string, string, []string) {
return library.IntegrationEnv(t).TestUser.Token, env.TestUser.ExpectedUsername, env.TestUser.ExpectedGroups return testlib.IntegrationEnv(t).TestUser.Token, env.TestUser.ExpectedUsername, env.TestUser.ExpectedGroups
}, },
}, },
{ {
name: "jwt authenticator", name: "jwt authenticator",
authenticator: library.CreateTestJWTAuthenticatorForCLIUpstream, authenticator: testlib.CreateTestJWTAuthenticatorForCLIUpstream,
token: func(t *testing.T) (string, string, []string) { token: func(t *testing.T) (string, string, []string) {
pinnipedExe := library.PinnipedCLIPath(t) pinnipedExe := testlib.PinnipedCLIPath(t)
credOutput, _ := runPinnipedLoginOIDC(ctx, t, pinnipedExe) credOutput, _ := runPinnipedLoginOIDC(ctx, t, pinnipedExe)
token := credOutput.Status.Token token := credOutput.Status.Token
@ -87,9 +87,9 @@ func TestSuccessfulCredentialRequest(t *testing.T) {
token, username, groups := test.token(t) token, username, groups := test.token(t)
var response *loginv1alpha1.TokenCredentialRequest var response *loginv1alpha1.TokenCredentialRequest
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
var err error var err error
response, err = library.CreateTokenCredentialRequest(ctx, t, response, err = testlib.CreateTokenCredentialRequest(ctx, t,
loginv1alpha1.TokenCredentialRequestSpec{Token: token, Authenticator: authenticator}, loginv1alpha1.TokenCredentialRequestSpec{Token: token, Authenticator: authenticator},
) )
requireEventually.NoError(err, "the request should never fail at the HTTP level") requireEventually.NoError(err, "the request should never fail at the HTTP level")
@ -108,7 +108,7 @@ func TestSuccessfulCredentialRequest(t *testing.T) {
}, 10*time.Second, 500*time.Millisecond) }, 10*time.Second, 500*time.Millisecond)
// Create a client using the certificate from the CredentialRequest. // Create a client using the certificate from the CredentialRequest.
clientWithCertFromCredentialRequest := library.NewClientsetWithCertAndKey( clientWithCertFromCredentialRequest := testlib.NewClientsetWithCertAndKey(
t, t,
response.Status.Credential.ClientCertificateData, response.Status.Credential.ClientCertificateData,
response.Status.Credential.ClientKeyData, response.Status.Credential.ClientKeyData,
@ -116,13 +116,13 @@ func TestSuccessfulCredentialRequest(t *testing.T) {
t.Run( t.Run(
"access as user", "access as user",
library.AccessAsUserTest(ctx, username, clientWithCertFromCredentialRequest), testlib.AccessAsUserTest(ctx, username, clientWithCertFromCredentialRequest),
) )
for _, group := range groups { for _, group := range groups {
group := group group := group
t.Run( t.Run(
"access as group "+group, "access as group "+group,
library.AccessAsGroupTest(ctx, group, clientWithCertFromCredentialRequest), testlib.AccessAsGroupTest(ctx, group, clientWithCertFromCredentialRequest),
) )
} }
}) })
@ -130,15 +130,15 @@ func TestSuccessfulCredentialRequest(t *testing.T) {
} }
func TestFailedCredentialRequestWhenTheRequestIsValidButTheTokenDoesNotAuthenticateTheUser(t *testing.T) { func TestFailedCredentialRequestWhenTheRequestIsValidButTheTokenDoesNotAuthenticateTheUser(t *testing.T) {
_ = library.IntegrationEnv(t).WithCapability(library.ClusterSigningKeyIsAvailable) _ = testlib.IntegrationEnv(t).WithCapability(testlib.ClusterSigningKeyIsAvailable)
// Create a testWebhook so we have a legitimate authenticator to pass to the // Create a testWebhook so we have a legitimate authenticator to pass to the
// TokenCredentialRequest API. // TokenCredentialRequest API.
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
testWebhook := library.CreateTestWebhookAuthenticator(ctx, t) testWebhook := testlib.CreateTestWebhookAuthenticator(ctx, t)
response, err := library.CreateTokenCredentialRequest(context.Background(), t, response, err := testlib.CreateTokenCredentialRequest(context.Background(), t,
loginv1alpha1.TokenCredentialRequestSpec{Token: "not a good token", Authenticator: testWebhook}, loginv1alpha1.TokenCredentialRequestSpec{Token: "not a good token", Authenticator: testWebhook},
) )
@ -150,15 +150,15 @@ func TestFailedCredentialRequestWhenTheRequestIsValidButTheTokenDoesNotAuthentic
} }
func TestCredentialRequest_ShouldFailWhenRequestDoesNotIncludeToken(t *testing.T) { func TestCredentialRequest_ShouldFailWhenRequestDoesNotIncludeToken(t *testing.T) {
_ = library.IntegrationEnv(t).WithCapability(library.ClusterSigningKeyIsAvailable) _ = testlib.IntegrationEnv(t).WithCapability(testlib.ClusterSigningKeyIsAvailable)
// Create a testWebhook so we have a legitimate authenticator to pass to the // Create a testWebhook so we have a legitimate authenticator to pass to the
// TokenCredentialRequest API. // TokenCredentialRequest API.
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
testWebhook := library.CreateTestWebhookAuthenticator(ctx, t) testWebhook := testlib.CreateTestWebhookAuthenticator(ctx, t)
response, err := library.CreateTokenCredentialRequest(context.Background(), t, response, err := testlib.CreateTokenCredentialRequest(context.Background(), t,
loginv1alpha1.TokenCredentialRequestSpec{Token: "", Authenticator: testWebhook}, loginv1alpha1.TokenCredentialRequestSpec{Token: "", Authenticator: testWebhook},
) )

View File

@ -65,7 +65,7 @@ import (
"go.pinniped.dev/internal/httputil/roundtripper" "go.pinniped.dev/internal/httputil/roundtripper"
"go.pinniped.dev/internal/kubeclient" "go.pinniped.dev/internal/kubeclient"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
// syncBuffer wraps bytes.Buffer with a mutex so we don't have races in our test code. // syncBuffer wraps bytes.Buffer with a mutex so we don't have races in our test code.
@ -100,22 +100,22 @@ func (sb *syncBuffer) Write(b []byte) (int, error) {
// - AKS ephemeral clusters: auto mode will choose enabled, supports LBs, has squid. // - AKS ephemeral clusters: auto mode will choose enabled, supports LBs, has squid.
// - EKS ephemeral clusters: auto mode will choose enabled, supports LBs, has squid. // - EKS ephemeral clusters: auto mode will choose enabled, supports LBs, has squid.
func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's complex. func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's complex.
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
impersonatorShouldHaveStartedAutomaticallyByDefault := !env.HasCapability(library.ClusterSigningKeyIsAvailable) impersonatorShouldHaveStartedAutomaticallyByDefault := !env.HasCapability(testlib.ClusterSigningKeyIsAvailable)
clusterSupportsLoadBalancers := env.HasCapability(library.HasExternalLoadBalancerProvider) clusterSupportsLoadBalancers := env.HasCapability(testlib.HasExternalLoadBalancerProvider)
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 20*time.Minute)
defer cancel() defer cancel()
// Create a client using the admin kubeconfig. // Create a client using the admin kubeconfig.
adminClient := library.NewKubernetesClientset(t) adminClient := testlib.NewKubernetesClientset(t)
adminConciergeClient := library.NewConciergeClientset(t) adminConciergeClient := testlib.NewConciergeClientset(t)
// Create a WebhookAuthenticator and prepare a TokenCredentialRequestSpec using the authenticator for use later. // Create a WebhookAuthenticator and prepare a TokenCredentialRequestSpec using the authenticator for use later.
credentialRequestSpecWithWorkingCredentials := loginv1alpha1.TokenCredentialRequestSpec{ credentialRequestSpecWithWorkingCredentials := loginv1alpha1.TokenCredentialRequestSpec{
Token: env.TestUser.Token, Token: env.TestUser.Token,
Authenticator: library.CreateTestWebhookAuthenticator(ctx, t), Authenticator: testlib.CreateTestWebhookAuthenticator(ctx, t),
} }
// The address of the ClusterIP service that points at the impersonation proxy's port (used when there is no load balancer). // The address of the ClusterIP service that points at the impersonation proxy's port (used when there is no load balancer).
@ -139,13 +139,13 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// However, we issue short-lived certs, so this cert will only be valid for a few minutes. // However, we issue short-lived certs, so this cert will only be valid for a few minutes.
// Cache it until it is almost expired and then refresh it whenever it is close to expired. // Cache it until it is almost expired and then refresh it whenever it is close to expired.
// //
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
resp, err := createTokenCredentialRequest(credentialRequestSpecWithWorkingCredentials, client) resp, err := createTokenCredentialRequest(credentialRequestSpecWithWorkingCredentials, client)
requireEventually.NoError(err) requireEventually.NoError(err)
requireEventually.NotNil(resp) requireEventually.NotNil(resp)
requireEventually.NotNil(resp.Status) requireEventually.NotNil(resp.Status)
requireEventually.NotNil(resp.Status.Credential) requireEventually.NotNil(resp.Status.Credential)
requireEventually.Nilf(resp.Status.Message, "expected no error message but got: %s", library.Sdump(resp.Status.Message)) requireEventually.Nilf(resp.Status.Message, "expected no error message but got: %s", testlib.Sdump(resp.Status.Message))
requireEventually.NotEmpty(resp.Status.Credential.ClientCertificateData) requireEventually.NotEmpty(resp.Status.Credential.ClientCertificateData)
requireEventually.NotEmpty(resp.Status.Credential.ClientKeyData) requireEventually.NotEmpty(resp.Status.Credential.ClientKeyData)
@ -217,7 +217,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// Auto mode should have decided that the impersonator will run and should have started a load balancer, // Auto mode should have decided that the impersonator will run and should have started a load balancer,
// and we will be able to use the load balancer to access the impersonator. (e.g. GKE, AKS, EKS) // and we will be able to use the load balancer to access the impersonator. (e.g. GKE, AKS, EKS)
// Check that load balancer has been automatically created by the impersonator's "auto" mode. // Check that load balancer has been automatically created by the impersonator's "auto" mode.
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
return hasImpersonationProxyLoadBalancerService(ctx, env, adminClient) return hasImpersonationProxyLoadBalancerService(ctx, env, adminClient)
}, 30*time.Second, 500*time.Millisecond) }, 30*time.Second, 500*time.Millisecond)
@ -251,7 +251,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
} }
// Check that no load balancer has been created by the impersonator's "auto" mode. // Check that no load balancer has been created by the impersonator's "auto" mode.
library.RequireNeverWithoutError(t, func() (bool, error) { testlib.RequireNeverWithoutError(t, func() (bool, error) {
return hasImpersonationProxyLoadBalancerService(ctx, env, adminClient) return hasImpersonationProxyLoadBalancerService(ctx, env, adminClient)
}, 10*time.Second, 500*time.Millisecond) }, 10*time.Second, 500*time.Millisecond)
@ -290,12 +290,12 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
t.Run("positive tests", func(t *testing.T) { t.Run("positive tests", func(t *testing.T) {
// Create an RBAC rule to allow this user to read/write everything. // Create an RBAC rule to allow this user to read/write everything.
library.CreateTestClusterRoleBinding(t, testlib.CreateTestClusterRoleBinding(t,
rbacv1.Subject{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: env.TestUser.ExpectedUsername}, rbacv1.Subject{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: env.TestUser.ExpectedUsername},
rbacv1.RoleRef{Kind: "ClusterRole", APIGroup: rbacv1.GroupName, Name: "edit"}, rbacv1.RoleRef{Kind: "ClusterRole", APIGroup: rbacv1.GroupName, Name: "edit"},
) )
// Wait for the above RBAC rule to take effect. // Wait for the above RBAC rule to take effect.
library.WaitForUserToHaveAccess(t, env.TestUser.ExpectedUsername, []string{}, &authorizationv1.ResourceAttributes{ testlib.WaitForUserToHaveAccess(t, env.TestUser.ExpectedUsername, []string{}, &authorizationv1.ResourceAttributes{
Verb: "get", Group: "", Version: "v1", Resource: "namespaces", Verb: "get", Group: "", Version: "v1", Resource: "namespaces",
}) })
@ -318,13 +318,13 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// influencing RBAC checks correctly. // influencing RBAC checks correctly.
t.Run( t.Run(
"access as user", "access as user",
library.AccessAsUserTest(ctx, env.TestUser.ExpectedUsername, impersonationProxyKubeClient(t)), testlib.AccessAsUserTest(ctx, env.TestUser.ExpectedUsername, impersonationProxyKubeClient(t)),
) )
for _, group := range env.TestUser.ExpectedGroups { for _, group := range env.TestUser.ExpectedGroups {
group := group group := group
t.Run( t.Run(
"access as group "+group, "access as group "+group,
library.AccessAsGroupTest(ctx, group, impersonationProxyKubeClient(t)), testlib.AccessAsGroupTest(ctx, group, impersonationProxyKubeClient(t)),
) )
} }
@ -447,7 +447,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// Use labels on our created ConfigMaps to avoid accidentally listing other ConfigMaps that might // Use labels on our created ConfigMaps to avoid accidentally listing other ConfigMaps that might
// exist in the namespace. In Kube 1.20+ there is a default ConfigMap in every namespace. // exist in the namespace. In Kube 1.20+ there is a default ConfigMap in every namespace.
configMapLabels := labels.Set{ configMapLabels := labels.Set{
"pinniped.dev/testConfigMap": library.RandHex(t, 8), "pinniped.dev/testConfigMap": testlib.RandHex(t, 8),
} }
// Test "create" verb through the impersonation proxy. // Test "create" verb through the impersonation proxy.
@ -469,7 +469,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// Make sure that all of the created ConfigMaps show up in the informer's cache to // Make sure that all of the created ConfigMaps show up in the informer's cache to
// demonstrate that the informer's "watch" verb is working through the impersonation proxy. // demonstrate that the informer's "watch" verb is working through the impersonation proxy.
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
_, err := informer.Lister().ConfigMaps(namespaceName).Get("configmap-1") _, err := informer.Lister().ConfigMaps(namespaceName).Get("configmap-1")
requireEventually.NoError(err) requireEventually.NoError(err)
_, err = informer.Lister().ConfigMaps(namespaceName).Get("configmap-2") _, err = informer.Lister().ConfigMaps(namespaceName).Get("configmap-2")
@ -496,7 +496,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
require.Equal(t, "bar", updateResult.Data["foo"]) require.Equal(t, "bar", updateResult.Data["foo"])
// Make sure that the updated ConfigMap shows up in the informer's cache. // Make sure that the updated ConfigMap shows up in the informer's cache.
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
configMap, err := informer.Lister().ConfigMaps(namespaceName).Get("configmap-3") configMap, err := informer.Lister().ConfigMaps(namespaceName).Get("configmap-3")
requireEventually.NoError(err) requireEventually.NoError(err)
requireEventually.Equal("bar", configMap.Data["foo"]) requireEventually.Equal("bar", configMap.Data["foo"])
@ -514,7 +514,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
require.Equal(t, "42", patchResult.Data["baz"]) require.Equal(t, "42", patchResult.Data["baz"])
// Make sure that the patched ConfigMap shows up in the informer's cache. // Make sure that the patched ConfigMap shows up in the informer's cache.
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
configMap, err := informer.Lister().ConfigMaps(namespaceName).Get("configmap-3") configMap, err := informer.Lister().ConfigMaps(namespaceName).Get("configmap-3")
requireEventually.NoError(err) requireEventually.NoError(err)
requireEventually.Equal("bar", configMap.Data["foo"]) requireEventually.Equal("bar", configMap.Data["foo"])
@ -526,7 +526,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
require.NoError(t, err) require.NoError(t, err)
// Make sure that the deleted ConfigMap shows up in the informer's cache. // Make sure that the deleted ConfigMap shows up in the informer's cache.
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
_, err := informer.Lister().ConfigMaps(namespaceName).Get("configmap-3") _, err := informer.Lister().ConfigMaps(namespaceName).Get("configmap-3")
requireEventually.Truef(k8serrors.IsNotFound(err), "expected a NotFound error from get, got %v", err) requireEventually.Truef(k8serrors.IsNotFound(err), "expected a NotFound error from get, got %v", err)
@ -540,7 +540,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
require.NoError(t, err) require.NoError(t, err)
// Make sure that the deleted ConfigMaps shows up in the informer's cache. // Make sure that the deleted ConfigMaps shows up in the informer's cache.
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
list, err := informer.Lister().ConfigMaps(namespaceName).List(configMapLabels.AsSelector()) list, err := informer.Lister().ConfigMaps(namespaceName).List(configMapLabels.AsSelector())
requireEventually.NoError(err) requireEventually.NoError(err)
requireEventually.Empty(list) requireEventually.Empty(list)
@ -630,7 +630,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
t.Run("nested impersonation as a cluster admin user is allowed", func(t *testing.T) { t.Run("nested impersonation as a cluster admin user is allowed", func(t *testing.T) {
t.Parallel() t.Parallel()
// Copy the admin credentials from the admin kubeconfig. // Copy the admin credentials from the admin kubeconfig.
adminClientRestConfig := library.NewClientConfig(t) adminClientRestConfig := testlib.NewClientConfig(t)
clusterAdminCredentials := getCredForConfig(t, adminClientRestConfig) clusterAdminCredentials := getCredForConfig(t, adminClientRestConfig)
// figure out who the admin user is // figure out who the admin user is
@ -705,7 +705,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
t.Run("nested impersonation as a cluster admin fails on reserved key", func(t *testing.T) { t.Run("nested impersonation as a cluster admin fails on reserved key", func(t *testing.T) {
t.Parallel() t.Parallel()
adminClientRestConfig := library.NewClientConfig(t) adminClientRestConfig := testlib.NewClientConfig(t)
clusterAdminCredentials := getCredForConfig(t, adminClientRestConfig) clusterAdminCredentials := getCredForConfig(t, adminClientRestConfig)
nestedImpersonationClient := newImpersonationProxyClientWithCredentials(t, nestedImpersonationClient := newImpersonationProxyClientWithCredentials(t,
@ -762,11 +762,11 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
time.Sleep(15 * time.Second) time.Sleep(15 * time.Second)
// allow the test SA to impersonate any SA // allow the test SA to impersonate any SA
library.CreateTestClusterRoleBinding(t, testlib.CreateTestClusterRoleBinding(t,
rbacv1.Subject{Kind: rbacv1.ServiceAccountKind, Name: saName, Namespace: namespaceName}, rbacv1.Subject{Kind: rbacv1.ServiceAccountKind, Name: saName, Namespace: namespaceName},
rbacv1.RoleRef{Kind: "ClusterRole", APIGroup: rbacv1.GroupName, Name: "edit"}, rbacv1.RoleRef{Kind: "ClusterRole", APIGroup: rbacv1.GroupName, Name: "edit"},
) )
library.WaitForUserToHaveAccess(t, serviceaccount.MakeUsername(namespaceName, saName), []string{}, &authorizationv1.ResourceAttributes{ testlib.WaitForUserToHaveAccess(t, serviceaccount.MakeUsername(namespaceName, saName), []string{}, &authorizationv1.ResourceAttributes{
Verb: "impersonate", Group: "", Version: "v1", Resource: "serviceaccounts", Verb: "impersonate", Group: "", Version: "v1", Resource: "serviceaccounts",
}) })
@ -817,7 +817,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{}) Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
// we expect the impersonation proxy to match the behavior of KAS in regards to anonymous requests // we expect the impersonation proxy to match the behavior of KAS in regards to anonymous requests
if env.HasCapability(library.AnonymousAuthenticationSupported) { if env.HasCapability(testlib.AnonymousAuthenticationSupported) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, require.Equal(t,
expectedWhoAmIRequestResponse( expectedWhoAmIRequestResponse(
@ -828,7 +828,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
whoAmI, whoAmI,
) )
} else { } else {
require.True(t, k8serrors.IsUnauthorized(err), library.Sdump(err)) require.True(t, k8serrors.IsUnauthorized(err), testlib.Sdump(err))
} }
// Test using a service account token. // Test using a service account token.
@ -895,7 +895,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
_, badAudErr := impersonationProxySABadAudPinnipedConciergeClient.IdentityV1alpha1().WhoAmIRequests(). _, badAudErr := impersonationProxySABadAudPinnipedConciergeClient.IdentityV1alpha1().WhoAmIRequests().
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{}) Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
require.True(t, k8serrors.IsUnauthorized(badAudErr), library.Sdump(badAudErr)) require.True(t, k8serrors.IsUnauthorized(badAudErr), testlib.Sdump(badAudErr))
tokenRequest, err := kubeClient.ServiceAccounts(namespaceName).CreateToken(ctx, saName, &authenticationv1.TokenRequest{ tokenRequest, err := kubeClient.ServiceAccounts(namespaceName).CreateToken(ctx, saName, &authenticationv1.TokenRequest{
Spec: authenticationv1.TokenRequestSpec{ Spec: authenticationv1.TokenRequestSpec{
@ -932,11 +932,11 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
) )
// allow the test SA to create CSRs // allow the test SA to create CSRs
library.CreateTestClusterRoleBinding(t, testlib.CreateTestClusterRoleBinding(t,
rbacv1.Subject{Kind: rbacv1.ServiceAccountKind, Name: saName, Namespace: namespaceName}, rbacv1.Subject{Kind: rbacv1.ServiceAccountKind, Name: saName, Namespace: namespaceName},
rbacv1.RoleRef{Kind: "ClusterRole", APIGroup: rbacv1.GroupName, Name: "system:node-bootstrapper"}, rbacv1.RoleRef{Kind: "ClusterRole", APIGroup: rbacv1.GroupName, Name: "system:node-bootstrapper"},
) )
library.WaitForUserToHaveAccess(t, serviceaccount.MakeUsername(namespaceName, saName), []string{}, &authorizationv1.ResourceAttributes{ testlib.WaitForUserToHaveAccess(t, serviceaccount.MakeUsername(namespaceName, saName), []string{}, &authorizationv1.ResourceAttributes{
Verb: "create", Group: certificatesv1.GroupName, Version: "*", Resource: "certificatesigningrequests", Verb: "create", Group: certificatesv1.GroupName, Version: "*", Resource: "certificatesigningrequests",
}) })
@ -1007,7 +1007,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// run the kubectl attach command // run the kubectl attach command
namespaceName := createTestNamespace(t, adminClient) namespaceName := createTestNamespace(t, adminClient)
attachPod := library.CreatePod(ctx, t, "impersonation-proxy-attach", namespaceName, corev1.PodSpec{ attachPod := testlib.CreatePod(ctx, t, "impersonation-proxy-attach", namespaceName, corev1.PodSpec{
Containers: []corev1.Container{ Containers: []corev1.Container{
{ {
Name: "impersonation-proxy-attach", Name: "impersonation-proxy-attach",
@ -1040,7 +1040,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// see that we can read stdout and it spits out stdin output back to us // see that we can read stdout and it spits out stdin output back to us
wantAttachStdout := fmt.Sprintf("VAR: %s\n", echoString) wantAttachStdout := fmt.Sprintf("VAR: %s\n", echoString)
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
requireEventually.Equal( requireEventually.Equal(
wantAttachStdout, wantAttachStdout,
attachStdout.String(), attachStdout.String(),
@ -1084,7 +1084,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
dialer.Proxy = func(req *http.Request) (*url.URL, error) { dialer.Proxy = func(req *http.Request) (*url.URL, error) {
proxyURL, err := url.Parse(env.Proxy) proxyURL, err := url.Parse(env.Proxy)
require.NoError(t, err) require.NoError(t, err)
t.Logf("passing request for %s through proxy %s", library.RedactURLParams(req.URL), proxyURL.String()) t.Logf("passing request for %s through proxy %s", testlib.RedactURLParams(req.URL), proxyURL.String())
return proxyURL, nil return proxyURL, nil
} }
} }
@ -1163,7 +1163,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
httpTransport.Proxy = func(req *http.Request) (*url.URL, error) { httpTransport.Proxy = func(req *http.Request) (*url.URL, error) {
proxyURL, err := url.Parse(env.Proxy) proxyURL, err := url.Parse(env.Proxy)
require.NoError(t, err) require.NoError(t, err)
t.Logf("passing request for %s through proxy %s", library.RedactURLParams(req.URL), proxyURL.String()) t.Logf("passing request for %s through proxy %s", testlib.RedactURLParams(req.URL), proxyURL.String())
return proxyURL, nil return proxyURL, nil
} }
} }
@ -1237,7 +1237,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
impersonationProxyAnonymousRestClient, err := rest.RESTClientFor(copyConfig) impersonationProxyAnonymousRestClient, err := rest.RESTClientFor(copyConfig)
require.NoError(t, err) require.NoError(t, err)
adminClientRestConfig := library.NewClientConfig(t) adminClientRestConfig := testlib.NewClientConfig(t)
clusterAdminCredentials := getCredForConfig(t, adminClientRestConfig) clusterAdminCredentials := getCredForConfig(t, adminClientRestConfig)
impersonationProxyAdminClientAsAnonymousConfig := newImpersonationProxyClientWithCredentials(t, impersonationProxyAdminClientAsAnonymousConfig := newImpersonationProxyClientWithCredentials(t,
clusterAdminCredentials, clusterAdminCredentials,
@ -1266,7 +1266,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
Authenticator: corev1.TypedLocalObjectReference{APIGroup: pointer.String("anything.pinniped.dev")}, Authenticator: corev1.TypedLocalObjectReference{APIGroup: pointer.String("anything.pinniped.dev")},
}, },
}, metav1.CreateOptions{}) }, metav1.CreateOptions{})
require.True(t, k8serrors.IsInvalid(err), library.Sdump(err)) require.True(t, k8serrors.IsInvalid(err), testlib.Sdump(err))
require.Equal(t, `.login.concierge.pinniped.dev "" is invalid: spec.token.value: Required value: token must be supplied`, err.Error()) require.Equal(t, `.login.concierge.pinniped.dev "" is invalid: spec.token.value: Required value: token must be supplied`, err.Error())
require.Equal(t, &loginv1alpha1.TokenCredentialRequest{}, tkr) require.Equal(t, &loginv1alpha1.TokenCredentialRequest{}, tkr)
}) })
@ -1282,21 +1282,21 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
t.Parallel() t.Parallel()
whoami, errWho := impersonationProxyAdminRestClientAsAnonymous.Post().Body([]byte(`{}`)).AbsPath("/apis/identity.concierge." + env.APIGroupSuffix + "/v1alpha1/whoamirequests").DoRaw(ctx) whoami, errWho := impersonationProxyAdminRestClientAsAnonymous.Post().Body([]byte(`{}`)).AbsPath("/apis/identity.concierge." + env.APIGroupSuffix + "/v1alpha1/whoamirequests").DoRaw(ctx)
require.NoError(t, errWho, library.Sdump(errWho)) require.NoError(t, errWho, testlib.Sdump(errWho))
require.True(t, strings.HasPrefix(string(whoami), `{"kind":"WhoAmIRequest","apiVersion":"identity.concierge.`+env.APIGroupSuffix+`/v1alpha1","metadata":{"creationTimestamp":null},"spec":{},"status":{"kubernetesUserInfo":{"user":{"username":"system:anonymous","groups":["system:unauthenticated"],"extra":{"original-user-info.impersonation-proxy.concierge.pinniped.dev":["{\"username\":`), string(whoami)) require.True(t, strings.HasPrefix(string(whoami), `{"kind":"WhoAmIRequest","apiVersion":"identity.concierge.`+env.APIGroupSuffix+`/v1alpha1","metadata":{"creationTimestamp":null},"spec":{},"status":{"kubernetesUserInfo":{"user":{"username":"system:anonymous","groups":["system:unauthenticated"],"extra":{"original-user-info.impersonation-proxy.concierge.pinniped.dev":["{\"username\":`), string(whoami))
healthz, errHealth := impersonationProxyAdminRestClientAsAnonymous.Get().AbsPath("/healthz").DoRaw(ctx) healthz, errHealth := impersonationProxyAdminRestClientAsAnonymous.Get().AbsPath("/healthz").DoRaw(ctx)
require.NoError(t, errHealth, library.Sdump(errHealth)) require.NoError(t, errHealth, testlib.Sdump(errHealth))
require.Equal(t, "ok", string(healthz)) require.Equal(t, "ok", string(healthz))
healthzLog, errHealthzLog := impersonationProxyAdminRestClientAsAnonymous.Get().AbsPath("/healthz/log").DoRaw(ctx) healthzLog, errHealthzLog := impersonationProxyAdminRestClientAsAnonymous.Get().AbsPath("/healthz/log").DoRaw(ctx)
require.True(t, k8serrors.IsForbidden(errHealthzLog), "%s\n%s", library.Sdump(errHealthzLog), string(healthzLog)) require.True(t, k8serrors.IsForbidden(errHealthzLog), "%s\n%s", testlib.Sdump(errHealthzLog), string(healthzLog))
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User \"system:anonymous\" cannot get path \"/healthz/log\": decision made by impersonation-proxy.concierge.pinniped.dev","reason":"Forbidden","details":{},"code":403}`+"\n", string(healthzLog)) require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User \"system:anonymous\" cannot get path \"/healthz/log\": decision made by impersonation-proxy.concierge.pinniped.dev","reason":"Forbidden","details":{},"code":403}`+"\n", string(healthzLog))
}) })
}) })
t.Run("anonymous authentication enabled", func(t *testing.T) { t.Run("anonymous authentication enabled", func(t *testing.T) {
library.IntegrationEnv(t).WithCapability(library.AnonymousAuthenticationSupported) testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported)
t.Parallel() t.Parallel()
// anonymous auth enabled // anonymous auth enabled
@ -1308,7 +1308,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
t.Parallel() t.Parallel()
healthz, errHealth := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx) healthz, errHealth := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx)
require.NoError(t, errHealth, library.Sdump(errHealth)) require.NoError(t, errHealth, testlib.Sdump(errHealth))
require.Equal(t, "ok", string(healthz)) require.Equal(t, "ok", string(healthz))
}) })
@ -1321,9 +1321,9 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
pod, err := impersonationProxyAnonymousClient.Kubernetes.CoreV1().Pods(metav1.NamespaceSystem). pod, err := impersonationProxyAnonymousClient.Kubernetes.CoreV1().Pods(metav1.NamespaceSystem).
Get(ctx, "does-not-matter", metav1.GetOptions{}) Get(ctx, "does-not-matter", metav1.GetOptions{})
require.True(t, k8serrors.IsForbidden(err), library.Sdump(err)) require.True(t, k8serrors.IsForbidden(err), testlib.Sdump(err))
require.EqualError(t, err, `pods "does-not-matter" is forbidden: User "system:anonymous" cannot get resource "pods" in API group "" in the namespace "kube-system": `+ require.EqualError(t, err, `pods "does-not-matter" is forbidden: User "system:anonymous" cannot get resource "pods" in API group "" in the namespace "kube-system": `+
`decision made by impersonation-proxy.concierge.pinniped.dev`, library.Sdump(err)) `decision made by impersonation-proxy.concierge.pinniped.dev`, testlib.Sdump(err))
require.Equal(t, &corev1.Pod{}, pod) require.Equal(t, &corev1.Pod{}, pod)
}) })
@ -1349,7 +1349,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
}) })
t.Run("anonymous authentication disabled", func(t *testing.T) { t.Run("anonymous authentication disabled", func(t *testing.T) {
library.IntegrationEnv(t).WithoutCapability(library.AnonymousAuthenticationSupported) testlib.IntegrationEnv(t).WithoutCapability(testlib.AnonymousAuthenticationSupported)
t.Parallel() t.Parallel()
// - hit the healthz endpoint (non-resource endpoint) // - hit the healthz endpoint (non-resource endpoint)
@ -1360,7 +1360,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
t.Parallel() t.Parallel()
healthz, err := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx) healthz, err := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx)
require.True(t, k8serrors.IsUnauthorized(err), library.Sdump(err)) require.True(t, k8serrors.IsUnauthorized(err), testlib.Sdump(err))
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(healthz)) require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(healthz))
}) })
@ -1373,7 +1373,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
pod, err := impersonationProxyAnonymousClient.Kubernetes.CoreV1().Pods(metav1.NamespaceSystem). pod, err := impersonationProxyAnonymousClient.Kubernetes.CoreV1().Pods(metav1.NamespaceSystem).
Get(ctx, "does-not-matter", metav1.GetOptions{}) Get(ctx, "does-not-matter", metav1.GetOptions{})
require.True(t, k8serrors.IsUnauthorized(err), library.Sdump(err)) require.True(t, k8serrors.IsUnauthorized(err), testlib.Sdump(err))
require.Equal(t, &corev1.Pod{}, pod) require.Equal(t, &corev1.Pod{}, pod)
}) })
@ -1386,7 +1386,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
whoAmI, err := impersonationProxyAnonymousClient.PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests(). whoAmI, err := impersonationProxyAnonymousClient.PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests().
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{}) Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
require.True(t, k8serrors.IsUnauthorized(err), library.Sdump(err)) require.True(t, k8serrors.IsUnauthorized(err), testlib.Sdump(err))
require.Equal(t, &identityv1alpha1.WhoAmIRequest{}, whoAmI) require.Equal(t, &identityv1alpha1.WhoAmIRequest{}, whoAmI)
}) })
}) })
@ -1404,7 +1404,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// sanity check default expected error message // sanity check default expected error message
_, err := impersonationProxySSRRClient.Create(ctx, invalidSSRR, metav1.CreateOptions{}) _, err := impersonationProxySSRRClient.Create(ctx, invalidSSRR, metav1.CreateOptions{})
require.True(t, k8serrors.IsBadRequest(err), library.Sdump(err)) require.True(t, k8serrors.IsBadRequest(err), testlib.Sdump(err))
require.EqualError(t, err, "no namespace on request") require.EqualError(t, err, "no namespace on request")
// remove the impersonation proxy SA's permissions // remove the impersonation proxy SA's permissions
@ -1434,14 +1434,14 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
_, errUpdate := crbClient.Update(ctx, crbEnd, metav1.UpdateOptions{}) _, errUpdate := crbClient.Update(ctx, crbEnd, metav1.UpdateOptions{})
require.NoError(t, errUpdate) require.NoError(t, errUpdate)
library.WaitForUserToHaveAccess(t, saFullName, nil, &authorizationv1.ResourceAttributes{ testlib.WaitForUserToHaveAccess(t, saFullName, nil, &authorizationv1.ResourceAttributes{
Verb: "impersonate", Verb: "impersonate",
Resource: "users", Resource: "users",
}) })
}) })
// assert that the impersonation proxy stops working when we remove its permissions // assert that the impersonation proxy stops working when we remove its permissions
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
_, errCreate := impersonationProxySSRRClient.Create(ctx, invalidSSRR, metav1.CreateOptions{}) _, errCreate := impersonationProxySSRRClient.Create(ctx, invalidSSRR, metav1.CreateOptions{})
switch { switch {
@ -1491,7 +1491,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
} }
waitForServiceAnnotations := func(annotations map[string]string) { waitForServiceAnnotations := func(annotations map[string]string) {
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
service, err := adminClient.CoreV1().Services(env.ConciergeNamespace).Get(ctx, impersonationProxyLoadBalancerName(env), metav1.GetOptions{}) service, err := adminClient.CoreV1().Services(env.ConciergeNamespace).Get(ctx, impersonationProxyLoadBalancerName(env), metav1.GetOptions{})
if err != nil { if err != nil {
return false, err return false, err
@ -1509,8 +1509,8 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
}) })
// Set a new annotation in the CredentialIssuer spec.impersonationProxy.service.annotations field. // Set a new annotation in the CredentialIssuer spec.impersonationProxy.service.annotations field.
newAnnotationKey := "pinniped.dev/test-" + library.RandHex(t, 8) newAnnotationKey := "pinniped.dev/test-" + testlib.RandHex(t, 8)
newAnnotationValue := "test-" + library.RandHex(t, 8) newAnnotationValue := "test-" + testlib.RandHex(t, 8)
updatedAnnotations := previous.Spec.ImpersonationProxy.Service.DeepCopy().Annotations updatedAnnotations := previous.Spec.ImpersonationProxy.Service.DeepCopy().Annotations
updatedAnnotations[newAnnotationKey] = newAnnotationValue updatedAnnotations[newAnnotationKey] = newAnnotationValue
applyCredentialIssuerAnnotations(updatedAnnotations) applyCredentialIssuerAnnotations(updatedAnnotations)
@ -1535,7 +1535,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
}) })
// wait until the credential issuer is updated with the new url // wait until the credential issuer is updated with the new url
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
newImpersonationProxyURL, _ := performImpersonatorDiscovery(ctx, t, env, adminConciergeClient) newImpersonationProxyURL, _ := performImpersonatorDiscovery(ctx, t, env, adminConciergeClient)
return newImpersonationProxyURL == "https://"+clusterIPServiceURL, nil return newImpersonationProxyURL == "https://"+clusterIPServiceURL, nil
}, 30*time.Second, 500*time.Millisecond) }, 30*time.Second, 500*time.Millisecond)
@ -1549,7 +1549,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// everything should work properly through the cluster ip service // everything should work properly through the cluster ip service
t.Run( t.Run(
"access as user", "access as user",
library.AccessAsUserTest(ctx, env.TestUser.ExpectedUsername, client), testlib.AccessAsUserTest(ctx, env.TestUser.ExpectedUsername, client),
) )
}) })
@ -1564,7 +1564,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
if clusterSupportsLoadBalancers { if clusterSupportsLoadBalancers {
// The load balancer should have been deleted when we disabled the impersonation proxy. // The load balancer should have been deleted when we disabled the impersonation proxy.
// Note that this can take kind of a long time on real cloud providers (e.g. ~22 seconds on EKS). // Note that this can take kind of a long time on real cloud providers (e.g. ~22 seconds on EKS).
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
hasService, err := hasImpersonationProxyLoadBalancerService(ctx, env, adminClient) hasService, err := hasImpersonationProxyLoadBalancerService(ctx, env, adminClient)
return !hasService, err return !hasService, err
}, 2*time.Minute, 500*time.Millisecond) }, 2*time.Minute, 500*time.Millisecond)
@ -1576,7 +1576,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// so we'll skip this check on clusters which have load balancers but don't run the squid proxy. // so we'll skip this check on clusters which have load balancers but don't run the squid proxy.
// The other cluster types that do run the squid proxy will give us sufficient coverage here. // The other cluster types that do run the squid proxy will give us sufficient coverage here.
if env.Proxy != "" { if env.Proxy != "" {
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
// It's okay if this returns RBAC errors because this user has no role bindings. // It's okay if this returns RBAC errors because this user has no role bindings.
// What we want to see is that the proxy eventually shuts down entirely. // What we want to see is that the proxy eventually shuts down entirely.
_, err := impersonationProxyViaSquidKubeClientWithoutCredential(t, proxyServiceEndpoint).CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) _, err := impersonationProxyViaSquidKubeClientWithoutCredential(t, proxyServiceEndpoint).CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
@ -1587,7 +1587,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// Check that the generated TLS cert Secret was deleted by the controller because it's supposed to clean this up // Check that the generated TLS cert Secret was deleted by the controller because it's supposed to clean this up
// when we disable the impersonator. // when we disable the impersonator.
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
_, err := adminClient.CoreV1().Secrets(env.ConciergeNamespace).Get(ctx, impersonationProxyTLSSecretName(env), metav1.GetOptions{}) _, err := adminClient.CoreV1().Secrets(env.ConciergeNamespace).Get(ctx, impersonationProxyTLSSecretName(env), metav1.GetOptions{})
requireEventually.Truef(k8serrors.IsNotFound(err), "expected NotFound error, got %v", err) requireEventually.Truef(k8serrors.IsNotFound(err), "expected NotFound error, got %v", err)
}, 10*time.Second, 250*time.Millisecond) }, 10*time.Second, 250*time.Millisecond)
@ -1602,14 +1602,14 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
// include an unsuccessful impersonation strategy saying that it was manually configured to be disabled. // include an unsuccessful impersonation strategy saying that it was manually configured to be disabled.
requireDisabledStrategy(ctx, t, env, adminConciergeClient) requireDisabledStrategy(ctx, t, env, adminConciergeClient)
if !env.HasCapability(library.ClusterSigningKeyIsAvailable) && env.HasCapability(library.AnonymousAuthenticationSupported) { if !env.HasCapability(testlib.ClusterSigningKeyIsAvailable) && env.HasCapability(testlib.AnonymousAuthenticationSupported) {
// This cluster does not support the cluster signing key strategy, so now that we've manually disabled the // This cluster does not support the cluster signing key strategy, so now that we've manually disabled the
// impersonation strategy, we should be left with no working strategies. // impersonation strategy, we should be left with no working strategies.
// Given that there are no working strategies, a TokenCredentialRequest which would otherwise work should now // Given that there are no working strategies, a TokenCredentialRequest which would otherwise work should now
// fail, because there is no point handing out credentials that are not going to work for any strategy. // fail, because there is no point handing out credentials that are not going to work for any strategy.
// Note that library.CreateTokenCredentialRequest makes an unauthenticated request, so we can't meaningfully // Note that library.CreateTokenCredentialRequest makes an unauthenticated request, so we can't meaningfully
// perform this part of the test on a cluster which does not allow anonymous authentication. // perform this part of the test on a cluster which does not allow anonymous authentication.
tokenCredentialRequestResponse, err := library.CreateTokenCredentialRequest(ctx, t, credentialRequestSpecWithWorkingCredentials) tokenCredentialRequestResponse, err := testlib.CreateTokenCredentialRequest(ctx, t, credentialRequestSpecWithWorkingCredentials)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, tokenCredentialRequestResponse.Status.Message, "expected an error message but got nil") require.NotNil(t, tokenCredentialRequestResponse.Status.Message, "expected an error message but got nil")
@ -1666,7 +1666,7 @@ func createServiceAccountToken(ctx context.Context, t *testing.T, adminClient ku
Delete(context.Background(), secret.Name, metav1.DeleteOptions{})) Delete(context.Background(), secret.Name, metav1.DeleteOptions{}))
}) })
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
secret, err = adminClient.CoreV1().Secrets(namespaceName).Get(ctx, secret.Name, metav1.GetOptions{}) secret, err = adminClient.CoreV1().Secrets(namespaceName).Get(ctx, secret.Name, metav1.GetOptions{})
if err != nil { if err != nil {
return false, err return false, err
@ -1692,7 +1692,7 @@ func expectedWhoAmIRequestResponse(username string, groups []string, extra map[s
} }
} }
func performImpersonatorDiscovery(ctx context.Context, t *testing.T, env *library.TestEnv, adminConciergeClient pinnipedconciergeclientset.Interface) (string, []byte) { func performImpersonatorDiscovery(ctx context.Context, t *testing.T, env *testlib.TestEnv, adminConciergeClient pinnipedconciergeclientset.Interface) (string, []byte) {
t.Helper() t.Helper()
var impersonationProxyURL string var impersonationProxyURL string
@ -1700,7 +1700,7 @@ func performImpersonatorDiscovery(ctx context.Context, t *testing.T, env *librar
t.Log("Waiting for CredentialIssuer strategy to be successful") t.Log("Waiting for CredentialIssuer strategy to be successful")
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
credentialIssuer, err := adminConciergeClient.ConfigV1alpha1().CredentialIssuers().Get(ctx, credentialIssuerName(env), metav1.GetOptions{}) credentialIssuer, err := adminConciergeClient.ConfigV1alpha1().CredentialIssuers().Get(ctx, credentialIssuerName(env), metav1.GetOptions{})
if err != nil || credentialIssuer.Status.Strategies == nil { if err != nil || credentialIssuer.Status.Strategies == nil {
t.Log("Did not find any CredentialIssuer with any strategies") t.Log("Did not find any CredentialIssuer with any strategies")
@ -1738,10 +1738,10 @@ func performImpersonatorDiscovery(ctx context.Context, t *testing.T, env *librar
return impersonationProxyURL, impersonationProxyCACertPEM return impersonationProxyURL, impersonationProxyCACertPEM
} }
func requireDisabledStrategy(ctx context.Context, t *testing.T, env *library.TestEnv, adminConciergeClient pinnipedconciergeclientset.Interface) { func requireDisabledStrategy(ctx context.Context, t *testing.T, env *testlib.TestEnv, adminConciergeClient pinnipedconciergeclientset.Interface) {
t.Helper() t.Helper()
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
credentialIssuer, err := adminConciergeClient.ConfigV1alpha1().CredentialIssuers().Get(ctx, credentialIssuerName(env), metav1.GetOptions{}) credentialIssuer, err := adminConciergeClient.ConfigV1alpha1().CredentialIssuers().Get(ctx, credentialIssuerName(env), metav1.GetOptions{})
if err != nil || credentialIssuer.Status.Strategies == nil { if err != nil || credentialIssuer.Status.Strategies == nil {
t.Log("Did not find any CredentialIssuer with any strategies") t.Log("Did not find any CredentialIssuer with any strategies")
@ -1812,12 +1812,12 @@ func kubeconfigProxyFunc(t *testing.T, squidProxyURL string) func(req *http.Requ
parsedSquidProxyURL, err := url.Parse(squidProxyURL) parsedSquidProxyURL, err := url.Parse(squidProxyURL)
require.NoError(t, err) require.NoError(t, err)
t.Logf("passing request for %s through proxy %s", library.RedactURLParams(req.URL), parsedSquidProxyURL.String()) t.Logf("passing request for %s through proxy %s", testlib.RedactURLParams(req.URL), parsedSquidProxyURL.String())
return parsedSquidProxyURL, nil return parsedSquidProxyURL, nil
} }
} }
func updateCredentialIssuer(ctx context.Context, t *testing.T, env *library.TestEnv, adminConciergeClient pinnipedconciergeclientset.Interface, spec conciergev1alpha.CredentialIssuerSpec) { func updateCredentialIssuer(ctx context.Context, t *testing.T, env *testlib.TestEnv, adminConciergeClient pinnipedconciergeclientset.Interface, spec conciergev1alpha.CredentialIssuerSpec) {
t.Helper() t.Helper()
err := retry.RetryOnConflict(retry.DefaultRetry, func() error { err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
@ -1832,7 +1832,7 @@ func updateCredentialIssuer(ctx context.Context, t *testing.T, env *library.Test
require.NoError(t, err) require.NoError(t, err)
} }
func hasImpersonationProxyLoadBalancerService(ctx context.Context, env *library.TestEnv, client kubernetes.Interface) (bool, error) { func hasImpersonationProxyLoadBalancerService(ctx context.Context, env *testlib.TestEnv, client kubernetes.Interface) (bool, error) {
service, err := client.CoreV1().Services(env.ConciergeNamespace).Get(ctx, impersonationProxyLoadBalancerName(env), metav1.GetOptions{}) service, err := client.CoreV1().Services(env.ConciergeNamespace).Get(ctx, impersonationProxyLoadBalancerName(env), metav1.GetOptions{})
if k8serrors.IsNotFound(err) { if k8serrors.IsNotFound(err) {
return false, nil return false, nil
@ -1843,34 +1843,34 @@ func hasImpersonationProxyLoadBalancerService(ctx context.Context, env *library.
return service.Spec.Type == corev1.ServiceTypeLoadBalancer, nil return service.Spec.Type == corev1.ServiceTypeLoadBalancer, nil
} }
func impersonationProxyTLSSecretName(env *library.TestEnv) string { func impersonationProxyTLSSecretName(env *testlib.TestEnv) string {
return env.ConciergeAppName + "-impersonation-proxy-tls-serving-certificate" return env.ConciergeAppName + "-impersonation-proxy-tls-serving-certificate"
} }
func impersonationProxyCASecretName(env *library.TestEnv) string { func impersonationProxyCASecretName(env *testlib.TestEnv) string {
return env.ConciergeAppName + "-impersonation-proxy-ca-certificate" return env.ConciergeAppName + "-impersonation-proxy-ca-certificate"
} }
func impersonationProxyLoadBalancerName(env *library.TestEnv) string { func impersonationProxyLoadBalancerName(env *testlib.TestEnv) string {
return env.ConciergeAppName + "-impersonation-proxy-load-balancer" return env.ConciergeAppName + "-impersonation-proxy-load-balancer"
} }
func impersonationProxyClusterIPName(env *library.TestEnv) string { func impersonationProxyClusterIPName(env *testlib.TestEnv) string {
return env.ConciergeAppName + "-impersonation-proxy-cluster-ip" return env.ConciergeAppName + "-impersonation-proxy-cluster-ip"
} }
func credentialIssuerName(env *library.TestEnv) string { func credentialIssuerName(env *testlib.TestEnv) string {
return env.ConciergeAppName + "-config" return env.ConciergeAppName + "-config"
} }
func getImpersonationKubeconfig(t *testing.T, env *library.TestEnv, impersonationProxyURL string, impersonationProxyCACertPEM []byte, authenticator corev1.TypedLocalObjectReference) (string, []string, string) { func getImpersonationKubeconfig(t *testing.T, env *testlib.TestEnv, impersonationProxyURL string, impersonationProxyCACertPEM []byte, authenticator corev1.TypedLocalObjectReference) (string, []string, string) {
t.Helper() t.Helper()
pinnipedExe := library.PinnipedCLIPath(t) pinnipedExe := testlib.PinnipedCLIPath(t)
tempDir := testutil.TempDir(t) tempDir := testutil.TempDir(t)
var envVarsWithProxy []string var envVarsWithProxy []string
if !env.HasCapability(library.HasExternalLoadBalancerProvider) { if !env.HasCapability(testlib.HasExternalLoadBalancerProvider) {
// Only if you don't have a load balancer, use the squid proxy when it's available. // Only if you don't have a load balancer, use the squid proxy when it's available.
envVarsWithProxy = append(os.Environ(), env.ProxyEnv()...) envVarsWithProxy = append(os.Environ(), env.ProxyEnv()...)
} }
@ -1991,8 +1991,8 @@ func createTokenCredentialRequest(
func newImpersonationProxyClientWithCredentials(t *testing.T, credentials *loginv1alpha1.ClusterCredential, impersonationProxyURL string, impersonationProxyCACertPEM []byte, nestedImpersonationConfig *rest.ImpersonationConfig) *kubeclient.Client { func newImpersonationProxyClientWithCredentials(t *testing.T, credentials *loginv1alpha1.ClusterCredential, impersonationProxyURL string, impersonationProxyCACertPEM []byte, nestedImpersonationConfig *rest.ImpersonationConfig) *kubeclient.Client {
t.Helper() t.Helper()
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
clusterSupportsLoadBalancers := env.HasCapability(library.HasExternalLoadBalancerProvider) clusterSupportsLoadBalancers := env.HasCapability(testlib.HasExternalLoadBalancerProvider)
kubeconfig := impersonationProxyRestConfig(credentials, impersonationProxyURL, impersonationProxyCACertPEM, nestedImpersonationConfig) kubeconfig := impersonationProxyRestConfig(credentials, impersonationProxyURL, impersonationProxyCACertPEM, nestedImpersonationConfig)
if !clusterSupportsLoadBalancers { if !clusterSupportsLoadBalancers {
@ -2000,7 +2000,7 @@ func newImpersonationProxyClientWithCredentials(t *testing.T, credentials *login
// Prefer to go through a load balancer because that's how the impersonator is intended to be used in the real world. // Prefer to go through a load balancer because that's how the impersonator is intended to be used in the real world.
kubeconfig.Proxy = kubeconfigProxyFunc(t, env.Proxy) kubeconfig.Proxy = kubeconfigProxyFunc(t, env.Proxy)
} }
return library.NewKubeclient(t, kubeconfig) return testlib.NewKubeclient(t, kubeconfig)
} }
func newAnonymousImpersonationProxyClient(t *testing.T, impersonationProxyURL string, impersonationProxyCACertPEM []byte, nestedImpersonationConfig *rest.ImpersonationConfig) *kubeclient.Client { func newAnonymousImpersonationProxyClient(t *testing.T, impersonationProxyURL string, impersonationProxyCACertPEM []byte, nestedImpersonationConfig *rest.ImpersonationConfig) *kubeclient.Client {
@ -2013,34 +2013,34 @@ func newAnonymousImpersonationProxyClient(t *testing.T, impersonationProxyURL st
func newImpersonationProxyClientWithCredentialsAndProxy(t *testing.T, credentials *loginv1alpha1.ClusterCredential, impersonationProxyURL string, impersonationProxyCACertPEM []byte, nestedImpersonationConfig *rest.ImpersonationConfig) *kubeclient.Client { func newImpersonationProxyClientWithCredentialsAndProxy(t *testing.T, credentials *loginv1alpha1.ClusterCredential, impersonationProxyURL string, impersonationProxyCACertPEM []byte, nestedImpersonationConfig *rest.ImpersonationConfig) *kubeclient.Client {
t.Helper() t.Helper()
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
kubeconfig := impersonationProxyRestConfig(credentials, impersonationProxyURL, impersonationProxyCACertPEM, nestedImpersonationConfig) kubeconfig := impersonationProxyRestConfig(credentials, impersonationProxyURL, impersonationProxyCACertPEM, nestedImpersonationConfig)
kubeconfig.Proxy = kubeconfigProxyFunc(t, env.Proxy) kubeconfig.Proxy = kubeconfigProxyFunc(t, env.Proxy)
return library.NewKubeclient(t, kubeconfig) return testlib.NewKubeclient(t, kubeconfig)
} }
// this uses a proxy in all cases, the other will only use it if you don't have load balancer capabilities. // this uses a proxy in all cases, the other will only use it if you don't have load balancer capabilities.
func newAnonymousImpersonationProxyClientWithProxy(t *testing.T, impersonationProxyURL string, impersonationProxyCACertPEM []byte, nestedImpersonationConfig *rest.ImpersonationConfig) *kubeclient.Client { func newAnonymousImpersonationProxyClientWithProxy(t *testing.T, impersonationProxyURL string, impersonationProxyCACertPEM []byte, nestedImpersonationConfig *rest.ImpersonationConfig) *kubeclient.Client {
t.Helper() t.Helper()
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
emptyCredentials := &loginv1alpha1.ClusterCredential{} emptyCredentials := &loginv1alpha1.ClusterCredential{}
kubeconfig := impersonationProxyRestConfig(emptyCredentials, impersonationProxyURL, impersonationProxyCACertPEM, nestedImpersonationConfig) kubeconfig := impersonationProxyRestConfig(emptyCredentials, impersonationProxyURL, impersonationProxyCACertPEM, nestedImpersonationConfig)
kubeconfig.Proxy = kubeconfigProxyFunc(t, env.Proxy) kubeconfig.Proxy = kubeconfigProxyFunc(t, env.Proxy)
return library.NewKubeclient(t, kubeconfig) return testlib.NewKubeclient(t, kubeconfig)
} }
func impersonationProxyViaSquidKubeClientWithoutCredential(t *testing.T, proxyServiceEndpoint string) kubernetes.Interface { func impersonationProxyViaSquidKubeClientWithoutCredential(t *testing.T, proxyServiceEndpoint string) kubernetes.Interface {
t.Helper() t.Helper()
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
proxyURL := "https://" + proxyServiceEndpoint proxyURL := "https://" + proxyServiceEndpoint
kubeconfig := impersonationProxyRestConfig(&loginv1alpha1.ClusterCredential{}, proxyURL, nil, nil) kubeconfig := impersonationProxyRestConfig(&loginv1alpha1.ClusterCredential{}, proxyURL, nil, nil)
kubeconfig.Proxy = kubeconfigProxyFunc(t, env.Proxy) kubeconfig.Proxy = kubeconfigProxyFunc(t, env.Proxy)
return library.NewKubeclient(t, kubeconfig).Kubernetes return testlib.NewKubeclient(t, kubeconfig).Kubernetes
} }
func newImpersonationProxyClient( func newImpersonationProxyClient(

View File

@ -17,18 +17,18 @@ import (
"k8s.io/utils/pointer" "k8s.io/utils/pointer"
conciergev1alpha "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1" conciergev1alpha "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestKubeCertAgent(t *testing.T) { func TestKubeCertAgent(t *testing.T) {
env := library.IntegrationEnv(t).WithCapability(library.ClusterSigningKeyIsAvailable) env := testlib.IntegrationEnv(t).WithCapability(testlib.ClusterSigningKeyIsAvailable)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
kubeClient := library.NewKubernetesClientset(t) kubeClient := testlib.NewKubernetesClientset(t)
adminConciergeClient := library.NewConciergeClientset(t) adminConciergeClient := testlib.NewConciergeClientset(t)
// Expect there to be at least on healthy kube-cert-agent pod on this cluster. // Expect there to be at least on healthy kube-cert-agent pod on this cluster.
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
ctx, cancel := context.WithTimeout(ctx, 10*time.Second) ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel() defer cancel()
agentPods, err := kubeClient.CoreV1().Pods(env.ConciergeNamespace).List(ctx, metav1.ListOptions{ agentPods, err := kubeClient.CoreV1().Pods(env.ConciergeNamespace).List(ctx, metav1.ListOptions{
@ -50,7 +50,7 @@ func TestKubeCertAgent(t *testing.T) {
}, 1*time.Minute, 2*time.Second, "never saw a healthy kube-cert-agent Pod running") }, 1*time.Minute, 2*time.Second, "never saw a healthy kube-cert-agent Pod running")
// Expect that the CredentialIssuer will have a healthy KubeClusterSigningCertificate strategy. // Expect that the CredentialIssuer will have a healthy KubeClusterSigningCertificate strategy.
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
ctx, cancel := context.WithTimeout(ctx, 10*time.Second) ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel() defer cancel()
credentialIssuer, err := adminConciergeClient.ConfigV1alpha1().CredentialIssuers().Get(ctx, credentialIssuerName(env), metav1.GetOptions{}) credentialIssuer, err := adminConciergeClient.ConfigV1alpha1().CredentialIssuers().Get(ctx, credentialIssuerName(env), metav1.GetOptions{})
@ -94,10 +94,10 @@ func findSuccessfulStrategy(credentialIssuer *conciergev1alpha.CredentialIssuer,
} }
func TestLegacyPodCleaner(t *testing.T) { func TestLegacyPodCleaner(t *testing.T) {
env := library.IntegrationEnv(t).WithCapability(library.ClusterSigningKeyIsAvailable) env := testlib.IntegrationEnv(t).WithCapability(testlib.ClusterSigningKeyIsAvailable)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel() defer cancel()
kubeClient := library.NewKubernetesClientset(t) kubeClient := testlib.NewKubernetesClientset(t)
// Pick the same labels that the legacy code would have used to run the kube-cert-agent pod. // Pick the same labels that the legacy code would have used to run the kube-cert-agent pod.
legacyAgentLabels := map[string]string{} legacyAgentLabels := map[string]string{}
@ -137,7 +137,7 @@ func TestLegacyPodCleaner(t *testing.T) {
}) })
// Expect the legacy-pod-cleaner controller to delete the pod. // Expect the legacy-pod-cleaner controller to delete the pod.
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
_, err := kubeClient.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) _, err := kubeClient.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{})
if k8serrors.IsNotFound(err) { if k8serrors.IsNotFound(err) {
t.Logf("fake legacy agent pod %s/%s was deleted as expected", pod.Namespace, pod.Name) t.Logf("fake legacy agent pod %s/%s was deleted as expected", pod.Namespace, pod.Name)

View File

@ -10,12 +10,12 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
// Smoke test to see if the kubeconfig works and the cluster is reachable. // Smoke test to see if the kubeconfig works and the cluster is reachable.
func TestGetNodes(t *testing.T) { func TestGetNodes(t *testing.T) {
library.SkipUnlessIntegration(t) testlib.SkipUnlessIntegration(t)
cmd := exec.Command("kubectl", "get", "nodes") cmd := exec.Command("kubectl", "get", "nodes")
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr

View File

@ -42,19 +42,19 @@ import (
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/pkg/oidcclient" "go.pinniped.dev/pkg/oidcclient"
"go.pinniped.dev/pkg/oidcclient/filesession" "go.pinniped.dev/pkg/oidcclient/filesession"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
"go.pinniped.dev/test/library/browsertest" "go.pinniped.dev/test/testlib/browsertest"
) )
// TestE2EFullIntegration tests a full integration scenario that combines the supervisor, concierge, and CLI. // TestE2EFullIntegration tests a full integration scenario that combines the supervisor, concierge, and CLI.
func TestE2EFullIntegration(t *testing.T) { func TestE2EFullIntegration(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
ctx, cancelFunc := context.WithTimeout(context.Background(), 15*time.Minute) ctx, cancelFunc := context.WithTimeout(context.Background(), 15*time.Minute)
defer cancelFunc() defer cancelFunc()
// Build pinniped CLI. // Build pinniped CLI.
pinnipedExe := library.PinnipedCLIPath(t) pinnipedExe := testlib.PinnipedCLIPath(t)
tempDir := testutil.TempDir(t) tempDir := testutil.TempDir(t)
// Start the browser driver. // Start the browser driver.
@ -86,7 +86,7 @@ func TestE2EFullIntegration(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Write the serving cert to a secret. // Write the serving cert to a secret.
certSecret := library.CreateTestSecret(t, certSecret := testlib.CreateTestSecret(t,
env.SupervisorNamespace, env.SupervisorNamespace,
"oidc-provider-tls", "oidc-provider-tls",
corev1.SecretTypeTLS, corev1.SecretTypeTLS,
@ -94,15 +94,15 @@ func TestE2EFullIntegration(t *testing.T) {
) )
// Create the downstream FederationDomain and expect it to go into the success status condition. // Create the downstream FederationDomain and expect it to go into the success status condition.
downstream := library.CreateTestFederationDomain(ctx, t, downstream := testlib.CreateTestFederationDomain(ctx, t,
issuerURL.String(), issuerURL.String(),
certSecret.Name, certSecret.Name,
configv1alpha1.SuccessFederationDomainStatusCondition, configv1alpha1.SuccessFederationDomainStatusCondition,
) )
// Create a JWTAuthenticator that will validate the tokens from the downstream issuer. // Create a JWTAuthenticator that will validate the tokens from the downstream issuer.
clusterAudience := "test-cluster-" + library.RandHex(t, 8) clusterAudience := "test-cluster-" + testlib.RandHex(t, 8)
authenticator := library.CreateTestJWTAuthenticator(ctx, t, authv1alpha.JWTAuthenticatorSpec{ authenticator := testlib.CreateTestJWTAuthenticator(ctx, t, authv1alpha.JWTAuthenticatorSpec{
Issuer: downstream.Spec.Issuer, Issuer: downstream.Spec.Issuer,
Audience: clusterAudience, Audience: clusterAudience,
TLS: &authv1alpha.TLSSpec{CertificateAuthorityData: testCABundleBase64}, TLS: &authv1alpha.TLSSpec{CertificateAuthorityData: testCABundleBase64},
@ -114,11 +114,11 @@ func TestE2EFullIntegration(t *testing.T) {
expectedGroups := env.SupervisorUpstreamOIDC.ExpectedGroups expectedGroups := env.SupervisorUpstreamOIDC.ExpectedGroups
// Create a ClusterRoleBinding to give our test user from the upstream read-only access to the cluster. // Create a ClusterRoleBinding to give our test user from the upstream read-only access to the cluster.
library.CreateTestClusterRoleBinding(t, testlib.CreateTestClusterRoleBinding(t,
rbacv1.Subject{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: expectedUsername}, rbacv1.Subject{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: expectedUsername},
rbacv1.RoleRef{Kind: "ClusterRole", APIGroup: rbacv1.GroupName, Name: "view"}, rbacv1.RoleRef{Kind: "ClusterRole", APIGroup: rbacv1.GroupName, Name: "view"},
) )
library.WaitForUserToHaveAccess(t, expectedUsername, []string{}, &authorizationv1.ResourceAttributes{ testlib.WaitForUserToHaveAccess(t, expectedUsername, []string{}, &authorizationv1.ResourceAttributes{
Verb: "get", Verb: "get",
Group: "", Group: "",
Version: "v1", Version: "v1",
@ -126,7 +126,7 @@ func TestE2EFullIntegration(t *testing.T) {
}) })
// Create upstream OIDC provider and wait for it to become ready. // Create upstream OIDC provider and wait for it to become ready.
library.CreateTestOIDCIdentityProvider(t, idpv1alpha1.OIDCIdentityProviderSpec{ testlib.CreateTestOIDCIdentityProvider(t, idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: env.SupervisorUpstreamOIDC.Issuer, Issuer: env.SupervisorUpstreamOIDC.Issuer,
TLS: &idpv1alpha1.TLSSpec{ TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)),
@ -139,7 +139,7 @@ func TestE2EFullIntegration(t *testing.T) {
Groups: env.SupervisorUpstreamOIDC.GroupsClaim, Groups: env.SupervisorUpstreamOIDC.GroupsClaim,
}, },
Client: idpv1alpha1.OIDCClient{ Client: idpv1alpha1.OIDCClient{
SecretName: library.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name, SecretName: testlib.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name,
}, },
}, idpv1alpha1.PhaseReady) }, idpv1alpha1.PhaseReady)
@ -194,7 +194,7 @@ func TestE2EFullIntegration(t *testing.T) {
} }
}() }()
reader := bufio.NewReader(library.NewLoggerReader(t, "stderr", stderrPipe)) reader := bufio.NewReader(testlib.NewLoggerReader(t, "stderr", stderrPipe))
line, err := reader.ReadString('\n') line, err := reader.ReadString('\n')
if err != nil { if err != nil {
return fmt.Errorf("could not read login URL line from stderr: %w", err) return fmt.Errorf("could not read login URL line from stderr: %w", err)
@ -277,7 +277,7 @@ func TestE2EFullIntegration(t *testing.T) {
// Add an LDAP upstream IDP and try using it to authenticate during kubectl commands. // Add an LDAP upstream IDP and try using it to authenticate during kubectl commands.
t.Run("with Supervisor LDAP upstream IDP", func(t *testing.T) { t.Run("with Supervisor LDAP upstream IDP", func(t *testing.T) {
if len(env.ToolsNamespace) == 0 && !env.HasCapability(library.CanReachInternetLDAPPorts) { if len(env.ToolsNamespace) == 0 && !env.HasCapability(testlib.CanReachInternetLDAPPorts) {
t.Skip("LDAP integration test requires connectivity to an LDAP server") t.Skip("LDAP integration test requires connectivity to an LDAP server")
} }
@ -285,11 +285,11 @@ func TestE2EFullIntegration(t *testing.T) {
expectedGroups := env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs expectedGroups := env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs
// Create a ClusterRoleBinding to give our test user from the upstream read-only access to the cluster. // Create a ClusterRoleBinding to give our test user from the upstream read-only access to the cluster.
library.CreateTestClusterRoleBinding(t, testlib.CreateTestClusterRoleBinding(t,
rbacv1.Subject{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: expectedUsername}, rbacv1.Subject{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: expectedUsername},
rbacv1.RoleRef{Kind: "ClusterRole", APIGroup: rbacv1.GroupName, Name: "view"}, rbacv1.RoleRef{Kind: "ClusterRole", APIGroup: rbacv1.GroupName, Name: "view"},
) )
library.WaitForUserToHaveAccess(t, expectedUsername, []string{}, &authorizationv1.ResourceAttributes{ testlib.WaitForUserToHaveAccess(t, expectedUsername, []string{}, &authorizationv1.ResourceAttributes{
Verb: "get", Verb: "get",
Group: "", Group: "",
Version: "v1", Version: "v1",
@ -297,7 +297,7 @@ func TestE2EFullIntegration(t *testing.T) {
}) })
// Put the bind service account's info into a Secret. // Put the bind service account's info into a Secret.
bindSecret := library.CreateTestSecret(t, env.SupervisorNamespace, "ldap-service-account", corev1.SecretTypeBasicAuth, bindSecret := testlib.CreateTestSecret(t, env.SupervisorNamespace, "ldap-service-account", corev1.SecretTypeBasicAuth,
map[string]string{ map[string]string{
corev1.BasicAuthUsernameKey: env.SupervisorUpstreamLDAP.BindUsername, corev1.BasicAuthUsernameKey: env.SupervisorUpstreamLDAP.BindUsername,
corev1.BasicAuthPasswordKey: env.SupervisorUpstreamLDAP.BindPassword, corev1.BasicAuthPasswordKey: env.SupervisorUpstreamLDAP.BindPassword,
@ -305,7 +305,7 @@ func TestE2EFullIntegration(t *testing.T) {
) )
// Create upstream LDAP provider and wait for it to become ready. // Create upstream LDAP provider and wait for it to become ready.
library.CreateTestLDAPIdentityProvider(t, idpv1alpha1.LDAPIdentityProviderSpec{ testlib.CreateTestLDAPIdentityProvider(t, idpv1alpha1.LDAPIdentityProviderSpec{
Host: env.SupervisorUpstreamLDAP.Host, Host: env.SupervisorUpstreamLDAP.Host,
TLS: &idpv1alpha1.TLSSpec{ TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamLDAP.CABundle)), CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamLDAP.CABundle)),
@ -379,7 +379,7 @@ func TestE2EFullIntegration(t *testing.T) {
func readFromFileUntilStringIsSeen(t *testing.T, f *os.File, until string) { func readFromFileUntilStringIsSeen(t *testing.T, f *os.File, until string) {
readFromFile := "" readFromFile := ""
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
someOutput, foundEOF := readAvailableOutput(t, f) someOutput, foundEOF := readAvailableOutput(t, f)
readFromFile += someOutput readFromFile += someOutput
if strings.Contains(readFromFile, until) { if strings.Contains(readFromFile, until) {
@ -407,7 +407,7 @@ func readAvailableOutput(t *testing.T, r io.Reader) (string, bool) {
func requireUserCanUseKubectlWithoutAuthenticatingAgain( func requireUserCanUseKubectlWithoutAuthenticatingAgain(
ctx context.Context, ctx context.Context,
t *testing.T, t *testing.T,
env *library.TestEnv, env *testlib.TestEnv,
downstream *configv1alpha1.FederationDomain, downstream *configv1alpha1.FederationDomain,
kubeconfigPath string, kubeconfigPath string,
sessionCachePath string, sessionCachePath string,
@ -485,7 +485,7 @@ func requireGCAnnotationsOnSessionStorage(ctx context.Context, t *testing.T, sup
// check that the access token is new (since it's just been refreshed) and has close to two minutes left. // check that the access token is new (since it's just been refreshed) and has close to two minutes left.
testutil.RequireTimeInDelta(t, startTime.Add(2*time.Minute), token.AccessToken.Expiry.Time, 15*time.Second) testutil.RequireTimeInDelta(t, startTime.Add(2*time.Minute), token.AccessToken.Expiry.Time, 15*time.Second)
kubeClient := library.NewKubernetesClientset(t).CoreV1() kubeClient := testlib.NewKubernetesClientset(t).CoreV1()
// get the access token secret that matches the signature from the cache // get the access token secret that matches the signature from the cache
accessTokenSignature := strings.Split(token.AccessToken.Token, ".")[1] accessTokenSignature := strings.Split(token.AccessToken.Token, ".")[1]
@ -515,14 +515,14 @@ func requireGCAnnotationsOnSessionStorage(ctx context.Context, t *testing.T, sup
testutil.RequireTimeInDelta(t, accessTokenGCTime, refreshTokenGCTime, 1*time.Minute) testutil.RequireTimeInDelta(t, accessTokenGCTime, refreshTokenGCTime, 1*time.Minute)
} }
func runPinnipedGetKubeconfig(t *testing.T, env *library.TestEnv, pinnipedExe string, tempDir string, pinnipedCLICommand []string) string { func runPinnipedGetKubeconfig(t *testing.T, env *testlib.TestEnv, pinnipedExe string, tempDir string, pinnipedCLICommand []string) string {
// Run "pinniped get kubeconfig" to get a kubeconfig YAML. // Run "pinniped get kubeconfig" to get a kubeconfig YAML.
envVarsWithProxy := append(os.Environ(), env.ProxyEnv()...) envVarsWithProxy := append(os.Environ(), env.ProxyEnv()...)
kubeconfigYAML, stderr := runPinnipedCLI(t, envVarsWithProxy, pinnipedExe, pinnipedCLICommand...) kubeconfigYAML, stderr := runPinnipedCLI(t, envVarsWithProxy, pinnipedExe, pinnipedCLICommand...)
t.Logf("stderr output from 'pinniped get kubeconfig':\n%s\n\n", stderr) t.Logf("stderr output from 'pinniped get kubeconfig':\n%s\n\n", stderr)
t.Logf("test kubeconfig:\n%s\n\n", kubeconfigYAML) t.Logf("test kubeconfig:\n%s\n\n", kubeconfigYAML)
restConfig := library.NewRestConfigFromKubeconfig(t, kubeconfigYAML) restConfig := testlib.NewRestConfigFromKubeconfig(t, kubeconfigYAML)
require.NotNil(t, restConfig.ExecProvider) require.NotNil(t, restConfig.ExecProvider)
require.Equal(t, []string{"login", "oidc"}, restConfig.ExecProvider.Args[:2]) require.Equal(t, []string{"login", "oidc"}, restConfig.ExecProvider.Args[:2])

View File

@ -16,13 +16,13 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/discovery" "k8s.io/client-go/discovery"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestGetAPIResourceList(t *testing.T) { func TestGetAPIResourceList(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
client := library.NewKubernetesClientset(t) client := testlib.NewKubernetesClientset(t)
groups, resources, err := client.Discovery().ServerGroupsAndResources() groups, resources, err := client.Discovery().ServerGroupsAndResources()
// discovery can have partial failures when an API service is unavailable (i.e. because of TestAPIServingCertificateAutoCreationAndRotation) // discovery can have partial failures when an API service is unavailable (i.e. because of TestAPIServingCertificateAutoCreationAndRotation)

View File

@ -22,14 +22,14 @@ import (
"go.pinniped.dev/internal/groupsuffix" "go.pinniped.dev/internal/groupsuffix"
"go.pinniped.dev/internal/kubeclient" "go.pinniped.dev/internal/kubeclient"
"go.pinniped.dev/internal/ownerref" "go.pinniped.dev/internal/ownerref"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestKubeClientOwnerRef(t *testing.T) { func TestKubeClientOwnerRef(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
regularClient := library.NewKubernetesClientset(t) regularClient := testlib.NewKubernetesClientset(t)
regularAggregationClient := library.NewAggregatedClientset(t) regularAggregationClient := testlib.NewAggregatedClientset(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
@ -75,7 +75,7 @@ func TestKubeClientOwnerRef(t *testing.T) {
UID: parentSecret.UID, UID: parentSecret.UID,
} }
snorlaxAPIGroup := fmt.Sprintf("%s.snorlax.dev", library.RandHex(t, 8)) snorlaxAPIGroup := fmt.Sprintf("%s.snorlax.dev", testlib.RandHex(t, 8))
parentAPIService, err := regularAggregationClient.ApiregistrationV1().APIServices().Create( parentAPIService, err := regularAggregationClient.ApiregistrationV1().APIServices().Create(
ctx, ctx,
&apiregistrationv1.APIService{ &apiregistrationv1.APIService{
@ -114,7 +114,7 @@ func TestKubeClientOwnerRef(t *testing.T) {
UID: parentAPIService.UID, UID: parentAPIService.UID,
} }
apiServiceRef, err := apiserviceref.New(parentAPIService.Name, kubeclient.WithConfig(library.NewClientConfig(t))) apiServiceRef, err := apiserviceref.New(parentAPIService.Name, kubeclient.WithConfig(testlib.NewClientConfig(t)))
require.NoError(t, err) require.NoError(t, err)
// create a client that should set an owner ref back to parent on create // create a client that should set an owner ref back to parent on create
@ -122,7 +122,7 @@ func TestKubeClientOwnerRef(t *testing.T) {
kubeclient.WithMiddleware(ownerref.New(parentSecret)), // secret owner ref first when possible kubeclient.WithMiddleware(ownerref.New(parentSecret)), // secret owner ref first when possible
apiServiceRef, // api service for everything else apiServiceRef, // api service for everything else
kubeclient.WithMiddleware(groupsuffix.New(env.APIGroupSuffix)), kubeclient.WithMiddleware(groupsuffix.New(env.APIGroupSuffix)),
kubeclient.WithConfig(library.NewClientConfig(t)), kubeclient.WithConfig(testlib.NewClientConfig(t)),
) )
require.NoError(t, err) require.NoError(t, err)
@ -188,7 +188,7 @@ func TestKubeClientOwnerRef(t *testing.T) {
}) })
// cluster scoped API service should be owned by the other one we created above // cluster scoped API service should be owned by the other one we created above
pandasAPIGroup := fmt.Sprintf("%s.pandas.dev", library.RandHex(t, 8)) pandasAPIGroup := fmt.Sprintf("%s.pandas.dev", testlib.RandHex(t, 8))
apiService, err := ownerRefClient.Aggregation.ApiregistrationV1().APIServices().Create( apiService, err := ownerRefClient.Aggregation.ApiregistrationV1().APIServices().Create(
ctx, ctx,
&apiregistrationv1.APIService{ &apiregistrationv1.APIService{
@ -305,7 +305,7 @@ func hasOwnerRef(t *testing.T, obj metav1.Object, ref metav1.OwnerReference) {
func isEventuallyDeleted(t *testing.T, f func() error) { func isEventuallyDeleted(t *testing.T, f func() error) {
t.Helper() t.Helper()
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
err := f() err := f()
switch { switch {
case err == nil: case err == nil:

View File

@ -21,11 +21,11 @@ import (
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
"go.pinniped.dev/internal/upstreamldap" "go.pinniped.dev/internal/upstreamldap"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestLDAPSearch(t *testing.T) { func TestLDAPSearch(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
// Note that these tests depend on the values hard-coded in the LDIF file in test/deploy/tools/ldap.yaml. // Note that these tests depend on the values hard-coded in the LDIF file in test/deploy/tools/ldap.yaml.
// It requires the test LDAP server from the tools deployment. // It requires the test LDAP server from the tools deployment.
@ -613,7 +613,7 @@ func TestLDAPSearch(t *testing.T) {
} }
func TestSimultaneousLDAPRequestsOnSingleProvider(t *testing.T) { func TestSimultaneousLDAPRequestsOnSingleProvider(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
// Note that these tests depend on the values hard-coded in the LDIF file in test/deploy/tools/ldap.yaml. // Note that these tests depend on the values hard-coded in the LDIF file in test/deploy/tools/ldap.yaml.
// It requires the test LDAP server from the tools deployment. // It requires the test LDAP server from the tools deployment.
@ -673,7 +673,7 @@ type authUserResult struct {
err error err error
} }
func defaultProviderConfig(env *library.TestEnv, port string) *upstreamldap.ProviderConfig { func defaultProviderConfig(env *testlib.TestEnv, port string) *upstreamldap.ProviderConfig {
return &upstreamldap.ProviderConfig{ return &upstreamldap.ProviderConfig{
Name: "test-ldap-provider", Name: "test-ldap-provider",
Host: "127.0.0.1:" + port, Host: "127.0.0.1:" + port,
@ -775,7 +775,7 @@ func startLongRunningCommandAndWaitForInitialOutput(
require.NoError(t, err) require.NoError(t, err)
}) })
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
t.Logf(`Waiting for %s to emit output: "%s"`, command, waitForOutputToContain) t.Logf(`Waiting for %s to emit output: "%s"`, command, waitForOutputToContain)
requireEventually.Equal(-1, cmd.ProcessState.ExitCode(), "subcommand ended sooner than expected") requireEventually.Equal(-1, cmd.ProcessState.ExitCode(), "subcommand ended sooner than expected")
requireEventually.Contains(watchOn.String(), waitForOutputToContain, "expected process to emit output") requireEventually.Contains(watchOn.String(), waitForOutputToContain, "expected process to emit output")

View File

@ -19,20 +19,20 @@ import (
v1 "k8s.io/client-go/kubernetes/typed/authorization/v1" v1 "k8s.io/client-go/kubernetes/typed/authorization/v1"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestServiceAccountPermissions(t *testing.T) { func TestServiceAccountPermissions(t *testing.T) {
// TODO: update this test to check the permissions of all service accounts // TODO: update this test to check the permissions of all service accounts
// For now it just checks the permissions of the impersonation proxy SA // For now it just checks the permissions of the impersonation proxy SA
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
defer cancel() defer cancel()
// impersonate the SA since it is easier than fetching a token and lets us control the group memberships // impersonate the SA since it is easier than fetching a token and lets us control the group memberships
config := rest.CopyConfig(library.NewClientConfig(t)) config := rest.CopyConfig(testlib.NewClientConfig(t))
config.Impersonate = rest.ImpersonationConfig{ config.Impersonate = rest.ImpersonationConfig{
UserName: serviceaccount.MakeUsername(env.ConciergeNamespace, env.ConciergeAppName+"-impersonation-proxy"), UserName: serviceaccount.MakeUsername(env.ConciergeNamespace, env.ConciergeAppName+"-impersonation-proxy"),
// avoid permissions assigned to system:serviceaccounts by explicitly impersonating system:serviceaccounts:<namespace> // avoid permissions assigned to system:serviceaccounts by explicitly impersonating system:serviceaccounts:<namespace>
@ -42,7 +42,7 @@ func TestServiceAccountPermissions(t *testing.T) {
Groups: []string{serviceaccount.MakeNamespaceGroupName(env.ConciergeNamespace), user.AllAuthenticated}, Groups: []string{serviceaccount.MakeNamespaceGroupName(env.ConciergeNamespace), user.AllAuthenticated},
} }
ssrrClient := library.NewKubeclient(t, config).Kubernetes.AuthorizationV1().SelfSubjectRulesReviews() ssrrClient := testlib.NewKubeclient(t, config).Kubernetes.AuthorizationV1().SelfSubjectRulesReviews()
// the impersonation proxy SA has the same permissions for all checks because it should only be authorized via cluster role bindings // the impersonation proxy SA has the same permissions for all checks because it should only be authorized via cluster role bindings
@ -67,7 +67,7 @@ func TestServiceAccountPermissions(t *testing.T) {
) )
} }
crbs, err := library.NewKubernetesClientset(t).RbacV1().ClusterRoleBindings().List(ctx, metav1.ListOptions{LabelSelector: "eks.amazonaws.com/component=pod-security-policy"}) crbs, err := testlib.NewKubernetesClientset(t).RbacV1().ClusterRoleBindings().List(ctx, metav1.ListOptions{LabelSelector: "eks.amazonaws.com/component=pod-security-policy"})
require.NoError(t, err) require.NoError(t, err)
if len(crbs.Items) > 0 { if len(crbs.Items) > 0 {
expectedResourceRules = append(expectedResourceRules, expectedResourceRules = append(expectedResourceRules,
@ -121,14 +121,14 @@ func testPermissionsInNamespace(ctx context.Context, t *testing.T, ssrrClient v1
func getOtherPinnipedGroupSuffix(t *testing.T) string { func getOtherPinnipedGroupSuffix(t *testing.T) string {
t.Helper() t.Helper()
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
var resources []*metav1.APIResourceList var resources []*metav1.APIResourceList
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
// we need a complete discovery listing for the check we are trying to make below // we need a complete discovery listing for the check we are trying to make below
// loop since tests like TestAPIServingCertificateAutoCreationAndRotation can break discovery // loop since tests like TestAPIServingCertificateAutoCreationAndRotation can break discovery
_, r, err := library.NewKubernetesClientset(t).Discovery().ServerGroupsAndResources() _, r, err := testlib.NewKubernetesClientset(t).Discovery().ServerGroupsAndResources()
if err != nil { if err != nil {
t.Logf("retrying due to partial discovery failure: %v", err) t.Logf("retrying due to partial discovery failure: %v", err)
return false, nil return false, nil

View File

@ -28,7 +28,7 @@ import (
pinnipedclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned" pinnipedclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
"go.pinniped.dev/internal/certauthority" "go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/internal/here" "go.pinniped.dev/internal/here"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
// This test is intended to exercise the supervisor's HTTP port 8080. It can either access it directly via // This test is intended to exercise the supervisor's HTTP port 8080. It can either access it directly via
@ -40,15 +40,15 @@ import (
// Testing talking to the supervisor's port 8443 where the supervisor is terminating TLS itself is // Testing talking to the supervisor's port 8443 where the supervisor is terminating TLS itself is
// handled by the others tests in this file. // handled by the others tests in this file.
func TestSupervisorOIDCDiscovery(t *testing.T) { func TestSupervisorOIDCDiscovery(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
client := library.NewSupervisorClientset(t) client := testlib.NewSupervisorClientset(t)
ns := env.SupervisorNamespace ns := env.SupervisorNamespace
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel() defer cancel()
temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(ctx, t, ns, defaultTLSCertSecretName(env), client, library.NewKubernetesClientset(t)) temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(ctx, t, ns, defaultTLSCertSecretName(env), client, testlib.NewKubernetesClientset(t))
tests := []struct { tests := []struct {
Scheme string Scheme string
@ -111,7 +111,7 @@ func TestSupervisorOIDCDiscovery(t *testing.T) {
// When the same issuer is added twice, both issuers are marked as duplicates, and neither provider is serving. // When the same issuer is added twice, both issuers are marked as duplicates, and neither provider is serving.
config6Duplicate1, _ := requireCreatingFederationDomainCausesDiscoveryEndpointsToAppear(ctx, t, scheme, addr, caBundle, issuer6, client) config6Duplicate1, _ := requireCreatingFederationDomainCausesDiscoveryEndpointsToAppear(ctx, t, scheme, addr, caBundle, issuer6, client)
config6Duplicate2 := library.CreateTestFederationDomain(ctx, t, issuer6, "", "") config6Duplicate2 := testlib.CreateTestFederationDomain(ctx, t, issuer6, "", "")
requireStatus(t, client, ns, config6Duplicate1.Name, v1alpha1.DuplicateFederationDomainStatusCondition) requireStatus(t, client, ns, config6Duplicate1.Name, v1alpha1.DuplicateFederationDomainStatusCondition)
requireStatus(t, client, ns, config6Duplicate2.Name, v1alpha1.DuplicateFederationDomainStatusCondition) requireStatus(t, client, ns, config6Duplicate2.Name, v1alpha1.DuplicateFederationDomainStatusCondition)
requireDiscoveryEndpointsAreNotFound(t, scheme, addr, caBundle, issuer6) requireDiscoveryEndpointsAreNotFound(t, scheme, addr, caBundle, issuer6)
@ -136,7 +136,7 @@ func TestSupervisorOIDCDiscovery(t *testing.T) {
} }
// When we create a provider with an invalid issuer, the status is set to invalid. // When we create a provider with an invalid issuer, the status is set to invalid.
badConfig := library.CreateTestFederationDomain(ctx, t, badIssuer, "", "") badConfig := testlib.CreateTestFederationDomain(ctx, t, badIssuer, "", "")
requireStatus(t, client, ns, badConfig.Name, v1alpha1.InvalidFederationDomainStatusCondition) requireStatus(t, client, ns, badConfig.Name, v1alpha1.InvalidFederationDomainStatusCondition)
requireDiscoveryEndpointsAreNotFound(t, scheme, addr, caBundle, badIssuer) requireDiscoveryEndpointsAreNotFound(t, scheme, addr, caBundle, badIssuer)
requireDeletingFederationDomainCausesDiscoveryEndpointsToDisappear(t, badConfig, client, ns, scheme, addr, caBundle, badIssuer) requireDeletingFederationDomainCausesDiscoveryEndpointsToDisappear(t, badConfig, client, ns, scheme, addr, caBundle, badIssuer)
@ -144,9 +144,9 @@ func TestSupervisorOIDCDiscovery(t *testing.T) {
} }
func TestSupervisorTLSTerminationWithSNI(t *testing.T) { func TestSupervisorTLSTerminationWithSNI(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
pinnipedClient := library.NewSupervisorClientset(t) pinnipedClient := testlib.NewSupervisorClientset(t)
kubeClient := library.NewKubernetesClientset(t) kubeClient := testlib.NewKubernetesClientset(t)
ns := env.SupervisorNamespace ns := env.SupervisorNamespace
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
@ -162,7 +162,7 @@ func TestSupervisorTLSTerminationWithSNI(t *testing.T) {
certSecretName1 := "integration-test-cert-1" certSecretName1 := "integration-test-cert-1"
// Create an FederationDomain with a spec.tls.secretName. // Create an FederationDomain with a spec.tls.secretName.
federationDomain1 := library.CreateTestFederationDomain(ctx, t, issuer1, certSecretName1, "") federationDomain1 := testlib.CreateTestFederationDomain(ctx, t, issuer1, certSecretName1, "")
requireStatus(t, pinnipedClient, federationDomain1.Namespace, federationDomain1.Name, v1alpha1.SuccessFederationDomainStatusCondition) requireStatus(t, pinnipedClient, federationDomain1.Namespace, federationDomain1.Name, v1alpha1.SuccessFederationDomainStatusCondition)
// The spec.tls.secretName Secret does not exist, so the endpoints should fail with TLS errors. // The spec.tls.secretName Secret does not exist, so the endpoints should fail with TLS errors.
@ -202,7 +202,7 @@ func TestSupervisorTLSTerminationWithSNI(t *testing.T) {
certSecretName2 := "integration-test-cert-2" certSecretName2 := "integration-test-cert-2"
// Create an FederationDomain with a spec.tls.secretName. // Create an FederationDomain with a spec.tls.secretName.
federationDomain2 := library.CreateTestFederationDomain(ctx, t, issuer2, certSecretName2, "") federationDomain2 := testlib.CreateTestFederationDomain(ctx, t, issuer2, certSecretName2, "")
requireStatus(t, pinnipedClient, federationDomain2.Namespace, federationDomain2.Name, v1alpha1.SuccessFederationDomainStatusCondition) requireStatus(t, pinnipedClient, federationDomain2.Namespace, federationDomain2.Name, v1alpha1.SuccessFederationDomainStatusCondition)
// Create the Secret. // Create the Secret.
@ -215,9 +215,9 @@ func TestSupervisorTLSTerminationWithSNI(t *testing.T) {
} }
func TestSupervisorTLSTerminationWithDefaultCerts(t *testing.T) { func TestSupervisorTLSTerminationWithDefaultCerts(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
pinnipedClient := library.NewSupervisorClientset(t) pinnipedClient := testlib.NewSupervisorClientset(t)
kubeClient := library.NewKubernetesClientset(t) kubeClient := testlib.NewKubernetesClientset(t)
ns := env.SupervisorNamespace ns := env.SupervisorNamespace
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
@ -236,7 +236,7 @@ func TestSupervisorTLSTerminationWithDefaultCerts(t *testing.T) {
port = hostAndPortSegments[1] port = hostAndPortSegments[1]
} }
ips, err := library.LookupIP(ctx, hostname) ips, err := testlib.LookupIP(ctx, hostname)
require.NoError(t, err) require.NoError(t, err)
require.NotEmpty(t, ips) require.NotEmpty(t, ips)
ipWithPort := ips[0].String() + ":" + port ipWithPort := ips[0].String() + ":" + port
@ -245,7 +245,7 @@ func TestSupervisorTLSTerminationWithDefaultCerts(t *testing.T) {
issuerUsingHostname := fmt.Sprintf("%s://%s/issuer1", scheme, address) issuerUsingHostname := fmt.Sprintf("%s://%s/issuer1", scheme, address)
// Create an FederationDomain without a spec.tls.secretName. // Create an FederationDomain without a spec.tls.secretName.
federationDomain1 := library.CreateTestFederationDomain(ctx, t, issuerUsingIPAddress, "", "") federationDomain1 := testlib.CreateTestFederationDomain(ctx, t, issuerUsingIPAddress, "", "")
requireStatus(t, pinnipedClient, federationDomain1.Namespace, federationDomain1.Name, v1alpha1.SuccessFederationDomainStatusCondition) requireStatus(t, pinnipedClient, federationDomain1.Namespace, federationDomain1.Name, v1alpha1.SuccessFederationDomainStatusCondition)
// There is no default TLS cert and the spec.tls.secretName was not set, so the endpoints should fail with TLS errors. // There is no default TLS cert and the spec.tls.secretName was not set, so the endpoints should fail with TLS errors.
@ -259,7 +259,7 @@ func TestSupervisorTLSTerminationWithDefaultCerts(t *testing.T) {
// Create an FederationDomain with a spec.tls.secretName. // Create an FederationDomain with a spec.tls.secretName.
certSecretName := "integration-test-cert-1" certSecretName := "integration-test-cert-1"
federationDomain2 := library.CreateTestFederationDomain(ctx, t, issuerUsingHostname, certSecretName, "") federationDomain2 := testlib.CreateTestFederationDomain(ctx, t, issuerUsingHostname, certSecretName, "")
requireStatus(t, pinnipedClient, federationDomain2.Namespace, federationDomain2.Name, v1alpha1.SuccessFederationDomainStatusCondition) requireStatus(t, pinnipedClient, federationDomain2.Namespace, federationDomain2.Name, v1alpha1.SuccessFederationDomainStatusCondition)
// Create the Secret. // Create the Secret.
@ -274,7 +274,7 @@ func TestSupervisorTLSTerminationWithDefaultCerts(t *testing.T) {
_ = requireDiscoveryEndpointsAreWorking(t, scheme, ipWithPort, string(defaultCA.Bundle()), issuerUsingIPAddress, nil) _ = requireDiscoveryEndpointsAreWorking(t, scheme, ipWithPort, string(defaultCA.Bundle()), issuerUsingIPAddress, nil)
} }
func defaultTLSCertSecretName(env *library.TestEnv) string { func defaultTLSCertSecretName(env *testlib.TestEnv) string {
return env.SupervisorAppName + "-default-tls-certificate" //nolint:gosec // this is not a hardcoded credential return env.SupervisorAppName + "-default-tls-certificate" //nolint:gosec // this is not a hardcoded credential
} }
@ -397,7 +397,7 @@ func requireEndpointNotFound(t *testing.T, url, host, caBundle string) {
requestNonExistentPath.Host = host requestNonExistentPath.Host = host
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
response, err := httpClient.Do(requestNonExistentPath) response, err := httpClient.Do(requestNonExistentPath)
requireEventually.NoError(err) requireEventually.NoError(err)
requireEventually.NoError(response.Body.Close()) requireEventually.NoError(response.Body.Close())
@ -411,7 +411,7 @@ func requireEndpointHasTLSErrorBecauseCertificatesAreNotReady(t *testing.T, url
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel() defer cancel()
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
requireEventually.NoError(err) requireEventually.NoError(err)
@ -432,7 +432,7 @@ func requireCreatingFederationDomainCausesDiscoveryEndpointsToAppear(
client pinnipedclientset.Interface, client pinnipedclientset.Interface,
) (*v1alpha1.FederationDomain, *ExpectedJWKSResponseFormat) { ) (*v1alpha1.FederationDomain, *ExpectedJWKSResponseFormat) {
t.Helper() t.Helper()
newFederationDomain := library.CreateTestFederationDomain(ctx, t, issuerName, "", "") newFederationDomain := testlib.CreateTestFederationDomain(ctx, t, issuerName, "", "")
jwksResult := requireDiscoveryEndpointsAreWorking(t, supervisorScheme, supervisorAddress, supervisorCABundle, issuerName, nil) jwksResult := requireDiscoveryEndpointsAreWorking(t, supervisorScheme, supervisorAddress, supervisorCABundle, issuerName, nil)
requireStatus(t, client, newFederationDomain.Namespace, newFederationDomain.Name, v1alpha1.SuccessFederationDomainStatusCondition) requireStatus(t, client, newFederationDomain.Namespace, newFederationDomain.Name, v1alpha1.SuccessFederationDomainStatusCondition)
return newFederationDomain, jwksResult return newFederationDomain, jwksResult
@ -552,7 +552,7 @@ func requireSuccessEndpointResponse(t *testing.T, endpointURL, issuer, caBundle
// Fetch that discovery endpoint. Give it some time for the endpoint to come into existence. // Fetch that discovery endpoint. Give it some time for the endpoint to come into existence.
var response *http.Response var response *http.Response
var responseBody []byte var responseBody []byte
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
var err error var err error
response, err = httpClient.Do(requestDiscoveryEndpoint) response, err = httpClient.Do(requestDiscoveryEndpoint)
requireEventually.NoError(err) requireEventually.NoError(err)
@ -603,7 +603,7 @@ func requireDelete(t *testing.T, client pinnipedclientset.Interface, ns, name st
func requireStatus(t *testing.T, client pinnipedclientset.Interface, ns, name string, status v1alpha1.FederationDomainStatusCondition) { func requireStatus(t *testing.T, client pinnipedclientset.Interface, ns, name string, status v1alpha1.FederationDomainStatusCondition) {
t.Helper() t.Helper()
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel() defer cancel()

View File

@ -13,7 +13,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
// The Supervisor health endpoint is public because that makes it easier // The Supervisor health endpoint is public because that makes it easier
@ -23,7 +23,7 @@ import (
// happen on a private container port at this time. // happen on a private container port at this time.
// This test checks that it is working and that it is public. // This test checks that it is working and that it is public.
func TestSupervisorHealthz(t *testing.T) { func TestSupervisorHealthz(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
if env.SupervisorHTTPAddress == "" { if env.SupervisorHTTPAddress == "" {
t.Skip("PINNIPED_TEST_SUPERVISOR_HTTP_ADDRESS not defined") t.Skip("PINNIPED_TEST_SUPERVISOR_HTTP_ADDRESS not defined")

View File

@ -32,12 +32,12 @@ import (
"go.pinniped.dev/pkg/oidcclient/nonce" "go.pinniped.dev/pkg/oidcclient/nonce"
"go.pinniped.dev/pkg/oidcclient/pkce" "go.pinniped.dev/pkg/oidcclient/pkce"
"go.pinniped.dev/pkg/oidcclient/state" "go.pinniped.dev/pkg/oidcclient/state"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
"go.pinniped.dev/test/library/browsertest" "go.pinniped.dev/test/testlib/browsertest"
) )
func TestSupervisorLogin(t *testing.T) { func TestSupervisorLogin(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
tests := []struct { tests := []struct {
name string name string
@ -55,13 +55,13 @@ func TestSupervisorLogin(t *testing.T) {
}, },
createIDP: func(t *testing.T) { createIDP: func(t *testing.T) {
t.Helper() t.Helper()
library.CreateTestOIDCIdentityProvider(t, idpv1alpha1.OIDCIdentityProviderSpec{ testlib.CreateTestOIDCIdentityProvider(t, idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: env.SupervisorUpstreamOIDC.Issuer, Issuer: env.SupervisorUpstreamOIDC.Issuer,
TLS: &idpv1alpha1.TLSSpec{ TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)),
}, },
Client: idpv1alpha1.OIDCClient{ Client: idpv1alpha1.OIDCClient{
SecretName: library.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name, SecretName: testlib.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name,
}, },
}, idpv1alpha1.PhaseReady) }, idpv1alpha1.PhaseReady)
}, },
@ -78,13 +78,13 @@ func TestSupervisorLogin(t *testing.T) {
}, },
createIDP: func(t *testing.T) { createIDP: func(t *testing.T) {
t.Helper() t.Helper()
library.CreateTestOIDCIdentityProvider(t, idpv1alpha1.OIDCIdentityProviderSpec{ testlib.CreateTestOIDCIdentityProvider(t, idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: env.SupervisorUpstreamOIDC.Issuer, Issuer: env.SupervisorUpstreamOIDC.Issuer,
TLS: &idpv1alpha1.TLSSpec{ TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)),
}, },
Client: idpv1alpha1.OIDCClient{ Client: idpv1alpha1.OIDCClient{
SecretName: library.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name, SecretName: testlib.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name,
}, },
Claims: idpv1alpha1.OIDCClaims{ Claims: idpv1alpha1.OIDCClaims{
Username: env.SupervisorUpstreamOIDC.UsernameClaim, Username: env.SupervisorUpstreamOIDC.UsernameClaim,
@ -104,19 +104,19 @@ func TestSupervisorLogin(t *testing.T) {
name: "ldap with email as username and groups names as DNs and using an LDAP provider which supports TLS", name: "ldap with email as username and groups names as DNs and using an LDAP provider which supports TLS",
maybeSkip: func(t *testing.T) { maybeSkip: func(t *testing.T) {
t.Helper() t.Helper()
if len(env.ToolsNamespace) == 0 && !env.HasCapability(library.CanReachInternetLDAPPorts) { if len(env.ToolsNamespace) == 0 && !env.HasCapability(testlib.CanReachInternetLDAPPorts) {
t.Skip("LDAP integration test requires connectivity to an LDAP server") t.Skip("LDAP integration test requires connectivity to an LDAP server")
} }
}, },
createIDP: func(t *testing.T) { createIDP: func(t *testing.T) {
t.Helper() t.Helper()
secret := library.CreateTestSecret(t, env.SupervisorNamespace, "ldap-service-account", v1.SecretTypeBasicAuth, secret := testlib.CreateTestSecret(t, env.SupervisorNamespace, "ldap-service-account", v1.SecretTypeBasicAuth,
map[string]string{ map[string]string{
v1.BasicAuthUsernameKey: env.SupervisorUpstreamLDAP.BindUsername, v1.BasicAuthUsernameKey: env.SupervisorUpstreamLDAP.BindUsername,
v1.BasicAuthPasswordKey: env.SupervisorUpstreamLDAP.BindPassword, v1.BasicAuthPasswordKey: env.SupervisorUpstreamLDAP.BindPassword,
}, },
) )
ldapIDP := library.CreateTestLDAPIdentityProvider(t, idpv1alpha1.LDAPIdentityProviderSpec{ ldapIDP := testlib.CreateTestLDAPIdentityProvider(t, idpv1alpha1.LDAPIdentityProviderSpec{
Host: env.SupervisorUpstreamLDAP.Host, Host: env.SupervisorUpstreamLDAP.Host,
TLS: &idpv1alpha1.TLSSpec{ TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamLDAP.CABundle)), CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamLDAP.CABundle)),
@ -169,19 +169,19 @@ func TestSupervisorLogin(t *testing.T) {
name: "ldap with CN as username and group names as CNs and using an LDAP provider which only supports StartTLS", // try another variation of configuration options name: "ldap with CN as username and group names as CNs and using an LDAP provider which only supports StartTLS", // try another variation of configuration options
maybeSkip: func(t *testing.T) { maybeSkip: func(t *testing.T) {
t.Helper() t.Helper()
if len(env.ToolsNamespace) == 0 && !env.HasCapability(library.CanReachInternetLDAPPorts) { if len(env.ToolsNamespace) == 0 && !env.HasCapability(testlib.CanReachInternetLDAPPorts) {
t.Skip("LDAP integration test requires connectivity to an LDAP server") t.Skip("LDAP integration test requires connectivity to an LDAP server")
} }
}, },
createIDP: func(t *testing.T) { createIDP: func(t *testing.T) {
t.Helper() t.Helper()
secret := library.CreateTestSecret(t, env.SupervisorNamespace, "ldap-service-account", v1.SecretTypeBasicAuth, secret := testlib.CreateTestSecret(t, env.SupervisorNamespace, "ldap-service-account", v1.SecretTypeBasicAuth,
map[string]string{ map[string]string{
v1.BasicAuthUsernameKey: env.SupervisorUpstreamLDAP.BindUsername, v1.BasicAuthUsernameKey: env.SupervisorUpstreamLDAP.BindUsername,
v1.BasicAuthPasswordKey: env.SupervisorUpstreamLDAP.BindPassword, v1.BasicAuthPasswordKey: env.SupervisorUpstreamLDAP.BindPassword,
}, },
) )
ldapIDP := library.CreateTestLDAPIdentityProvider(t, idpv1alpha1.LDAPIdentityProviderSpec{ ldapIDP := testlib.CreateTestLDAPIdentityProvider(t, idpv1alpha1.LDAPIdentityProviderSpec{
Host: env.SupervisorUpstreamLDAP.StartTLSOnlyHost, Host: env.SupervisorUpstreamLDAP.StartTLSOnlyHost,
TLS: &idpv1alpha1.TLSSpec{ TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamLDAP.CABundle)), CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamLDAP.CABundle)),
@ -278,7 +278,7 @@ func testSupervisorLogin(
requestAuthorization func(t *testing.T, downstreamAuthorizeURL, downstreamCallbackURL string, httpClient *http.Client), requestAuthorization func(t *testing.T, downstreamAuthorizeURL, downstreamCallbackURL string, httpClient *http.Client),
wantDownstreamIDTokenSubjectToMatch, wantDownstreamIDTokenUsernameToMatch string, wantDownstreamIDTokenGroups []string, wantDownstreamIDTokenSubjectToMatch, wantDownstreamIDTokenUsernameToMatch string, wantDownstreamIDTokenGroups []string,
) { ) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel() defer cancel()
@ -305,12 +305,12 @@ func testSupervisorLogin(
return nil, nil return nil, nil
} }
if env.Proxy == "" { if env.Proxy == "" {
t.Logf("passing request for %s with no proxy", library.RedactURLParams(req.URL)) t.Logf("passing request for %s with no proxy", testlib.RedactURLParams(req.URL))
return nil, nil return nil, nil
} }
proxyURL, err := url.Parse(env.Proxy) proxyURL, err := url.Parse(env.Proxy)
require.NoError(t, err) require.NoError(t, err)
t.Logf("passing request for %s through proxy %s", library.RedactURLParams(req.URL), proxyURL.String()) t.Logf("passing request for %s through proxy %s", testlib.RedactURLParams(req.URL), proxyURL.String())
return proxyURL, nil return proxyURL, nil
}, },
}, },
@ -329,7 +329,7 @@ func testSupervisorLogin(
require.NoError(t, err) require.NoError(t, err)
// Write the serving cert to a secret. // Write the serving cert to a secret.
certSecret := library.CreateTestSecret(t, certSecret := testlib.CreateTestSecret(t,
env.SupervisorNamespace, env.SupervisorNamespace,
"oidc-provider-tls", "oidc-provider-tls",
v1.SecretTypeTLS, v1.SecretTypeTLS,
@ -337,7 +337,7 @@ func testSupervisorLogin(
) )
// Create the downstream FederationDomain and expect it to go into the success status condition. // Create the downstream FederationDomain and expect it to go into the success status condition.
downstream := library.CreateTestFederationDomain(ctx, t, downstream := testlib.CreateTestFederationDomain(ctx, t,
issuerURL.String(), issuerURL.String(),
certSecret.Name, certSecret.Name,
configv1alpha1.SuccessFederationDomainStatusCondition, configv1alpha1.SuccessFederationDomainStatusCondition,
@ -354,7 +354,7 @@ func testSupervisorLogin(
nil, nil,
) )
require.NoError(t, err) require.NoError(t, err)
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
rsp, err := httpClient.Do(requestJWKSEndpoint) rsp, err := httpClient.Do(requestJWKSEndpoint)
requireEventually.NoError(err) requireEventually.NoError(err)
requireEventually.NoError(rsp.Body.Close()) requireEventually.NoError(rsp.Body.Close())
@ -366,7 +366,7 @@ func testSupervisorLogin(
// Perform OIDC discovery for our downstream. // Perform OIDC discovery for our downstream.
var discovery *coreosoidc.Provider var discovery *coreosoidc.Provider
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
var err error var err error
discovery, err = coreosoidc.NewProvider(oidcHTTPClientContext, downstream.Spec.Issuer) discovery, err = coreosoidc.NewProvider(oidcHTTPClientContext, downstream.Spec.Issuer)
requireEventually.NoError(err) requireEventually.NoError(err)
@ -403,7 +403,7 @@ func testSupervisorLogin(
// Expect that our callback handler was invoked. // Expect that our callback handler was invoked.
callback := localCallbackServer.waitForCallback(10 * time.Second) callback := localCallbackServer.waitForCallback(10 * time.Second)
t.Logf("got callback request: %s", library.MaskTokens(callback.URL.String())) t.Logf("got callback request: %s", testlib.MaskTokens(callback.URL.String()))
require.Equal(t, stateParam.String(), callback.URL.Query().Get("state")) require.Equal(t, stateParam.String(), callback.URL.Query().Get("state"))
require.ElementsMatch(t, []string{"openid", "pinniped:request-audience", "offline_access"}, strings.Split(callback.URL.Query().Get("scope"), " ")) require.ElementsMatch(t, []string{"openid", "pinniped:request-audience", "offline_access"}, strings.Split(callback.URL.Query().Get("scope"), " "))
authcode := callback.URL.Query().Get("code") authcode := callback.URL.Query().Get("code")
@ -497,7 +497,7 @@ func verifyTokenResponse(
func requestAuthorizationUsingOIDCIdentityProvider(t *testing.T, downstreamAuthorizeURL, downstreamCallbackURL string, httpClient *http.Client) { func requestAuthorizationUsingOIDCIdentityProvider(t *testing.T, downstreamAuthorizeURL, downstreamCallbackURL string, httpClient *http.Client) {
t.Helper() t.Helper()
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
ctx, cancelFunc := context.WithTimeout(context.Background(), time.Minute) ctx, cancelFunc := context.WithTimeout(context.Background(), time.Minute)
defer cancelFunc() defer cancelFunc()
@ -512,7 +512,7 @@ func requestAuthorizationUsingOIDCIdentityProvider(t *testing.T, downstreamAutho
// Open the web browser and navigate to the downstream authorize URL. // Open the web browser and navigate to the downstream authorize URL.
page := browsertest.Open(t) page := browsertest.Open(t)
t.Logf("opening browser to downstream authorize URL %s", library.MaskTokens(downstreamAuthorizeURL)) t.Logf("opening browser to downstream authorize URL %s", testlib.MaskTokens(downstreamAuthorizeURL))
require.NoError(t, page.Navigate(downstreamAuthorizeURL)) require.NoError(t, page.Navigate(downstreamAuthorizeURL))
// Expect to be redirected to the upstream provider and log in. // Expect to be redirected to the upstream provider and log in.
@ -542,7 +542,7 @@ func requestAuthorizationUsingLDAPIdentityProvider(t *testing.T, downstreamAutho
// to retry this request multiple times until we get the expected 302 status response. // to retry this request multiple times until we get the expected 302 status response.
var authResponse *http.Response var authResponse *http.Response
var responseBody []byte var responseBody []byte
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
authResponse, err = httpClient.Do(authRequest) authResponse, err = httpClient.Do(authRequest)
if err != nil { if err != nil {
t.Logf("got authorization response with error %v", err) t.Logf("got authorization response with error %v", err)

View File

@ -15,19 +15,19 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1" configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestSupervisorSecrets(t *testing.T) { func TestSupervisorSecrets(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
kubeClient := library.NewKubernetesClientset(t) kubeClient := testlib.NewKubernetesClientset(t)
supervisorClient := library.NewSupervisorClientset(t) supervisorClient := testlib.NewSupervisorClientset(t)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel() defer cancel()
// Create our FederationDomain under test. // Create our FederationDomain under test.
federationDomain := library.CreateTestFederationDomain(ctx, t, "", "", "") federationDomain := testlib.CreateTestFederationDomain(ctx, t, "", "", "")
tests := []struct { tests := []struct {
name string name string
@ -75,7 +75,7 @@ func TestSupervisorSecrets(t *testing.T) {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
// Ensure a secret is created with the FederationDomain's JWKS. // Ensure a secret is created with the FederationDomain's JWKS.
var updatedFederationDomain *configv1alpha1.FederationDomain var updatedFederationDomain *configv1alpha1.FederationDomain
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
resp, err := supervisorClient. resp, err := supervisorClient.
ConfigV1alpha1(). ConfigV1alpha1().
FederationDomains(env.SupervisorNamespace). FederationDomains(env.SupervisorNamespace).
@ -107,7 +107,7 @@ func TestSupervisorSecrets(t *testing.T) {
Secrets(env.SupervisorNamespace). Secrets(env.SupervisorNamespace).
Delete(ctx, test.secretName(updatedFederationDomain), metav1.DeleteOptions{}) Delete(ctx, test.secretName(updatedFederationDomain), metav1.DeleteOptions{})
require.NoError(t, err) require.NoError(t, err)
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
var err error var err error
secret, err = kubeClient. secret, err = kubeClient.
CoreV1(). CoreV1().

View File

@ -16,7 +16,7 @@ import (
corev1client "k8s.io/client-go/kubernetes/typed/core/v1" corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
"go.pinniped.dev/internal/crud" "go.pinniped.dev/internal/crud"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestStorageGarbageCollection(t *testing.T) { func TestStorageGarbageCollection(t *testing.T) {
@ -24,8 +24,8 @@ func TestStorageGarbageCollection(t *testing.T) {
// and will not impact other tests, or be impacted by other tests, when run in parallel. // and will not impact other tests, or be impacted by other tests, when run in parallel.
t.Parallel() t.Parallel()
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
client := library.NewKubernetesClientset(t) client := testlib.NewKubernetesClientset(t)
secrets := client.CoreV1().Secrets(env.SupervisorNamespace) secrets := client.CoreV1().Secrets(env.SupervisorNamespace)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel() defer cancel()
@ -55,12 +55,12 @@ func TestStorageGarbageCollection(t *testing.T) {
// in practice we should only need to wait about 30 seconds, which is the GC controller's self-imposed // in practice we should only need to wait about 30 seconds, which is the GC controller's self-imposed
// rate throttling time period. // rate throttling time period.
slightlyLongerThanGCControllerFullResyncPeriod := 3*time.Minute + 30*time.Second slightlyLongerThanGCControllerFullResyncPeriod := 3*time.Minute + 30*time.Second
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
_, err := secrets.Get(ctx, secretAlreadyExpired.Name, metav1.GetOptions{}) _, err := secrets.Get(ctx, secretAlreadyExpired.Name, metav1.GetOptions{})
requireEventually.Truef(k8serrors.IsNotFound(err), "wanted a NotFound error but got %v", err) requireEventually.Truef(k8serrors.IsNotFound(err), "wanted a NotFound error but got %v", err)
}, slightlyLongerThanGCControllerFullResyncPeriod, 250*time.Millisecond) }, slightlyLongerThanGCControllerFullResyncPeriod, 250*time.Millisecond)
library.RequireEventually(t, func(requireEventually *require.Assertions) { testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
_, err := secrets.Get(ctx, secretWhichWillExpireBeforeTheTestEnds.Name, metav1.GetOptions{}) _, err := secrets.Get(ctx, secretWhichWillExpireBeforeTheTestEnds.Name, metav1.GetOptions{})
requireEventually.Truef(k8serrors.IsNotFound(err), "wanted a NotFound error but got %v", err) requireEventually.Truef(k8serrors.IsNotFound(err), "wanted a NotFound error but got %v", err)
}, slightlyLongerThanGCControllerFullResyncPeriod, 250*time.Millisecond) }, slightlyLongerThanGCControllerFullResyncPeriod, 250*time.Millisecond)

View File

@ -20,12 +20,12 @@ import (
"go.pinniped.dev/internal/fositestorage/authorizationcode" "go.pinniped.dev/internal/fositestorage/authorizationcode"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestAuthorizeCodeStorage(t *testing.T) { func TestAuthorizeCodeStorage(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
client := library.NewKubernetesClientset(t) client := testlib.NewKubernetesClientset(t)
const ( const (
// randomly generated HMAC authorization code (see below) // randomly generated HMAC authorization code (see below)

View File

@ -11,11 +11,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1" "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestSupervisorUpstreamOIDCDiscovery(t *testing.T) { func TestSupervisorUpstreamOIDCDiscovery(t *testing.T) {
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
t.Run("invalid missing secret and bad issuer", func(t *testing.T) { t.Run("invalid missing secret and bad issuer", func(t *testing.T) {
t.Parallel() t.Parallel()
@ -25,7 +25,7 @@ func TestSupervisorUpstreamOIDCDiscovery(t *testing.T) {
SecretName: "does-not-exist", SecretName: "does-not-exist",
}, },
} }
upstream := library.CreateTestOIDCIdentityProvider(t, spec, v1alpha1.PhaseError) upstream := testlib.CreateTestOIDCIdentityProvider(t, spec, v1alpha1.PhaseError)
expectUpstreamConditions(t, upstream, []v1alpha1.Condition{ expectUpstreamConditions(t, upstream, []v1alpha1.Condition{
{ {
Type: "ClientCredentialsValid", Type: "ClientCredentialsValid",
@ -54,10 +54,10 @@ Get "https://127.0.0.1:444444/issuer/.well-known/openid-configuration": dial tcp
AdditionalScopes: []string{"email", "profile"}, AdditionalScopes: []string{"email", "profile"},
}, },
Client: v1alpha1.OIDCClient{ Client: v1alpha1.OIDCClient{
SecretName: library.CreateClientCredsSecret(t, "test-client-id", "test-client-secret").Name, SecretName: testlib.CreateClientCredsSecret(t, "test-client-id", "test-client-secret").Name,
}, },
} }
upstream := library.CreateTestOIDCIdentityProvider(t, spec, v1alpha1.PhaseError) upstream := testlib.CreateTestOIDCIdentityProvider(t, spec, v1alpha1.PhaseError)
expectUpstreamConditions(t, upstream, []v1alpha1.Condition{ expectUpstreamConditions(t, upstream, []v1alpha1.Condition{
{ {
Type: "ClientCredentialsValid", Type: "ClientCredentialsValid",
@ -86,10 +86,10 @@ oidc: issuer did not match the issuer returned by provider, expected "` + env.Su
AdditionalScopes: []string{"email", "profile"}, AdditionalScopes: []string{"email", "profile"},
}, },
Client: v1alpha1.OIDCClient{ Client: v1alpha1.OIDCClient{
SecretName: library.CreateClientCredsSecret(t, "test-client-id", "test-client-secret").Name, SecretName: testlib.CreateClientCredsSecret(t, "test-client-id", "test-client-secret").Name,
}, },
} }
upstream := library.CreateTestOIDCIdentityProvider(t, spec, v1alpha1.PhaseReady) upstream := testlib.CreateTestOIDCIdentityProvider(t, spec, v1alpha1.PhaseReady)
expectUpstreamConditions(t, upstream, []v1alpha1.Condition{ expectUpstreamConditions(t, upstream, []v1alpha1.Condition{
{ {
Type: "ClientCredentialsValid", Type: "ClientCredentialsValid",

View File

@ -26,18 +26,18 @@ import (
"k8s.io/client-go/util/keyutil" "k8s.io/client-go/util/keyutil"
identityv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/identity/v1alpha1" identityv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/identity/v1alpha1"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
func TestWhoAmI_Kubeadm(t *testing.T) { func TestWhoAmI_Kubeadm(t *testing.T) {
// use the cluster signing key being available as a proxy for this being a kubeadm cluster // use the cluster signing key being available as a proxy for this being a kubeadm cluster
// we should add more robust logic around skipping clusters based on vendor // we should add more robust logic around skipping clusters based on vendor
_ = library.IntegrationEnv(t).WithCapability(library.ClusterSigningKeyIsAvailable) _ = testlib.IntegrationEnv(t).WithCapability(testlib.ClusterSigningKeyIsAvailable)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
whoAmI, err := library.NewConciergeClientset(t).IdentityV1alpha1().WhoAmIRequests(). whoAmI, err := testlib.NewConciergeClientset(t).IdentityV1alpha1().WhoAmIRequests().
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{}) Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
@ -61,12 +61,12 @@ func TestWhoAmI_Kubeadm(t *testing.T) {
} }
func TestWhoAmI_ServiceAccount_Legacy(t *testing.T) { func TestWhoAmI_ServiceAccount_Legacy(t *testing.T) {
_ = library.IntegrationEnv(t) _ = testlib.IntegrationEnv(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
kubeClient := library.NewKubernetesClientset(t).CoreV1() kubeClient := testlib.NewKubernetesClientset(t).CoreV1()
ns, err := kubeClient.Namespaces().Create(ctx, &corev1.Namespace{ ns, err := kubeClient.Namespaces().Create(ctx, &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -97,7 +97,7 @@ func TestWhoAmI_ServiceAccount_Legacy(t *testing.T) {
}, metav1.CreateOptions{}) }, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
library.RequireEventuallyWithoutError(t, func() (bool, error) { testlib.RequireEventuallyWithoutError(t, func() (bool, error) {
secret, err = kubeClient.Secrets(ns.Name).Get(ctx, secret.Name, metav1.GetOptions{}) secret, err = kubeClient.Secrets(ns.Name).Get(ctx, secret.Name, metav1.GetOptions{})
if err != nil { if err != nil {
return false, err return false, err
@ -105,10 +105,10 @@ func TestWhoAmI_ServiceAccount_Legacy(t *testing.T) {
return len(secret.Data[corev1.ServiceAccountTokenKey]) > 0, nil return len(secret.Data[corev1.ServiceAccountTokenKey]) > 0, nil
}, time.Minute, time.Second) }, time.Minute, time.Second)
saConfig := library.NewAnonymousClientRestConfig(t) saConfig := testlib.NewAnonymousClientRestConfig(t)
saConfig.BearerToken = string(secret.Data[corev1.ServiceAccountTokenKey]) saConfig.BearerToken = string(secret.Data[corev1.ServiceAccountTokenKey])
whoAmI, err := library.NewKubeclient(t, saConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests(). whoAmI, err := testlib.NewKubeclient(t, saConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests().
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{}) Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
@ -134,12 +134,12 @@ func TestWhoAmI_ServiceAccount_Legacy(t *testing.T) {
} }
func TestWhoAmI_ServiceAccount_TokenRequest(t *testing.T) { func TestWhoAmI_ServiceAccount_TokenRequest(t *testing.T) {
_ = library.IntegrationEnv(t) _ = testlib.IntegrationEnv(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
kubeClient := library.NewKubernetesClientset(t).CoreV1() kubeClient := testlib.NewKubernetesClientset(t).CoreV1()
ns, err := kubeClient.Namespaces().Create(ctx, &corev1.Namespace{ ns, err := kubeClient.Namespaces().Create(ctx, &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -193,12 +193,12 @@ func TestWhoAmI_ServiceAccount_TokenRequest(t *testing.T) {
}, metav1.CreateOptions{}) }, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
saBadAudConfig := library.NewAnonymousClientRestConfig(t) saBadAudConfig := testlib.NewAnonymousClientRestConfig(t)
saBadAudConfig.BearerToken = tokenRequestBadAudience.Status.Token saBadAudConfig.BearerToken = tokenRequestBadAudience.Status.Token
_, badAudErr := library.NewKubeclient(t, saBadAudConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests(). _, badAudErr := testlib.NewKubeclient(t, saBadAudConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests().
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{}) Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
require.True(t, errors.IsUnauthorized(badAudErr), library.Sdump(badAudErr)) require.True(t, errors.IsUnauthorized(badAudErr), testlib.Sdump(badAudErr))
tokenRequest, err := kubeClient.ServiceAccounts(ns.Name).CreateToken(ctx, sa.Name, &authenticationv1.TokenRequest{ tokenRequest, err := kubeClient.ServiceAccounts(ns.Name).CreateToken(ctx, sa.Name, &authenticationv1.TokenRequest{
Spec: authenticationv1.TokenRequestSpec{ Spec: authenticationv1.TokenRequestSpec{
@ -213,10 +213,10 @@ func TestWhoAmI_ServiceAccount_TokenRequest(t *testing.T) {
}, metav1.CreateOptions{}) }, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
saTokenReqConfig := library.NewAnonymousClientRestConfig(t) saTokenReqConfig := testlib.NewAnonymousClientRestConfig(t)
saTokenReqConfig.BearerToken = tokenRequest.Status.Token saTokenReqConfig.BearerToken = tokenRequest.Status.Token
whoAmITokenReq, err := library.NewKubeclient(t, saTokenReqConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests(). whoAmITokenReq, err := testlib.NewKubeclient(t, saTokenReqConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests().
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{}) Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
@ -248,12 +248,12 @@ func TestWhoAmI_ServiceAccount_TokenRequest(t *testing.T) {
func TestWhoAmI_CSR(t *testing.T) { func TestWhoAmI_CSR(t *testing.T) {
// use the cluster signing key being available as a proxy for this not being an EKS cluster // use the cluster signing key being available as a proxy for this not being an EKS cluster
// we should add more robust logic around skipping clusters based on vendor // we should add more robust logic around skipping clusters based on vendor
_ = library.IntegrationEnv(t).WithCapability(library.ClusterSigningKeyIsAvailable) _ = testlib.IntegrationEnv(t).WithCapability(testlib.ClusterSigningKeyIsAvailable)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
kubeClient := library.NewKubernetesClientset(t) kubeClient := testlib.NewKubernetesClientset(t)
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err) require.NoError(t, err)
@ -305,11 +305,11 @@ func TestWhoAmI_CSR(t *testing.T) {
crtPEM, err := csr.WaitForCertificate(ctx, kubeClient, csrName, csrUID) crtPEM, err := csr.WaitForCertificate(ctx, kubeClient, csrName, csrUID)
require.NoError(t, err) require.NoError(t, err)
csrConfig := library.NewAnonymousClientRestConfig(t) csrConfig := testlib.NewAnonymousClientRestConfig(t)
csrConfig.CertData = crtPEM csrConfig.CertData = crtPEM
csrConfig.KeyData = keyPEM csrConfig.KeyData = keyPEM
whoAmI, err := library.NewKubeclient(t, csrConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests(). whoAmI, err := testlib.NewKubeclient(t, csrConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests().
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{}) Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
@ -333,14 +333,14 @@ func TestWhoAmI_CSR(t *testing.T) {
} }
func TestWhoAmI_Anonymous(t *testing.T) { func TestWhoAmI_Anonymous(t *testing.T) {
_ = library.IntegrationEnv(t).WithCapability(library.AnonymousAuthenticationSupported) _ = testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
anonymousConfig := library.NewAnonymousClientRestConfig(t) anonymousConfig := testlib.NewAnonymousClientRestConfig(t)
whoAmI, err := library.NewKubeclient(t, anonymousConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests(). whoAmI, err := testlib.NewKubeclient(t, anonymousConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests().
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{}) Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
@ -363,12 +363,12 @@ func TestWhoAmI_Anonymous(t *testing.T) {
} }
func TestWhoAmI_ImpersonateDirectly(t *testing.T) { func TestWhoAmI_ImpersonateDirectly(t *testing.T) {
_ = library.IntegrationEnv(t) _ = testlib.IntegrationEnv(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
impersonationConfig := library.NewClientConfig(t) impersonationConfig := testlib.NewClientConfig(t)
impersonationConfig.Impersonate = rest.ImpersonationConfig{ impersonationConfig.Impersonate = rest.ImpersonationConfig{
UserName: "solaire", UserName: "solaire",
// need to impersonate system:authenticated directly to support older clusters otherwise we will get RBAC errors below // need to impersonate system:authenticated directly to support older clusters otherwise we will get RBAC errors below
@ -379,7 +379,7 @@ func TestWhoAmI_ImpersonateDirectly(t *testing.T) {
}, },
} }
whoAmI, err := library.NewKubeclient(t, impersonationConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests(). whoAmI, err := testlib.NewKubeclient(t, impersonationConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests().
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{}) Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
@ -406,12 +406,12 @@ func TestWhoAmI_ImpersonateDirectly(t *testing.T) {
whoAmI, whoAmI,
) )
impersonationAnonymousConfig := library.NewClientConfig(t) impersonationAnonymousConfig := testlib.NewClientConfig(t)
impersonationAnonymousConfig.Impersonate.UserName = "system:anonymous" impersonationAnonymousConfig.Impersonate.UserName = "system:anonymous"
// need to impersonate system:unauthenticated directly to support older clusters otherwise we will get RBAC errors below // need to impersonate system:unauthenticated directly to support older clusters otherwise we will get RBAC errors below
impersonationAnonymousConfig.Impersonate.Groups = []string{"system:unauthenticated"} impersonationAnonymousConfig.Impersonate.Groups = []string{"system:unauthenticated"}
whoAmIAnonymous, err := library.NewKubeclient(t, impersonationAnonymousConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests(). whoAmIAnonymous, err := testlib.NewKubeclient(t, impersonationAnonymousConfig).PinnipedConcierge.IdentityV1alpha1().WhoAmIRequests().
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{}) Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)

View File

@ -1,7 +1,7 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package library package testlib
import ( import (
"context" "context"

View File

@ -1,7 +1,7 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved. // Copyright 2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package library package testlib
import ( import (
"context" "context"

View File

@ -12,7 +12,7 @@ import (
"github.com/sclevine/agouti" "github.com/sclevine/agouti"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/testlib"
) )
const ( const (
@ -25,7 +25,7 @@ const (
// in a mode that ignore certificate errors. // in a mode that ignore certificate errors.
func Open(t *testing.T) *agouti.Page { func Open(t *testing.T) *agouti.Page {
t.Logf("opening browser driver") t.Logf("opening browser driver")
env := library.IntegrationEnv(t) env := testlib.IntegrationEnv(t)
caps := agouti.NewCapabilities() caps := agouti.NewCapabilities()
if env.Proxy != "" { if env.Proxy != "" {
t.Logf("configuring Chrome to use proxy %q", env.Proxy) t.Logf("configuring Chrome to use proxy %q", env.Proxy)
@ -59,7 +59,7 @@ func Open(t *testing.T) *agouti.Page {
func WaitForVisibleElements(t *testing.T, page *agouti.Page, selectors ...string) { func WaitForVisibleElements(t *testing.T, page *agouti.Page, selectors ...string) {
t.Helper() t.Helper()
library.RequireEventuallyf(t, testlib.RequireEventuallyf(t,
func(requireEventually *require.Assertions) { func(requireEventually *require.Assertions) {
for _, sel := range selectors { for _, sel := range selectors {
vis, err := page.First(sel).Visible() vis, err := page.First(sel).Visible()
@ -78,7 +78,7 @@ func WaitForVisibleElements(t *testing.T, page *agouti.Page, selectors ...string
// to occur and times out, failing the test, if it never does. // to occur and times out, failing the test, if it never does.
func WaitForURL(t *testing.T, page *agouti.Page, pat *regexp.Regexp) { func WaitForURL(t *testing.T, page *agouti.Page, pat *regexp.Regexp) {
var lastURL string var lastURL string
library.RequireEventuallyf(t, testlib.RequireEventuallyf(t,
func(requireEventually *require.Assertions) { func(requireEventually *require.Assertions) {
url, err := page.URL() url, err := page.URL()
if url != lastURL { if url != lastURL {
@ -97,7 +97,7 @@ func WaitForURL(t *testing.T, page *agouti.Page, pat *regexp.Regexp) {
// LoginToUpstream expects the page to be redirected to one of several known upstream IDPs. // LoginToUpstream expects the page to be redirected to one of several known upstream IDPs.
// It knows how to enter the test username/password and submit the upstream login form. // It knows how to enter the test username/password and submit the upstream login form.
func LoginToUpstream(t *testing.T, page *agouti.Page, upstream library.TestOIDCUpstream) { func LoginToUpstream(t *testing.T, page *agouti.Page, upstream testlib.TestOIDCUpstream) {
t.Helper() t.Helper()
type config struct { type config struct {

View File

@ -1,7 +1,7 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package library package testlib
import ( import (
"io/ioutil" "io/ioutil"

View File

@ -1,7 +1,7 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package library package testlib
import ( import (
"context" "context"

View File

@ -1,7 +1,7 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package library package testlib
import ( import (
"encoding/base64" "encoding/base64"

View File

@ -1,7 +1,7 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package library package testlib
import ( import (
"fmt" "fmt"

View File

@ -3,7 +3,7 @@
// +build !go1.14 // +build !go1.14
package library package testlib
import ( import (
"context" "context"

View File

@ -3,7 +3,7 @@
// +build go1.14 // +build go1.14
package library package testlib
import ( import (
"context" "context"

View File

@ -1,7 +1,7 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved. // Copyright 2020 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package library package testlib
import "testing" import "testing"

View File

@ -1,7 +1,7 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved. // Copyright 2020 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package library package testlib
import "github.com/davecgh/go-spew/spew" import "github.com/davecgh/go-spew/spew"