Allow the integration tests to set an IP address for the Supervisor issuer

Co-authored-by: Ryan Richard <richardry@vmware.com>
This commit is contained in:
Joshua Casey
2024-08-30 15:48:04 -05:00
parent c0bab69cd1
commit 557dee06f0
6 changed files with 77 additions and 31 deletions

View File

@@ -11,6 +11,7 @@ import (
"errors"
"fmt"
"io"
"net"
"net/url"
"os"
"os/exec"
@@ -71,6 +72,11 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
pinnipedExe := testlib.PinnipedCLIPath(t)
issuerURL, _ := env.InferSupervisorIssuerURL(t)
isIssuerAnIPAddress := net.ParseIP(issuerURL.Hostname()) != nil
var issuerIPs []net.IP
if isIssuerAnIPAddress {
issuerIPs = append(issuerIPs, net.ParseIP(issuerURL.Hostname()))
}
// Generate a CA bundle with which to serve this provider.
t.Logf("generating test CA")
@@ -85,24 +91,52 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
// Use the CA to issue a TLS server cert.
t.Logf("issuing test certificate")
federationDomainTLSServingCert, err := federationDomainSelfSignedCA.IssueServerCert(
[]string{issuerURL.Hostname()}, nil, 1*time.Hour)
[]string{issuerURL.Hostname()}, issuerIPs, 1*time.Hour)
require.NoError(t, err)
federationDomainTLSServingCertPEM, federationDomainTLSServingCertKeyPEM, err := certauthority.ToPEM(federationDomainTLSServingCert)
require.NoError(t, err)
// Write the serving cert to a secret.
federationDomainTLSServingCertSecret := testlib.CreateTestSecret(t,
supervisorClient := testlib.NewSupervisorClientset(t)
temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(
topSetupCtx,
t,
env.SupervisorNamespace,
"oidc-provider-tls",
corev1.SecretTypeTLS,
map[string]string{"tls.crt": string(federationDomainTLSServingCertPEM), "tls.key": string(federationDomainTLSServingCertKeyPEM)},
env.DefaultTLSCertSecretName(),
supervisorClient,
testlib.NewKubernetesClientset(t),
)
// Create the downstream FederationDomain and expect it to go into the success status condition.
var tlsSpecForFederationDomain *supervisorconfigv1alpha1.FederationDomainTLSSpec
if isIssuerAnIPAddress {
testlib.CreateTestSecretWithName(
t,
env.SupervisorNamespace,
env.DefaultTLSCertSecretName(),
corev1.SecretTypeTLS,
map[string]string{
"tls.crt": string(federationDomainTLSServingCertPEM),
"tls.key": string(federationDomainTLSServingCertKeyPEM),
},
)
} else {
// Write the serving cert to a secret.
federationDomainTLSServingCertSecret := testlib.CreateTestSecret(t,
env.SupervisorNamespace,
"oidc-provider-tls",
corev1.SecretTypeTLS,
map[string]string{
"tls.crt": string(federationDomainTLSServingCertPEM),
"tls.key": string(federationDomainTLSServingCertKeyPEM),
},
)
tlsSpecForFederationDomain = &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: federationDomainTLSServingCertSecret.Name}
}
// Create the downstream FederationDomain.
federationDomain := testlib.CreateTestFederationDomain(topSetupCtx, t,
supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: issuerURL.String(),
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: federationDomainTLSServingCertSecret.Name},
TLS: tlsSpecForFederationDomain,
},
supervisorconfigv1alpha1.FederationDomainPhaseError, // in phase error until there is an IDP created
)
@@ -1416,7 +1450,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Update the FederationDomain to use the two IDPs.
federationDomainsClient := testlib.NewSupervisorClientset(t).ConfigV1alpha1().FederationDomains(env.SupervisorNamespace)
federationDomainsClient := supervisorClient.ConfigV1alpha1().FederationDomains(env.SupervisorNamespace)
gotFederationDomain, err := federationDomainsClient.Get(testCtx, federationDomain.Name, metav1.GetOptions{})
require.NoError(t, err)
@@ -1736,7 +1770,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Update the FederationDomain to use the two IDPs.
federationDomainsClient := testlib.NewSupervisorClientset(t).ConfigV1alpha1().FederationDomains(env.SupervisorNamespace)
federationDomainsClient := supervisorClient.ConfigV1alpha1().FederationDomains(env.SupervisorNamespace)
gotFederationDomain, err := federationDomainsClient.Get(testCtx, federationDomain.Name, metav1.GetOptions{})
require.NoError(t, err)

View File

@@ -61,8 +61,8 @@ func TestSupervisorOIDCDiscovery_Disruptive(t *testing.T) {
ips = append(ips, ip)
}
temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(ctx, t, ns, defaultTLSCertSecretName(env), client, testlib.NewKubernetesClientset(t))
defaultCA := createTLSCertificateSecret(ctx, t, ns, httpsAddress, ips, defaultTLSCertSecretName(env), kubeClient)
temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(ctx, t, ns, env.DefaultTLSCertSecretName(), client, testlib.NewKubernetesClientset(t))
defaultCA := createTLSCertificateSecret(ctx, t, ns, httpsAddress, ips, env.DefaultTLSCertSecretName(), kubeClient)
tests := []struct {
Name string
@@ -182,7 +182,7 @@ func TestSupervisorTLSTerminationWithSNI_Disruptive(t *testing.T) {
Client: idpv1alpha1.OIDCClient{SecretName: "this-will-not-exist-but-does-not-matter"},
}, idpv1alpha1.PhaseError)
temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(ctx, t, ns, defaultTLSCertSecretName(env), pinnipedClient, kubeClient)
temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(ctx, t, ns, env.DefaultTLSCertSecretName(), pinnipedClient, kubeClient)
scheme := "https"
address := env.SupervisorHTTPSAddress // hostname and port for direct access to the supervisor's port 8443
@@ -268,7 +268,7 @@ func TestSupervisorTLSTerminationWithDefaultCerts_Disruptive(t *testing.T) {
Client: idpv1alpha1.OIDCClient{SecretName: "this-will-not-exist-but-does-not-matter"},
}, idpv1alpha1.PhaseError)
temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(ctx, t, ns, defaultTLSCertSecretName(env), pinnipedClient, kubeClient)
temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(ctx, t, ns, env.DefaultTLSCertSecretName(), pinnipedClient, kubeClient)
scheme := "https"
address := env.SupervisorHTTPSAddress // hostname and port for direct access to the supervisor's port 8443
@@ -297,7 +297,7 @@ func TestSupervisorTLSTerminationWithDefaultCerts_Disruptive(t *testing.T) {
requireEndpointHasBootstrapTLSErrorBecauseCertificatesAreNotReady(t, issuerUsingIPAddress)
// Create a Secret at the special name which represents the default TLS cert.
defaultCA := createTLSCertificateSecret(ctx, t, ns, "cert-hostname-doesnt-matter", []net.IP{ips[0]}, defaultTLSCertSecretName(env), kubeClient)
defaultCA := createTLSCertificateSecret(ctx, t, ns, "cert-hostname-doesnt-matter", []net.IP{ips[0]}, env.DefaultTLSCertSecretName(), kubeClient)
// Now that the Secret exists, we should be able to access the endpoints by IP address using the CA.
_ = requireStandardDiscoveryEndpointsAreWorking(t, scheme, ipWithPort, string(defaultCA.Bundle()), issuerUsingIPAddress, nil)
@@ -323,10 +323,6 @@ func TestSupervisorTLSTerminationWithDefaultCerts_Disruptive(t *testing.T) {
_ = requireStandardDiscoveryEndpointsAreWorking(t, scheme, ipWithPort, string(defaultCA.Bundle()), issuerUsingIPAddress, nil)
}
func defaultTLSCertSecretName(env *testlib.TestEnv) string {
return env.SupervisorAppName + "-default-tls-certificate"
}
func createTLSCertificateSecret(ctx context.Context, t *testing.T, ns string, hostname string, ips []net.IP, secretName string, kubeClient kubernetes.Interface) *certauthority.CA {
// Create a CA.
ca, err := certauthority.New("Acme Corp", 1000*time.Hour)

View File

@@ -33,7 +33,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
t.Cleanup(cancel)
temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(ctx, t,
env.SupervisorNamespace, defaultTLSCertSecretName(env), supervisorClient, testlib.NewKubernetesClientset(t))
env.SupervisorNamespace, env.DefaultTLSCertSecretName(), supervisorClient, testlib.NewKubernetesClientset(t))
tests := []struct {
name string

View File

@@ -1,4 +1,4 @@
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package integration
@@ -27,7 +27,7 @@ func TestSupervisorHealthzBootstrap_Disruptive(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()
temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(ctx, t, ns, defaultTLSCertSecretName(env), pinnipedClient, kubeClient)
temporarilyRemoveAllFederationDomainsAndDefaultTLSCertSecret(ctx, t, ns, env.DefaultTLSCertSecretName(), pinnipedClient, kubeClient)
httpClient := &http.Client{
Transport: &http.Transport{

View File

@@ -474,17 +474,13 @@ func CreateTestConfigMap(t *testing.T, namespace string, baseName string, string
return created
}
func CreateTestSecret(t *testing.T, namespace string, baseName string, secretType corev1.SecretType, stringData map[string]string) *corev1.Secret {
func createTestSecret(t *testing.T, namespace string, secret *corev1.Secret) *corev1.Secret {
t.Helper()
client := NewKubernetesClientset(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
created, err := client.CoreV1().Secrets(namespace).Create(ctx, &corev1.Secret{
ObjectMeta: TestObjectMeta(t, baseName),
Type: secretType,
StringData: stringData,
}, metav1.CreateOptions{})
created, err := client.CoreV1().Secrets(namespace).Create(ctx, secret, metav1.CreateOptions{})
require.NoError(t, err)
t.Cleanup(func() {
@@ -496,6 +492,25 @@ func CreateTestSecret(t *testing.T, namespace string, baseName string, secretTyp
return created
}
func CreateTestSecret(t *testing.T, namespace string, baseName string, secretType corev1.SecretType, stringData map[string]string) *corev1.Secret {
return createTestSecret(t, namespace, &corev1.Secret{
ObjectMeta: TestObjectMeta(t, baseName),
Type: secretType,
StringData: stringData,
})
}
func CreateTestSecretWithName(t *testing.T, namespace string, name string, secretType corev1.SecretType, stringData map[string]string) *corev1.Secret {
secret := &corev1.Secret{
ObjectMeta: TestObjectMeta(t, ""),
Type: secretType,
StringData: stringData,
}
secret.GenerateName = ""
secret.Name = name
return createTestSecret(t, namespace, secret)
}
func CreateTestSecretBytes(t *testing.T, namespace string, baseName string, secretType corev1.SecretType, data map[string][]byte) *corev1.Secret {
t.Helper()
client := NewKubernetesClientset(t)

View File

@@ -98,6 +98,10 @@ func (e *TestEnv) InferSupervisorIssuerURL(t *testing.T) (*url.URL, string) {
return issuerURL, issuerAsString
}
func (e *TestEnv) DefaultTLSCertSecretName() string {
return e.SupervisorAppName + "-default-tls-certificate"
}
type TestLDAPUpstream struct {
Host string `json:"host"`
Domain string `json:"domain"`
@@ -262,9 +266,6 @@ func loadEnvVars(t *testing.T, result *TestEnv) {
result.SupervisorHTTPSIngressAddress = os.Getenv("PINNIPED_TEST_SUPERVISOR_HTTPS_INGRESS_ADDRESS")
result.SupervisorHTTPSAddress = needEnv(t, "PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS")
require.NotRegexp(t, "^[0-9]", result.SupervisorHTTPSAddress,
"PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS must be a hostname with an optional port and cannot be an IP address",
)
result.SupervisorHTTPSIngressCABundle = base64Decoded(t, os.Getenv("PINNIPED_TEST_SUPERVISOR_HTTPS_INGRESS_CA_BUNDLE"))
conciergeCustomLabelsYAML := needEnv(t, "PINNIPED_TEST_CONCIERGE_CUSTOM_LABELS")