mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-01-08 07:11:53 +00:00
Add integration tests to ensure that LDAP/AD conditions with status Unknown if they cannot be validated
Co-authored-by: Ryan Richard <richardry@vmware.com>
This commit is contained in:
committed by
Ryan Richard
parent
6b49cd7d28
commit
f918edd846
@@ -49,10 +49,10 @@ func TestLDAPSearch_Parallel(t *testing.T) {
|
||||
ldapsLocalhostPort := localhostPorts[1]
|
||||
unusedLocalhostPort := localhostPorts[2]
|
||||
|
||||
// Expose the the test LDAP server's TLS port on the localhost.
|
||||
// Expose the test LDAP server's TLS port on the localhost.
|
||||
startKubectlPortForward(ctx, t, ldapsLocalhostPort, "ldaps", "ldap", env.ToolsNamespace)
|
||||
|
||||
// Expose the the test LDAP server's StartTLS port on the localhost.
|
||||
// Expose the test LDAP server's StartTLS port on the localhost.
|
||||
startKubectlPortForward(ctx, t, ldapLocalhostPort, "ldap", "ldap", env.ToolsNamespace)
|
||||
|
||||
providerConfig := func(editFunc func(p *upstreamldap.ProviderConfig)) *upstreamldap.ProviderConfig {
|
||||
@@ -853,11 +853,11 @@ func startKubectlPortForward(ctx context.Context, t *testing.T, hostPort, remote
|
||||
func findRecentlyUnusedLocalhostPorts(t *testing.T, howManyPorts int) []string {
|
||||
t.Helper()
|
||||
|
||||
listeners := []net.Listener{}
|
||||
for range howManyPorts {
|
||||
unusedPortGrabbingListener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
listeners := make([]net.Listener, howManyPorts)
|
||||
for i := range howManyPorts {
|
||||
var err error
|
||||
listeners[i], err = net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
listeners = append(listeners, unusedPortGrabbingListener)
|
||||
}
|
||||
|
||||
ports := make([]string, len(listeners))
|
||||
|
||||
193
test/integration/supervisor_ad_idp_test.go
Normal file
193
test/integration/supervisor_ad_idp_test.go
Normal file
@@ -0,0 +1,193 @@
|
||||
// Copyright 2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
|
||||
"go.pinniped.dev/test/testlib"
|
||||
)
|
||||
|
||||
func TestActiveDirectoryIDPPhaseAndConditions_Parallel(t *testing.T) {
|
||||
env := testlib.IntegrationEnv(t)
|
||||
testlib.SkipTestWhenActiveDirectoryIsUnavailable(t, env)
|
||||
|
||||
supervisorNamespace := testlib.IntegrationEnv(t).SupervisorNamespace
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
adIDPClient := testlib.NewSupervisorClientset(t).IDPV1alpha1().ActiveDirectoryIdentityProviders(supervisorNamespace)
|
||||
|
||||
bindSecret := testlib.CreateTestSecret(
|
||||
t,
|
||||
env.SupervisorNamespace,
|
||||
"ad-bind-secret",
|
||||
corev1.SecretTypeBasicAuth,
|
||||
map[string]string{
|
||||
corev1.BasicAuthUsernameKey: env.SupervisorUpstreamActiveDirectory.BindUsername,
|
||||
corev1.BasicAuthPasswordKey: env.SupervisorUpstreamActiveDirectory.BindPassword,
|
||||
},
|
||||
)
|
||||
|
||||
happySpec := idpv1alpha1.ActiveDirectoryIdentityProviderSpec{
|
||||
Host: env.SupervisorUpstreamActiveDirectory.Host,
|
||||
Bind: idpv1alpha1.ActiveDirectoryIdentityProviderBind{
|
||||
SecretName: bindSecret.Name,
|
||||
},
|
||||
TLS: &idpv1alpha1.TLSSpec{
|
||||
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamActiveDirectory.CABundle)),
|
||||
},
|
||||
UserSearch: idpv1alpha1.ActiveDirectoryIdentityProviderUserSearch{
|
||||
Base: env.SupervisorUpstreamActiveDirectory.UserSearchBase,
|
||||
Filter: "",
|
||||
Attributes: idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{
|
||||
Username: env.SupervisorUpstreamActiveDirectory.TestUserMailAttributeName,
|
||||
UID: env.SupervisorUpstreamActiveDirectory.TestUserUniqueIDAttributeName,
|
||||
},
|
||||
},
|
||||
GroupSearch: idpv1alpha1.ActiveDirectoryIdentityProviderGroupSearch{
|
||||
Base: env.SupervisorUpstreamActiveDirectory.GroupSearchBase,
|
||||
Filter: "", // use the default value of "member={}"
|
||||
Attributes: idpv1alpha1.ActiveDirectoryIdentityProviderGroupSearchAttributes{
|
||||
GroupName: "", // use the default value of "dn"
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
adSpec idpv1alpha1.ActiveDirectoryIdentityProviderSpec
|
||||
wantPhase idpv1alpha1.ActiveDirectoryIdentityProviderPhase
|
||||
wantConditions []*metav1.Condition
|
||||
}{
|
||||
{
|
||||
name: "Happy Path",
|
||||
adSpec: happySpec,
|
||||
wantPhase: idpv1alpha1.ActiveDirectoryPhaseReady,
|
||||
wantConditions: []*metav1.Condition{
|
||||
{
|
||||
Type: "BindSecretValid",
|
||||
Status: "True",
|
||||
Reason: "Success",
|
||||
Message: "loaded bind secret",
|
||||
},
|
||||
{
|
||||
Type: "LDAPConnectionValid",
|
||||
Status: "True",
|
||||
Reason: "Success",
|
||||
Message: fmt.Sprintf(
|
||||
`successfully able to connect to %q and bind as user %q [validated with Secret %q at version %q]`,
|
||||
env.SupervisorUpstreamActiveDirectory.Host,
|
||||
env.SupervisorUpstreamActiveDirectory.BindUsername,
|
||||
bindSecret.Name,
|
||||
bindSecret.ResourceVersion),
|
||||
},
|
||||
{
|
||||
Type: "SearchBaseFound",
|
||||
Status: "True",
|
||||
Reason: "UsingConfigurationFromSpec",
|
||||
Message: "Using search base from ActiveDirectoryIdentityProvider config.",
|
||||
},
|
||||
{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "True",
|
||||
Reason: "Success",
|
||||
Message: "spec.tls is valid: using configured CA bundle",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "CA bundle is invalid yields conditions TLSConfigurationValid with status 'False' and LDAPConnectionValid with status 'Unknown'",
|
||||
adSpec: func() idpv1alpha1.ActiveDirectoryIdentityProviderSpec {
|
||||
temp := happySpec.DeepCopy()
|
||||
temp.TLS.CertificateAuthorityData = "this-is-not-base64-encoded"
|
||||
return *temp
|
||||
}(),
|
||||
wantPhase: idpv1alpha1.ActiveDirectoryPhaseError,
|
||||
wantConditions: []*metav1.Condition{
|
||||
{
|
||||
Type: "BindSecretValid",
|
||||
Status: "True",
|
||||
Reason: "Success",
|
||||
Message: "loaded bind secret",
|
||||
},
|
||||
{
|
||||
Type: "LDAPConnectionValid",
|
||||
Status: "Unknown",
|
||||
Reason: "UnableToValidate",
|
||||
Message: "unable to validate; see other conditions for details",
|
||||
},
|
||||
{
|
||||
Type: "SearchBaseFound",
|
||||
Status: "Unknown",
|
||||
Reason: "UnableToValidate",
|
||||
Message: "unable to validate; see other conditions for details",
|
||||
},
|
||||
{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "False",
|
||||
Reason: "InvalidTLSConfig",
|
||||
Message: "spec.tls.certificateAuthorityData is invalid: illegal base64 data at input byte 4",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Bind secret not found yields conditions BindSecretValid with status 'False' and LDAPConnectionValid with status 'Unknown'",
|
||||
adSpec: func() idpv1alpha1.ActiveDirectoryIdentityProviderSpec {
|
||||
temp := happySpec.DeepCopy()
|
||||
temp.Bind.SecretName = "this-secret-does-not-exist"
|
||||
return *temp
|
||||
}(),
|
||||
wantPhase: idpv1alpha1.ActiveDirectoryPhaseError,
|
||||
wantConditions: []*metav1.Condition{
|
||||
{
|
||||
Type: "BindSecretValid",
|
||||
Status: "False",
|
||||
Reason: "SecretNotFound",
|
||||
Message: `secret "this-secret-does-not-exist" not found`,
|
||||
},
|
||||
{
|
||||
Type: "LDAPConnectionValid",
|
||||
Status: "Unknown",
|
||||
Reason: "UnableToValidate",
|
||||
Message: "unable to validate; see other conditions for details",
|
||||
},
|
||||
{
|
||||
Type: "SearchBaseFound",
|
||||
Status: "Unknown",
|
||||
Reason: "UnableToValidate",
|
||||
Message: "unable to validate; see other conditions for details",
|
||||
},
|
||||
{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "True",
|
||||
Reason: "Success",
|
||||
Message: "spec.tls is valid: using configured CA bundle",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
idp := testlib.CreateTestActiveDirectoryIdentityProvider(t, test.adSpec, test.wantPhase)
|
||||
testlib.WaitForActiveDirectoryIdentityProviderStatusConditions(
|
||||
ctx,
|
||||
t,
|
||||
adIDPClient,
|
||||
idp.Name,
|
||||
test.wantConditions,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"go.pinniped.dev/test/testlib"
|
||||
)
|
||||
|
||||
const generateNamePrefix = "integration-test-github-idp-"
|
||||
const generateGitHubNamePrefix = "integration-test-github-idp-"
|
||||
|
||||
func TestGitHubIDPStaticValidationOnCreate_Parallel(t *testing.T) {
|
||||
adminClient := testlib.NewKubernetesClientset(t)
|
||||
@@ -37,7 +37,7 @@ func TestGitHubIDPStaticValidationOnCreate_Parallel(t *testing.T) {
|
||||
|
||||
ns, err := namespaceClient.Create(ctx, &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: generateNamePrefix,
|
||||
GenerateName: generateGitHubNamePrefix,
|
||||
},
|
||||
}, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
@@ -240,7 +240,7 @@ func TestGitHubIDPStaticValidationOnCreate_Parallel(t *testing.T) {
|
||||
|
||||
input := &idpv1alpha1.GitHubIdentityProvider{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: generateNamePrefix,
|
||||
GenerateName: generateGitHubNamePrefix,
|
||||
},
|
||||
Spec: tt.inputSpec,
|
||||
}
|
||||
@@ -268,7 +268,7 @@ func TestGitHubIDPSetsDefaultsWithKubectl_Parallel(t *testing.T) {
|
||||
|
||||
ns, err := namespaceClient.Create(ctx, &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: generateNamePrefix,
|
||||
GenerateName: generateGitHubNamePrefix,
|
||||
},
|
||||
}, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
@@ -278,7 +278,7 @@ func TestGitHubIDPSetsDefaultsWithKubectl_Parallel(t *testing.T) {
|
||||
})
|
||||
t.Logf("Created namespace %s", ns.Name)
|
||||
|
||||
idpName := generateNamePrefix + testlib.RandHex(t, 16)
|
||||
idpName := generateGitHubNamePrefix + testlib.RandHex(t, 16)
|
||||
|
||||
githubIDPYaml := []byte(here.Doc(fmt.Sprintf(`
|
||||
---
|
||||
@@ -336,8 +336,8 @@ func TestGitHubIDPPhaseAndConditions_Parallel(t *testing.T) {
|
||||
secretsClient := kubernetesClient.CoreV1().Secrets(supervisorNamespace)
|
||||
gitHubIDPClient := testlib.NewSupervisorClientset(t).IDPV1alpha1().GitHubIdentityProviders(supervisorNamespace)
|
||||
|
||||
happySecretName := generateNamePrefix + testlib.RandHex(t, 16)
|
||||
invalidSecretName := generateNamePrefix + testlib.RandHex(t, 16)
|
||||
happySecretName := generateGitHubNamePrefix + testlib.RandHex(t, 16)
|
||||
invalidSecretName := generateGitHubNamePrefix + testlib.RandHex(t, 16)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -490,7 +490,7 @@ func TestGitHubIDPPhaseAndConditions_Parallel(t *testing.T) {
|
||||
|
||||
var secretName string
|
||||
for _, secret := range tt.secrets {
|
||||
secret.GenerateName = generateNamePrefix
|
||||
secret.GenerateName = generateGitHubNamePrefix
|
||||
|
||||
created, err := secretsClient.Create(ctx, secret, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
@@ -505,7 +505,7 @@ func TestGitHubIDPPhaseAndConditions_Parallel(t *testing.T) {
|
||||
|
||||
for _, idp := range tt.idps {
|
||||
idp.Name = ""
|
||||
idp.GenerateName = generateNamePrefix
|
||||
idp.GenerateName = generateGitHubNamePrefix
|
||||
idp.Spec.Client.SecretName = secretName
|
||||
|
||||
created, err := gitHubIDPClient.Create(ctx, idp, metav1.CreateOptions{})
|
||||
@@ -532,7 +532,7 @@ func TestGitHubIDPInWrongNamespace_Parallel(t *testing.T) {
|
||||
namespaceClient := kubernetesClient.CoreV1().Namespaces()
|
||||
otherNamespace, err := namespaceClient.Create(ctx, &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: generateNamePrefix,
|
||||
GenerateName: generateGitHubNamePrefix,
|
||||
},
|
||||
}, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
@@ -545,7 +545,7 @@ func TestGitHubIDPInWrongNamespace_Parallel(t *testing.T) {
|
||||
|
||||
idp := &idpv1alpha1.GitHubIdentityProvider{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: generateNamePrefix,
|
||||
GenerateName: generateGitHubNamePrefix,
|
||||
Namespace: otherNamespace.Name,
|
||||
},
|
||||
Spec: idpv1alpha1.GitHubIdentityProviderSpec{
|
||||
@@ -592,7 +592,7 @@ func TestGitHubIDPSecretInOtherNamespace_Parallel(t *testing.T) {
|
||||
namespaceClient := kubernetesClient.CoreV1().Namespaces()
|
||||
otherNamespace, err := namespaceClient.Create(ctx, &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: generateNamePrefix,
|
||||
GenerateName: generateGitHubNamePrefix,
|
||||
},
|
||||
}, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
@@ -605,7 +605,7 @@ func TestGitHubIDPSecretInOtherNamespace_Parallel(t *testing.T) {
|
||||
|
||||
secret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: generateNamePrefix,
|
||||
GenerateName: generateGitHubNamePrefix,
|
||||
Namespace: otherNamespace.Name,
|
||||
},
|
||||
Type: "secrets.pinniped.dev/github-client",
|
||||
@@ -621,7 +621,7 @@ func TestGitHubIDPSecretInOtherNamespace_Parallel(t *testing.T) {
|
||||
|
||||
idp := &idpv1alpha1.GitHubIdentityProvider{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: generateNamePrefix,
|
||||
GenerateName: generateGitHubNamePrefix,
|
||||
Namespace: supervisorNamespace,
|
||||
},
|
||||
Spec: idpv1alpha1.GitHubIdentityProviderSpec{
|
||||
@@ -701,7 +701,7 @@ func TestGitHubIDPTooManyOrganizationsStaticValidationOnCreate_Parallel(t *testi
|
||||
|
||||
ns, err := namespaceClient.Create(ctx, &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: generateNamePrefix,
|
||||
GenerateName: generateGitHubNamePrefix,
|
||||
},
|
||||
}, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
@@ -714,7 +714,7 @@ func TestGitHubIDPTooManyOrganizationsStaticValidationOnCreate_Parallel(t *testi
|
||||
|
||||
input := &idpv1alpha1.GitHubIdentityProvider{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: generateNamePrefix,
|
||||
GenerateName: generateGitHubNamePrefix,
|
||||
},
|
||||
Spec: idpv1alpha1.GitHubIdentityProviderSpec{
|
||||
AllowAuthentication: idpv1alpha1.GitHubAllowAuthenticationSpec{
|
||||
|
||||
174
test/integration/supervisor_ldap_idp_test.go
Normal file
174
test/integration/supervisor_ldap_idp_test.go
Normal file
@@ -0,0 +1,174 @@
|
||||
// Copyright 2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
|
||||
"go.pinniped.dev/test/testlib"
|
||||
)
|
||||
|
||||
func TestLDAPIDPPhaseAndConditions_Parallel(t *testing.T) {
|
||||
env := testlib.IntegrationEnv(t)
|
||||
|
||||
supervisorNamespace := testlib.IntegrationEnv(t).SupervisorNamespace
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
ldapIDPClient := testlib.NewSupervisorClientset(t).IDPV1alpha1().LDAPIdentityProviders(supervisorNamespace)
|
||||
|
||||
bindSecret := testlib.CreateTestSecret(
|
||||
t,
|
||||
env.SupervisorNamespace,
|
||||
"ldap-bind-secret",
|
||||
corev1.SecretTypeBasicAuth,
|
||||
map[string]string{
|
||||
corev1.BasicAuthUsernameKey: env.SupervisorUpstreamLDAP.BindUsername,
|
||||
corev1.BasicAuthPasswordKey: env.SupervisorUpstreamLDAP.BindPassword,
|
||||
},
|
||||
)
|
||||
|
||||
happySpec := idpv1alpha1.LDAPIdentityProviderSpec{
|
||||
Host: env.SupervisorUpstreamLDAP.Host,
|
||||
Bind: idpv1alpha1.LDAPIdentityProviderBind{
|
||||
SecretName: bindSecret.Name,
|
||||
},
|
||||
TLS: &idpv1alpha1.TLSSpec{
|
||||
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamLDAP.CABundle)),
|
||||
},
|
||||
UserSearch: idpv1alpha1.LDAPIdentityProviderUserSearch{
|
||||
Base: env.SupervisorUpstreamLDAP.UserSearchBase,
|
||||
Filter: "",
|
||||
Attributes: idpv1alpha1.LDAPIdentityProviderUserSearchAttributes{
|
||||
Username: env.SupervisorUpstreamLDAP.TestUserMailAttributeName,
|
||||
UID: env.SupervisorUpstreamLDAP.TestUserUniqueIDAttributeName,
|
||||
},
|
||||
},
|
||||
GroupSearch: idpv1alpha1.LDAPIdentityProviderGroupSearch{
|
||||
Base: env.SupervisorUpstreamLDAP.GroupSearchBase,
|
||||
Filter: "", // use the default value of "member={}"
|
||||
Attributes: idpv1alpha1.LDAPIdentityProviderGroupSearchAttributes{
|
||||
GroupName: "", // use the default value of "dn"
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ldapSpec idpv1alpha1.LDAPIdentityProviderSpec
|
||||
wantPhase idpv1alpha1.LDAPIdentityProviderPhase
|
||||
wantConditions []*metav1.Condition
|
||||
}{
|
||||
{
|
||||
name: "Happy Path",
|
||||
ldapSpec: happySpec,
|
||||
wantPhase: idpv1alpha1.LDAPPhaseReady,
|
||||
wantConditions: []*metav1.Condition{
|
||||
{
|
||||
Type: "BindSecretValid",
|
||||
Status: "True",
|
||||
Reason: "Success",
|
||||
Message: "loaded bind secret",
|
||||
},
|
||||
{
|
||||
Type: "LDAPConnectionValid",
|
||||
Status: "True",
|
||||
Reason: "Success",
|
||||
Message: fmt.Sprintf(
|
||||
`successfully able to connect to %q and bind as user %q [validated with Secret %q at version %q]`,
|
||||
env.SupervisorUpstreamLDAP.Host,
|
||||
env.SupervisorUpstreamLDAP.BindUsername,
|
||||
bindSecret.Name,
|
||||
bindSecret.ResourceVersion),
|
||||
},
|
||||
{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "True",
|
||||
Reason: "Success",
|
||||
Message: "spec.tls is valid: using configured CA bundle",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "CA bundle is invalid yields conditions TLSConfigurationValid with status 'False' and LDAPConnectionValid/SearchBaseFound with status 'Unknown'",
|
||||
ldapSpec: func() idpv1alpha1.LDAPIdentityProviderSpec {
|
||||
temp := happySpec.DeepCopy()
|
||||
temp.TLS.CertificateAuthorityData = "this-is-not-base64-encoded"
|
||||
return *temp
|
||||
}(),
|
||||
wantPhase: idpv1alpha1.LDAPPhaseError,
|
||||
wantConditions: []*metav1.Condition{
|
||||
{
|
||||
Type: "BindSecretValid",
|
||||
Status: "True",
|
||||
Reason: "Success",
|
||||
Message: "loaded bind secret",
|
||||
},
|
||||
{
|
||||
Type: "LDAPConnectionValid",
|
||||
Status: "Unknown",
|
||||
Reason: "UnableToValidate",
|
||||
Message: "unable to validate; see other conditions for details",
|
||||
},
|
||||
{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "False",
|
||||
Reason: "InvalidTLSConfig",
|
||||
Message: "spec.tls.certificateAuthorityData is invalid: illegal base64 data at input byte 4",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Bind secret not found yields conditions BindSecretValid with status 'False' and LDAPConnectionValid/SearchBaseFound with status 'Unknown'",
|
||||
ldapSpec: func() idpv1alpha1.LDAPIdentityProviderSpec {
|
||||
temp := happySpec.DeepCopy()
|
||||
temp.Bind.SecretName = "this-secret-does-not-exist"
|
||||
return *temp
|
||||
}(),
|
||||
wantPhase: idpv1alpha1.LDAPPhaseError,
|
||||
wantConditions: []*metav1.Condition{
|
||||
{
|
||||
Type: "BindSecretValid",
|
||||
Status: "False",
|
||||
Reason: "SecretNotFound",
|
||||
Message: `secret "this-secret-does-not-exist" not found`,
|
||||
},
|
||||
{
|
||||
Type: "LDAPConnectionValid",
|
||||
Status: "Unknown",
|
||||
Reason: "UnableToValidate",
|
||||
Message: "unable to validate; see other conditions for details",
|
||||
},
|
||||
{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "True",
|
||||
Reason: "Success",
|
||||
Message: "spec.tls is valid: using configured CA bundle",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
idp := testlib.CreateTestLDAPIdentityProvider(t, test.ldapSpec, test.wantPhase)
|
||||
testlib.WaitForLDAPIdentityProviderStatusConditions(
|
||||
ctx,
|
||||
t,
|
||||
ldapIDPClient,
|
||||
idp.Name,
|
||||
test.wantConditions,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1000,6 +1000,80 @@ func WaitForGitHubIdentityProviderStatusConditions(
|
||||
}, 60*time.Second, 1*time.Second, "wanted conditions for GitHubIdentityProvider %q", gitHubIDPName)
|
||||
}
|
||||
|
||||
func WaitForLDAPIdentityProviderStatusConditions(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
client alpha1.LDAPIdentityProviderInterface,
|
||||
ldapIDPName string,
|
||||
expectConditions []*metav1.Condition,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
RequireEventuallyf(t, func(requireEventually *require.Assertions) {
|
||||
idp, err := client.Get(ctx, ldapIDPName, metav1.GetOptions{})
|
||||
requireEventually.NoError(err)
|
||||
|
||||
actualConditions := make([]*metav1.Condition, len(idp.Status.Conditions))
|
||||
for i, c := range idp.Status.Conditions {
|
||||
actualConditions[i] = c.DeepCopy()
|
||||
}
|
||||
|
||||
requireEventually.Lenf(actualConditions, len(expectConditions),
|
||||
"wanted status conditions: %#v", expectConditions)
|
||||
|
||||
for i, wantCond := range expectConditions {
|
||||
actualCond := actualConditions[i]
|
||||
|
||||
// This is a cheat to avoid needing to make equality assertions on these fields.
|
||||
requireEventually.NotZero(actualCond.LastTransitionTime)
|
||||
wantCond.LastTransitionTime = actualCond.LastTransitionTime
|
||||
requireEventually.NotZero(actualCond.ObservedGeneration)
|
||||
wantCond.ObservedGeneration = actualCond.ObservedGeneration
|
||||
|
||||
requireEventually.Equalf(wantCond, actualCond,
|
||||
"wanted status conditions: %#v\nactual status conditions were: %#v\nnot equal at index %d",
|
||||
expectConditions, &actualConditions, i)
|
||||
}
|
||||
}, 60*time.Second, 1*time.Second, "wanted conditions for LDAPIdentityProvider %q", ldapIDPName)
|
||||
}
|
||||
|
||||
func WaitForActiveDirectoryIdentityProviderStatusConditions(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
client alpha1.ActiveDirectoryIdentityProviderInterface,
|
||||
activeDirectoryIDPName string,
|
||||
expectConditions []*metav1.Condition,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
RequireEventuallyf(t, func(requireEventually *require.Assertions) {
|
||||
idp, err := client.Get(ctx, activeDirectoryIDPName, metav1.GetOptions{})
|
||||
requireEventually.NoError(err)
|
||||
|
||||
actualConditions := make([]*metav1.Condition, len(idp.Status.Conditions))
|
||||
for i, c := range idp.Status.Conditions {
|
||||
actualConditions[i] = c.DeepCopy()
|
||||
}
|
||||
|
||||
requireEventually.Lenf(actualConditions, len(expectConditions),
|
||||
"wanted status conditions: %#v", expectConditions)
|
||||
|
||||
for i, wantCond := range expectConditions {
|
||||
actualCond := actualConditions[i]
|
||||
|
||||
// This is a cheat to avoid needing to make equality assertions on these fields.
|
||||
requireEventually.NotZero(actualCond.LastTransitionTime)
|
||||
wantCond.LastTransitionTime = actualCond.LastTransitionTime
|
||||
requireEventually.NotZero(actualCond.ObservedGeneration)
|
||||
wantCond.ObservedGeneration = actualCond.ObservedGeneration
|
||||
|
||||
requireEventually.Equalf(wantCond, actualCond,
|
||||
"wanted status conditions: %#v\nactual status conditions were: %#v\nnot equal at index %d",
|
||||
expectConditions, &actualConditions, i)
|
||||
}
|
||||
}, 60*time.Second, 1*time.Second, "wanted conditions for ActiveDirectoryIdentityProvider %q", activeDirectoryIDPName)
|
||||
}
|
||||
|
||||
func TestObjectMeta(t *testing.T, baseName string) metav1.ObjectMeta {
|
||||
return metav1.ObjectMeta{
|
||||
GenerateName: fmt.Sprintf("test-%s-", baseName),
|
||||
|
||||
Reference in New Issue
Block a user