mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-02-14 10:00:05 +00:00
integration tests decide if cluster supports anon auth more dynamically
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user