integration tests decide if cluster supports anon auth more dynamically

This commit is contained in:
Ryan Richard
2026-01-22 12:53:11 -08:00
parent 0f0f3997a0
commit 736e2472c6
10 changed files with 166 additions and 71 deletions

View File

@@ -1,4 +1,4 @@
# Copyright 2021 the Pinniped contributors. All Rights Reserved. # Copyright 2021-2026 the Pinniped contributors. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# The name of the cluster type. # The name of the cluster type.
@@ -13,9 +13,13 @@ capabilities:
# Will the cluster successfully provision a load balancer if requested? # Will the cluster successfully provision a load balancer if requested?
hasExternalLoadBalancerProvider: true hasExternalLoadBalancerProvider: true
# Does the cluster allow requests without authentication?
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
anonymousAuthenticationSupported: false
# Are LDAP ports on the Internet reachable without interference from network firewalls or proxies? # Are LDAP ports on the Internet reachable without interference from network firewalls or proxies?
canReachInternetLDAPPorts: true canReachInternetLDAPPorts: true
# Does the cluster allow requests without authentication?
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
anonymousAuthentication:
healthEndpoints:
allowed: false
otherEndpoints:
allowed: false

View File

@@ -1,4 +1,4 @@
# Copyright 2021 the Pinniped contributors. All Rights Reserved. # Copyright 2021-2026 the Pinniped contributors. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# The name of the cluster type. # The name of the cluster type.
@@ -13,9 +13,14 @@ capabilities:
# Will the cluster successfully provision a load balancer if requested? # Will the cluster successfully provision a load balancer if requested?
hasExternalLoadBalancerProvider: true hasExternalLoadBalancerProvider: true
# Does the cluster allow requests without authentication?
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
anonymousAuthenticationSupported: true
# Are LDAP ports on the Internet reachable without interference from network firewalls or proxies? # Are LDAP ports on the Internet reachable without interference from network firewalls or proxies?
canReachInternetLDAPPorts: true canReachInternetLDAPPorts: true
# Does the cluster allow requests without authentication?
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
# Amazon disabled anonymous authentication in EKS clusters starting with k8s 1.32.
anonymousAuthentication:
healthEndpoints:
allowed: true
otherEndpoints:
allowedIfK8sMinorVersionLessThan: 32

View File

@@ -1,4 +1,4 @@
# Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. # Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# The name of the cluster type. # The name of the cluster type.
@@ -13,9 +13,14 @@ capabilities:
# Will the cluster successfully provision a load balancer if requested? # Will the cluster successfully provision a load balancer if requested?
hasExternalLoadBalancerProvider: true hasExternalLoadBalancerProvider: true
# Does the cluster allow requests without authentication?
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
anonymousAuthenticationSupported: true
# Are LDAP ports on the Internet reachable without interference from network firewalls or proxies? # Are LDAP ports on the Internet reachable without interference from network firewalls or proxies?
canReachInternetLDAPPorts: true canReachInternetLDAPPorts: true
# Does the cluster allow requests without authentication?
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
# Google disabled anonymous authentication in GKE clusters by default starting with k8s 1.35.
anonymousAuthentication:
healthEndpoints:
allowed: true
otherEndpoints:
allowedIfK8sMinorVersionLessThan: 35

View File

@@ -1,4 +1,4 @@
# Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. # Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# The name of the cluster type. # The name of the cluster type.
@@ -13,9 +13,13 @@ capabilities:
# Will the cluster successfully provision a load balancer if requested? # Will the cluster successfully provision a load balancer if requested?
hasExternalLoadBalancerProvider: false hasExternalLoadBalancerProvider: false
# Does the cluster allow requests without authentication?
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
anonymousAuthenticationSupported: true
# Are LDAP ports on the Internet reachable without interference from network firewalls or proxies? # Are LDAP ports on the Internet reachable without interference from network firewalls or proxies?
canReachInternetLDAPPorts: true canReachInternetLDAPPorts: true
# Does the cluster allow requests without authentication?
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
anonymousAuthentication:
healthEndpoints:
allowed: true
otherEndpoints:
allowed: true

View File

@@ -1,4 +1,4 @@
# Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. # Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# The name of the cluster type. # The name of the cluster type.
@@ -13,9 +13,13 @@ capabilities:
# Will the cluster successfully provision a load balancer if requested? # Will the cluster successfully provision a load balancer if requested?
hasExternalLoadBalancerProvider: true hasExternalLoadBalancerProvider: true
# Does the cluster allow requests without authentication?
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
anonymousAuthenticationSupported: true
# Are LDAP ports on the Internet reachable without interference from network firewalls or proxies? # Are LDAP ports on the Internet reachable without interference from network firewalls or proxies?
canReachInternetLDAPPorts: true canReachInternetLDAPPorts: true
# Does the cluster allow requests without authentication?
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
anonymousAuthentication:
healthEndpoints:
allowed: true
otherEndpoints:
allowed: true

View File

@@ -1,4 +1,4 @@
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package integration package integration
@@ -218,7 +218,7 @@ func TestCredentialRequest_Browser(t *testing.T) {
// for its localhost listener via --listen-port=env.CLIUpstreamOIDC.CallbackURL.Port() per oidcLoginCommand. // for its localhost listener via --listen-port=env.CLIUpstreamOIDC.CallbackURL.Port() per oidcLoginCommand.
// Since ports are global to the process, tests using oidcLoginCommand must be run serially. // Since ports are global to the process, tests using oidcLoginCommand must be run serially.
func TestCredentialRequest_JWTAuthenticatorRulesToDisallowLogin_Browser(t *testing.T) { func TestCredentialRequest_JWTAuthenticatorRulesToDisallowLogin_Browser(t *testing.T) {
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported) env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
basicSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{ basicSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{
Issuer: env.CLIUpstreamOIDC.Issuer, Issuer: env.CLIUpstreamOIDC.Issuer,
@@ -321,7 +321,7 @@ func TestCredentialRequest_JWTAuthenticatorRulesToDisallowLogin_Browser(t *testi
// TCRs are non-mutating and safe to run in parallel with serial tests, see main_test.go. // TCRs are non-mutating and safe to run in parallel with serial tests, see main_test.go.
func TestCredentialRequest_ShouldFailWhenTheAuthenticatorDoesNotExist_Parallel(t *testing.T) { func TestCredentialRequest_ShouldFailWhenTheAuthenticatorDoesNotExist_Parallel(t *testing.T) {
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported) env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
t.Cleanup(cancel) t.Cleanup(cancel)
@@ -344,7 +344,7 @@ func TestCredentialRequest_ShouldFailWhenTheAuthenticatorDoesNotExist_Parallel(t
// TCRs are non-mutating and safe to run in parallel with serial tests, see main_test.go. // TCRs are non-mutating and safe to run in parallel with serial tests, see main_test.go.
func TestCredentialRequest_ShouldFailWhenTheRequestIsValidButTheTokenDoesNotAuthenticateTheUser_Parallel(t *testing.T) { func TestCredentialRequest_ShouldFailWhenTheRequestIsValidButTheTokenDoesNotAuthenticateTheUser_Parallel(t *testing.T) {
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported) env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
// Create a testWebhook so we have a legitimate authenticator to pass to the TokenCredentialRequest API. // Create a testWebhook so we have a legitimate authenticator to pass to the TokenCredentialRequest API.
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
@@ -365,7 +365,7 @@ func TestCredentialRequest_ShouldFailWhenTheRequestIsValidButTheTokenDoesNotAuth
// TCRs are non-mutating and safe to run in parallel with serial tests, see main_test.go. // TCRs are non-mutating and safe to run in parallel with serial tests, see main_test.go.
func TestCredentialRequest_ShouldFailWhenRequestDoesNotIncludeToken_Parallel(t *testing.T) { func TestCredentialRequest_ShouldFailWhenRequestDoesNotIncludeToken_Parallel(t *testing.T) {
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported) env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
// Create a testWebhook so we have a legitimate authenticator to pass to the TokenCredentialRequest API. // Create a testWebhook so we have a legitimate authenticator to pass to the TokenCredentialRequest API.
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)

View File

@@ -1,4 +1,4 @@
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package integration package integration
@@ -902,8 +902,8 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
whoAmI, err = impersonationProxyAnonymousPinnipedConciergeClient.IdentityV1alpha1().WhoAmIRequests(). whoAmI, err = impersonationProxyAnonymousPinnipedConciergeClient.IdentityV1alpha1().WhoAmIRequests().
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 regard to anonymous requests
if env.HasCapability(testlib.AnonymousAuthenticationSupported) { if env.HasCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints) {
require.NoError(t, err, testlib.Sdump(err)) require.NoError(t, err, testlib.Sdump(err))
require.Equal(t, require.Equal(t,
expectedWhoAmIRequestResponse( expectedWhoAmIRequestResponse(
@@ -1409,8 +1409,8 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
}) })
}) })
t.Run("anonymous authentication enabled", func(t *testing.T) { t.Run("anonymous authentication enabled for health checks", func(t *testing.T) {
testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported) testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForHealthEndpoints)
parallelIfNotEKS(t) parallelIfNotEKS(t)
// anonymous auth enabled // anonymous auth enabled
@@ -1421,11 +1421,50 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
t.Run("non-resource request", func(t *testing.T) { t.Run("non-resource request", func(t *testing.T) {
parallelIfNotEKS(t) parallelIfNotEKS(t)
healthz, errHealth := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx) response, err := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx)
require.NoError(t, errHealth, testlib.Sdump(errHealth)) require.NoError(t, err, testlib.Sdump(err))
require.Equal(t, "ok", string(healthz)) require.Equal(t, "ok", string(response))
})
response, err = impersonationProxyAnonymousRestClient.Get().AbsPath("/readyz").DoRaw(ctx)
require.NoError(t, err, testlib.Sdump(err))
require.Equal(t, "ok", string(response))
response, err = impersonationProxyAnonymousRestClient.Get().AbsPath("/livez").DoRaw(ctx)
require.NoError(t, err, testlib.Sdump(err))
require.Equal(t, "ok", string(response))
})
})
t.Run("anonymous authentication disabled for health checks", func(t *testing.T) {
testlib.IntegrationEnv(t).WithoutCapability(testlib.AnonymousAuthenticationSupportedForHealthEndpoints)
parallelIfNotEKS(t)
// anonymous auth disabled
// - hit the healthz endpoint (non-resource endpoint)
// - through the impersonation proxy
// - should fail Unauthorized
t.Run("non-resource request", func(t *testing.T) {
parallelIfNotEKS(t)
expectedResponse := `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}` + "\n"
response, err := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx)
require.True(t, apierrors.IsUnauthorized(err), testlib.Sdump(err))
require.Equal(t, expectedResponse, string(response))
response, err = impersonationProxyAnonymousRestClient.Get().AbsPath("/readyz").DoRaw(ctx)
require.True(t, apierrors.IsUnauthorized(err), testlib.Sdump(err))
require.Equal(t, expectedResponse, string(response))
response, err = impersonationProxyAnonymousRestClient.Get().AbsPath("/livez").DoRaw(ctx)
require.True(t, apierrors.IsUnauthorized(err), testlib.Sdump(err))
require.Equal(t, expectedResponse, string(response))
})
})
t.Run("anonymous authentication enabled for other endpoints", func(t *testing.T) {
testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
parallelIfNotEKS(t)
// - hit the pods endpoint (a resource endpoint) // - hit the pods endpoint (a resource endpoint)
// - through the impersonation proxy // - through the impersonation proxy
// - should fail forbidden // - should fail forbidden
@@ -1462,22 +1501,10 @@ 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 for other endpoints", func(t *testing.T) {
testlib.IntegrationEnv(t).WithoutCapability(testlib.AnonymousAuthenticationSupported) testlib.IntegrationEnv(t).WithoutCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
parallelIfNotEKS(t) parallelIfNotEKS(t)
// - hit the healthz endpoint (non-resource endpoint)
// - through the impersonation proxy
// - should fail unauthorized
// - kube api server should reject it
t.Run("non-resource request", func(t *testing.T) {
parallelIfNotEKS(t)
healthz, err := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx)
require.True(t, apierrors.IsUnauthorized(err), testlib.Sdump(err))
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(healthz))
})
// - hit the pods endpoint (a resource endpoint) // - hit the pods endpoint (a resource endpoint)
// - through the impersonation proxy // - through the impersonation proxy
// - should fail unauthorized // - should fail unauthorized
@@ -1491,7 +1518,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
require.Equal(t, &corev1.Pod{}, pod) require.Equal(t, &corev1.Pod{}, pod)
}) })
// - request to whoami (pinniped resource endpoing) // - request to whoami (pinniped resource endpoint)
// - through the impersonation proxy // - through the impersonation proxy
// - should fail unauthorized // - should fail unauthorized
// - kube api server should reject it // - kube api server should reject it
@@ -1982,7 +2009,7 @@ 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(testlib.ClusterSigningKeyIsAvailable) && env.HasCapability(testlib.AnonymousAuthenticationSupported) { if !env.HasCapability(testlib.ClusterSigningKeyIsAvailable) && env.HasCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints) {
// 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

View File

@@ -1,4 +1,4 @@
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package integration package integration
@@ -394,7 +394,7 @@ func maybeNeedsExtraWithSHA256(
// whoami requests are non-mutating and safe to run in parallel with serial tests, see main_test.go. // whoami requests are non-mutating and safe to run in parallel with serial tests, see main_test.go.
func TestWhoAmI_Anonymous_Parallel(t *testing.T) { func TestWhoAmI_Anonymous_Parallel(t *testing.T) {
_ = testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported) _ = testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()

View File

@@ -1,4 +1,4 @@
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved. // Copyright 2022-2026 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package integration package integration
@@ -1040,11 +1040,11 @@ func TestOIDCClientSecretRequestUnauthenticated_Parallel(t *testing.T) {
}, metav1.CreateOptions{}) }, metav1.CreateOptions{})
require.Error(t, err) require.Error(t, err)
if env.KubernetesDistribution == testlib.AKSDistro { if env.HasCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints) {
// On AKS the error just says "Unauthorized".
require.Contains(t, err.Error(), "Unauthorized")
} else {
// Clusters which allow anonymous auth will give a more detailed error. // Clusters which allow anonymous auth will give a more detailed error.
require.Contains(t, err.Error(), `User "system:anonymous" cannot create resource "oidcclientsecretrequests"`) require.Contains(t, err.Error(), `User "system:anonymous" cannot create resource "oidcclientsecretrequests"`)
} else {
// On AKS and any other cluster which disallows anonymous auth, the error just says "Unauthorized".
require.Contains(t, err.Error(), "Unauthorized")
} }
} }

View File

@@ -1,4 +1,4 @@
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package testlib package testlib
@@ -9,6 +9,7 @@ import (
"net/url" "net/url"
"os" "os"
"sort" "sort"
"strconv"
"strings" "strings"
"sync" "sync"
"testing" "testing"
@@ -17,16 +18,18 @@ import (
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1" authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
"go.pinniped.dev/internal/testutil"
) )
type Capability string type Capability string
type KubeDistro string type KubeDistro string
const ( const (
ClusterSigningKeyIsAvailable Capability = "clusterSigningKeyIsAvailable" ClusterSigningKeyIsAvailable Capability = "clusterSigningKeyIsAvailable"
AnonymousAuthenticationSupported Capability = "anonymousAuthenticationSupported" HasExternalLoadBalancerProvider Capability = "hasExternalLoadBalancerProvider"
HasExternalLoadBalancerProvider Capability = "hasExternalLoadBalancerProvider" CanReachInternetLDAPPorts Capability = "canReachInternetLDAPPorts"
CanReachInternetLDAPPorts Capability = "canReachInternetLDAPPorts" AnonymousAuthenticationSupportedForHealthEndpoints Capability = "anonymousAuthenticationSupportedForHealthEndpoints"
AnonymousAuthenticationSupportedForOtherEndpoints Capability = "anonymousAuthenticationSupportedForOtherEndpoints"
KindDistro KubeDistro = "Kind" KindDistro KubeDistro = "Kind"
GKEDistro KubeDistro = "GKE" GKEDistro KubeDistro = "GKE"
@@ -35,6 +38,24 @@ const (
TKGSDistro KubeDistro = "TKGS" TKGSDistro KubeDistro = "TKGS"
) )
type Capabilities struct {
ClusterSigningKeyIsAvailable bool `json:"clusterSigningKeyIsAvailable"`
HasExternalLoadBalancerProvider bool `json:"hasExternalLoadBalancerProvider"`
CanReachInternetLDAPPorts bool `json:"canReachInternetLDAPPorts"`
AnonymousAuthentication AnonymousAuthenticationCapabilities `json:"anonymousAuthentication"`
}
type AnonymousAuthenticationCapabilities struct {
HealthEndpoints AnonymousAuthenticationEndpointCapability `json:"healthEndpoints"`
OtherEndpoints AnonymousAuthenticationEndpointCapability `json:"otherEndpoints"`
}
type AnonymousAuthenticationEndpointCapability struct {
Allowed bool `json:"allowed"`
AllowedIfK8sMinorVersionLessThan string `json:"allowedIfK8sMinorVersionLessThan"`
}
// TestEnv captures all the external parameters consumed by our integration tests. // TestEnv captures all the external parameters consumed by our integration tests.
type TestEnv struct { type TestEnv struct {
t *testing.T t *testing.T
@@ -50,7 +71,7 @@ type TestEnv struct {
SupervisorCustomLabels map[string]string `json:"supervisorCustomLabels"` SupervisorCustomLabels map[string]string `json:"supervisorCustomLabels"`
ConciergeCustomLabels map[string]string `json:"conciergeCustomLabels"` ConciergeCustomLabels map[string]string `json:"conciergeCustomLabels"`
KubernetesDistribution KubeDistro `json:"kubernetesDistribution"` KubernetesDistribution KubeDistro `json:"kubernetesDistribution"`
Capabilities map[Capability]bool `json:"capabilities"` Capabilities Capabilities `json:"capabilities"`
TestWebhook authenticationv1alpha1.WebhookAuthenticatorSpec `json:"testWebhook"` TestWebhook authenticationv1alpha1.WebhookAuthenticatorSpec `json:"testWebhook"`
SupervisorHTTPSAddress string `json:"supervisorHttpsAddress"` SupervisorHTTPSAddress string `json:"supervisorHttpsAddress"`
SupervisorHTTPSIngressAddress string `json:"supervisorHttpsIngressAddress"` SupervisorHTTPSIngressAddress string `json:"supervisorHttpsIngressAddress"`
@@ -400,9 +421,34 @@ func loadEnvVars(t *testing.T, result *TestEnv) {
func (e *TestEnv) HasCapability(cap Capability) bool { func (e *TestEnv) HasCapability(cap Capability) bool {
e.t.Helper() e.t.Helper()
isCapable, capabilityWasDescribed := e.Capabilities[cap]
require.Truef(e.t, capabilityWasDescribed, "the %q capability of the test environment was not described", cap) switch cap {
return isCapable case AnonymousAuthenticationSupportedForHealthEndpoints:
versionLessThan := e.Capabilities.AnonymousAuthentication.HealthEndpoints.AllowedIfK8sMinorVersionLessThan
if versionLessThan == "" {
return e.Capabilities.AnonymousAuthentication.HealthEndpoints.Allowed
}
minorVersionNumber, err := strconv.Atoi(versionLessThan)
require.NoError(e.t, err, "could not parse minor version number from AnonymousAuthentication HealthEndpoints capability as int")
return !testutil.KubeServerMinorVersionAtLeastInclusive(e.t, NewKubernetesClientset(e.t).Discovery(), minorVersionNumber)
case AnonymousAuthenticationSupportedForOtherEndpoints:
versionLessThan := e.Capabilities.AnonymousAuthentication.OtherEndpoints.AllowedIfK8sMinorVersionLessThan
if versionLessThan == "" {
return e.Capabilities.AnonymousAuthentication.OtherEndpoints.Allowed
}
minorVersionNumber, err := strconv.Atoi(versionLessThan)
require.NoError(e.t, err, "could not parse minor version number from AnonymousAuthentication OtherEndpoints capability as int")
return !testutil.KubeServerMinorVersionAtLeastInclusive(e.t, NewKubernetesClientset(e.t).Discovery(), minorVersionNumber)
case ClusterSigningKeyIsAvailable:
return e.Capabilities.ClusterSigningKeyIsAvailable
case HasExternalLoadBalancerProvider:
return e.Capabilities.HasExternalLoadBalancerProvider
case CanReachInternetLDAPPorts:
return e.Capabilities.CanReachInternetLDAPPorts
default:
require.Failf(e.t, "unknown capability type", "name: %s", cap)
return false
}
} }
func (e *TestEnv) WithCapability(cap Capability) *TestEnv { func (e *TestEnv) WithCapability(cap Capability) *TestEnv {