Merge pull request #1947 from vmware-tanzu/jtc/add-importas-linter

Enforce import aliases
This commit is contained in:
Joshua Casey
2024-06-11 12:27:57 -05:00
committed by GitHub
187 changed files with 4057 additions and 3977 deletions
+65
View File
@@ -48,6 +48,10 @@ linters:
- fatcontext
# - canonicalheader Can't do this one since it alerts on valid headers such as X-XSS-Protection
- spancheck
- importas
- makezero
- prealloc
- gofmt
issues:
exclude-dirs:
@@ -91,3 +95,64 @@ linters-settings:
- end
- record-error
- set-status
importas:
no-unaliased: true # All packages explicitly listed below must be aliased
no-extra-aliases: false # Allow other aliases than the ones explicitly listed below
alias:
# k8s.io/apimachinery
- pkg: k8s.io/apimachinery/pkg/util/errors
alias: utilerrors
- pkg: k8s.io/apimachinery/pkg/api/errors
alias: apierrors
- pkg: k8s.io/apimachinery/pkg/apis/meta/v1
alias: metav1
# k8s.io
- pkg: k8s.io/api/core/v1
alias: corev1
# OAuth2/OIDC/Fosite
- pkg: github.com/coreos/go-oidc/v3/oidc
alias: coreosoidc
- pkg: github.com/ory/fosite/handler/oauth2
alias: fositeoauth2
# Generated Pinniped
- pkg: go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1
alias: authenticationv1alpha1
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/clientsecret/v1alpha1
alias: clientsecretv1alpha1
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1
alias: supervisorconfigv1alpha1
- pkg: go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1
alias: conciergeconfigv1alpha1
- pkg: go.pinniped.dev/generated/latest/client/concierge/clientset/versioned
alias: conciergeclientset
- pkg: go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/scheme
alias: conciergeclientsetscheme
- pkg: go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake
alias: conciergefake
- pkg: go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned
alias: supervisorclientset
- pkg: go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/scheme
alias: supervisorclientsetscheme
- pkg: go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake
alias: supervisorfake
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1
alias: idpv1alpha1
- pkg: go.pinniped.dev/generated/latest/client/concierge/informers/externalversions
alias: conciergeinformers
- pkg: go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions
alias: supervisorinformers
# Pinniped internal
- pkg: go.pinniped.dev/internal/concierge/scheme
alias: conciergescheme
gofmt:
# Simplify code: gofmt with `-s` option.
# Default: true
simplify: false
# Apply the rewrite rules to the source before reformatting.
# https://pkg.go.dev/cmd/gofmt
# Default: []
rewrite-rules:
- pattern: 'interface{}'
replacement: 'any'
- pattern: 'a[b:len(a)]'
replacement: 'a[b:]'
@@ -94,7 +94,7 @@ func TestEntrypoint(t *testing.T) {
var logBuf bytes.Buffer
testLog := log.New(&logBuf, "", 0)
exited := "exiting via fatal"
fail = func(format string, v ...interface{}) {
fail = func(format string, v ...any) {
testLog.Printf(format, v...)
panic(exited)
}
+1 -1
View File
@@ -42,7 +42,7 @@ func TestEntrypoint(t *testing.T) {
var logBuf bytes.Buffer
testLog := log.New(&logBuf, "", 0)
exited := "exiting via fatal"
fail = func(err error, keysAndValues ...interface{}) {
fail = func(err error, keysAndValues ...any) {
testLog.Print(err)
if len(keysAndValues) > 0 {
testLog.Print(keysAndValues...)
+5 -5
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package cmd
@@ -13,7 +13,7 @@ import (
"github.com/spf13/pflag"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
)
// conciergeModeFlag represents the method by which we should connect to the Concierge on a cluster during login.
@@ -62,12 +62,12 @@ func (f *conciergeModeFlag) Type() string {
}
// MatchesFrontend returns true iff the flag matches the type of the provided frontend.
func (f *conciergeModeFlag) MatchesFrontend(frontend *configv1alpha1.CredentialIssuerFrontend) bool {
func (f *conciergeModeFlag) MatchesFrontend(frontend *conciergeconfigv1alpha1.CredentialIssuerFrontend) bool {
switch *f {
case modeImpersonationProxy:
return frontend.Type == configv1alpha1.ImpersonationProxyFrontendType
return frontend.Type == conciergeconfigv1alpha1.ImpersonationProxyFrontendType
case modeTokenCredentialRequestAPI:
return frontend.Type == configv1alpha1.TokenCredentialRequestAPIFrontendType
return frontend.Type == conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType
case modeUnknown:
fallthrough
default:
+8 -8
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package cmd
@@ -13,7 +13,7 @@ import (
"github.com/stretchr/testify/require"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
"go.pinniped.dev/internal/certauthority"
)
@@ -24,14 +24,14 @@ func TestConciergeModeFlag(t *testing.T) {
require.NoError(t, f.Set(""))
require.Equal(t, modeUnknown, f)
require.EqualError(t, f.Set("foo"), `invalid mode "foo", valid modes are TokenCredentialRequestAPI and ImpersonationProxy`)
require.True(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.TokenCredentialRequestAPIFrontendType}))
require.True(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.ImpersonationProxyFrontendType}))
require.True(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType}))
require.True(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.ImpersonationProxyFrontendType}))
require.NoError(t, f.Set("TokenCredentialRequestAPI"))
require.Equal(t, modeTokenCredentialRequestAPI, f)
require.Equal(t, "TokenCredentialRequestAPI", f.String())
require.True(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.TokenCredentialRequestAPIFrontendType}))
require.False(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.ImpersonationProxyFrontendType}))
require.True(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType}))
require.False(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.ImpersonationProxyFrontendType}))
require.NoError(t, f.Set("tokencredentialrequestapi"))
require.Equal(t, modeTokenCredentialRequestAPI, f)
@@ -40,8 +40,8 @@ func TestConciergeModeFlag(t *testing.T) {
require.NoError(t, f.Set("ImpersonationProxy"))
require.Equal(t, modeImpersonationProxy, f)
require.Equal(t, "ImpersonationProxy", f.String())
require.False(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.TokenCredentialRequestAPIFrontendType}))
require.True(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.ImpersonationProxyFrontendType}))
require.False(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType}))
require.True(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.ImpersonationProxyFrontendType}))
require.NoError(t, f.Set("impersonationproxy"))
require.Equal(t, modeImpersonationProxy, f)
+29 -29
View File
@@ -12,6 +12,7 @@ import (
"io"
"net/http"
"os"
"slices"
"strconv"
"strings"
"time"
@@ -23,10 +24,9 @@ import (
_ "k8s.io/client-go/plugin/pkg/client/auth" // Adds handlers for various dynamic auth plugins in client-go
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/utils/strings/slices"
conciergev1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
idpdiscoveryv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
@@ -314,7 +314,7 @@ func newExecConfig(deps kubeconfigDeps, flags getKubeconfigParams) (*clientcmdap
if flags.staticToken != "" && flags.staticTokenEnvName != "" {
return nil, fmt.Errorf("only one of --static-token and --static-token-env can be specified")
}
execConfig.Args = append([]string{"login", "static"}, execConfig.Args...)
execConfig.Args = slices.Concat([]string{"login", "static"}, execConfig.Args)
if flags.staticToken != "" {
execConfig.Args = append(execConfig.Args, "--token="+flags.staticToken)
}
@@ -325,7 +325,7 @@ func newExecConfig(deps kubeconfigDeps, flags getKubeconfigParams) (*clientcmdap
}
// Otherwise continue to parse the OIDC-related flags and output a config that runs `pinniped login oidc`.
execConfig.Args = append([]string{"login", "oidc"}, execConfig.Args...)
execConfig.Args = slices.Concat([]string{"login", "oidc"}, execConfig.Args)
if flags.oidc.issuer == "" {
return nil, fmt.Errorf("could not autodiscover --oidc-issuer and none was provided")
}
@@ -391,7 +391,7 @@ func getCurrentContext(currentKubeConfig clientcmdapi.Config, flags getKubeconfi
return &kubeconfigNames{ContextName: contextName, UserName: ctx.AuthInfo, ClusterName: ctx.Cluster}, nil
}
func waitForCredentialIssuer(ctx context.Context, clientset conciergeclientset.Interface, flags getKubeconfigParams, deps kubeconfigDeps) (*configv1alpha1.CredentialIssuer, error) {
func waitForCredentialIssuer(ctx context.Context, clientset conciergeclientset.Interface, flags getKubeconfigParams, deps kubeconfigDeps) (*conciergeconfigv1alpha1.CredentialIssuer, error) {
credentialIssuer, err := lookupCredentialIssuer(clientset, flags.concierge.credentialIssuer, deps.log)
if err != nil {
return nil, err
@@ -427,7 +427,7 @@ func waitForCredentialIssuer(ctx context.Context, clientset conciergeclientset.I
return credentialIssuer, nil
}
func discoverConciergeParams(credentialIssuer *configv1alpha1.CredentialIssuer, flags *getKubeconfigParams, v1Cluster *clientcmdapi.Cluster, log plog.MinLogger) error {
func discoverConciergeParams(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer, flags *getKubeconfigParams, v1Cluster *clientcmdapi.Cluster, log plog.MinLogger) error {
// Autodiscover the --concierge-mode.
frontend, err := getConciergeFrontend(credentialIssuer, flags.concierge.mode)
if err != nil {
@@ -438,10 +438,10 @@ func discoverConciergeParams(credentialIssuer *configv1alpha1.CredentialIssuer,
// Auto-set --concierge-mode if it wasn't explicitly set.
if flags.concierge.mode == modeUnknown {
switch frontend.Type {
case configv1alpha1.TokenCredentialRequestAPIFrontendType:
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType:
log.Info("discovered Concierge operating in TokenCredentialRequest API mode")
flags.concierge.mode = modeTokenCredentialRequestAPI
case configv1alpha1.ImpersonationProxyFrontendType:
case conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
log.Info("discovered Concierge operating in impersonation proxy mode")
flags.concierge.mode = modeImpersonationProxy
}
@@ -450,9 +450,9 @@ func discoverConciergeParams(credentialIssuer *configv1alpha1.CredentialIssuer,
// Auto-set --concierge-endpoint if it wasn't explicitly set.
if flags.concierge.endpoint == "" {
switch frontend.Type {
case configv1alpha1.TokenCredentialRequestAPIFrontendType:
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType:
flags.concierge.endpoint = v1Cluster.Server
case configv1alpha1.ImpersonationProxyFrontendType:
case conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
flags.concierge.endpoint = frontend.ImpersonationProxyInfo.Endpoint
}
log.Info("discovered Concierge endpoint", "endpoint", flags.concierge.endpoint)
@@ -461,9 +461,9 @@ func discoverConciergeParams(credentialIssuer *configv1alpha1.CredentialIssuer,
// Auto-set --concierge-ca-bundle if it wasn't explicitly set..
if len(flags.concierge.caBundle) == 0 {
switch frontend.Type {
case configv1alpha1.TokenCredentialRequestAPIFrontendType:
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType:
flags.concierge.caBundle = v1Cluster.CertificateAuthorityData
case configv1alpha1.ImpersonationProxyFrontendType:
case conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
data, err := base64.StdEncoding.DecodeString(frontend.ImpersonationProxyInfo.CertificateAuthorityData)
if err != nil {
return fmt.Errorf("autodiscovered Concierge CA bundle is invalid: %w", err)
@@ -475,7 +475,7 @@ func discoverConciergeParams(credentialIssuer *configv1alpha1.CredentialIssuer,
return nil
}
func logStrategies(credentialIssuer *configv1alpha1.CredentialIssuer, log plog.MinLogger) {
func logStrategies(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer, log plog.MinLogger) {
for _, strategy := range credentialIssuer.Status.Strategies {
log.Info("found CredentialIssuer strategy",
"type", strategy.Type,
@@ -488,7 +488,7 @@ func logStrategies(credentialIssuer *configv1alpha1.CredentialIssuer, log plog.M
func discoverAuthenticatorParams(authenticator metav1.Object, flags *getKubeconfigParams, log plog.MinLogger) error {
switch auth := authenticator.(type) {
case *conciergev1alpha1.WebhookAuthenticator:
case *authenticationv1alpha1.WebhookAuthenticator:
// If the --concierge-authenticator-type/--concierge-authenticator-name flags were not set explicitly, set
// them to point at the discovered WebhookAuthenticator.
if flags.concierge.authenticatorType == "" && flags.concierge.authenticatorName == "" {
@@ -496,7 +496,7 @@ func discoverAuthenticatorParams(authenticator metav1.Object, flags *getKubeconf
flags.concierge.authenticatorType = "webhook"
flags.concierge.authenticatorName = auth.Name
}
case *conciergev1alpha1.JWTAuthenticator:
case *authenticationv1alpha1.JWTAuthenticator:
// If the --concierge-authenticator-type/--concierge-authenticator-name flags were not set explicitly, set
// them to point at the discovered JWTAuthenticator.
if flags.concierge.authenticatorType == "" && flags.concierge.authenticatorName == "" {
@@ -531,19 +531,19 @@ func discoverAuthenticatorParams(authenticator metav1.Object, flags *getKubeconf
return nil
}
func getConciergeFrontend(credentialIssuer *configv1alpha1.CredentialIssuer, mode conciergeModeFlag) (*configv1alpha1.CredentialIssuerFrontend, error) {
func getConciergeFrontend(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer, mode conciergeModeFlag) (*conciergeconfigv1alpha1.CredentialIssuerFrontend, error) {
for _, strategy := range credentialIssuer.Status.Strategies {
// Skip unhealthy strategies.
if strategy.Status != configv1alpha1.SuccessStrategyStatus {
if strategy.Status != conciergeconfigv1alpha1.SuccessStrategyStatus {
continue
}
// Backfill the .status.strategies[].frontend field from .status.kubeConfigInfo for backwards compatibility.
if strategy.Type == configv1alpha1.KubeClusterSigningCertificateStrategyType && strategy.Frontend == nil && credentialIssuer.Status.KubeConfigInfo != nil {
if strategy.Type == conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType && strategy.Frontend == nil && credentialIssuer.Status.KubeConfigInfo != nil {
strategy = *strategy.DeepCopy()
strategy.Frontend = &configv1alpha1.CredentialIssuerFrontend{
Type: configv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &configv1alpha1.TokenCredentialRequestAPIInfo{
strategy.Frontend = &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
Server: credentialIssuer.Status.KubeConfigInfo.Server,
CertificateAuthorityData: credentialIssuer.Status.KubeConfigInfo.CertificateAuthorityData,
},
@@ -557,7 +557,7 @@ func getConciergeFrontend(credentialIssuer *configv1alpha1.CredentialIssuer, mod
// Skip any unknown frontend types.
switch strategy.Frontend.Type {
case configv1alpha1.TokenCredentialRequestAPIFrontendType, configv1alpha1.ImpersonationProxyFrontendType:
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType, conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
default:
continue
}
@@ -585,7 +585,7 @@ func newExecKubeconfig(cluster *clientcmdapi.Cluster, execConfig *clientcmdapi.E
}
}
func lookupCredentialIssuer(clientset conciergeclientset.Interface, name string, log plog.MinLogger) (*configv1alpha1.CredentialIssuer, error) {
func lookupCredentialIssuer(clientset conciergeclientset.Interface, name string, log plog.MinLogger) (*conciergeconfigv1alpha1.CredentialIssuer, error) {
ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*20)
defer cancelFunc()
@@ -747,9 +747,9 @@ func countCACerts(pemData []byte) int {
return len(pool.Subjects())
}
func hasPendingStrategy(credentialIssuer *configv1alpha1.CredentialIssuer) bool {
func hasPendingStrategy(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer) bool {
for _, strategy := range credentialIssuer.Status.Strategies {
if strategy.Reason == configv1alpha1.PendingStrategyReason {
if strategy.Reason == conciergeconfigv1alpha1.PendingStrategyReason {
return true
}
}
@@ -794,12 +794,12 @@ func pinnipedSupervisorDiscovery(ctx context.Context, flags *getKubeconfigParams
return err
}
if !supervisorSupportsBothUsernameAndGroupsScopes {
flags.oidc.scopes = slices.Filter(nil, flags.oidc.scopes, func(scope string) bool {
flags.oidc.scopes = slices.DeleteFunc(flags.oidc.scopes, func(scope string) bool {
if scope == oidcapi.ScopeUsername || scope == oidcapi.ScopeGroups {
log.Info("removed scope from --oidc-scopes list because it is not supported by this Supervisor", "scope", scope)
return false // Remove username and groups scopes if there were present in the flags.
return true // Remove username and groups scopes if there were present in the flags.
}
return true // Keep any other scopes in the flag list.
return false // Keep any other scopes in the flag list.
})
}
+92 -91
View File
@@ -10,6 +10,7 @@ import (
"net/http"
"os"
"path/filepath"
"slices"
"testing"
"time"
@@ -20,10 +21,10 @@ import (
"k8s.io/client-go/tools/clientcmd"
"k8s.io/utils/ptr"
conciergev1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
fakeconciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
conciergefake "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
"go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/internal/here"
"go.pinniped.dev/internal/testutil"
@@ -44,16 +45,16 @@ func TestGetKubeconfig(t *testing.T) {
require.NoError(t, os.WriteFile(testConciergeCABundlePath, testConciergeCA.Bundle(), 0600))
credentialIssuer := func() runtime.Object {
return &configv1alpha1.CredentialIssuer{
return &conciergeconfigv1alpha1.CredentialIssuer{
ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"},
Status: configv1alpha1.CredentialIssuerStatus{
Strategies: []configv1alpha1.CredentialIssuerStrategy{{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.SuccessStrategyStatus,
Reason: configv1alpha1.FetchedKeyStrategyReason,
Frontend: &configv1alpha1.CredentialIssuerFrontend{
Type: configv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &configv1alpha1.TokenCredentialRequestAPIInfo{
Status: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: conciergeconfigv1alpha1.FetchedKeyStrategyReason,
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
Server: "https://concierge-endpoint.example.com",
CertificateAuthorityData: base64.StdEncoding.EncodeToString(testConciergeCA.Bundle()),
},
@@ -64,12 +65,12 @@ func TestGetKubeconfig(t *testing.T) {
}
jwtAuthenticator := func(issuerCABundle string, issuerURL string) runtime.Object {
return &conciergev1alpha1.JWTAuthenticator{
return &authenticationv1alpha1.JWTAuthenticator{
ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"},
Spec: conciergev1alpha1.JWTAuthenticatorSpec{
Spec: authenticationv1alpha1.JWTAuthenticatorSpec{
Issuer: issuerURL,
Audience: "test-audience",
TLS: &conciergev1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(issuerCABundle)),
},
},
@@ -271,7 +272,7 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
&conciergeconfigv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
}
},
wantError: true,
@@ -290,7 +291,7 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
&conciergeconfigv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -314,7 +315,7 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
&conciergeconfigv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -338,7 +339,7 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
&conciergeconfigv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -360,7 +361,7 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
&conciergeconfigv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -391,7 +392,7 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
&conciergeconfigv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
}
},
conciergeReactions: []kubetesting.Reactor{
@@ -422,7 +423,7 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
&conciergeconfigv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -444,11 +445,11 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
&conciergev1alpha1.JWTAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator-1"}},
&conciergev1alpha1.JWTAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator-2"}},
&conciergev1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator-3"}},
&conciergev1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator-4"}},
&conciergeconfigv1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"}},
&authenticationv1alpha1.JWTAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator-1"}},
&authenticationv1alpha1.JWTAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator-2"}},
&authenticationv1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator-3"}},
&authenticationv1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator-4"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -474,18 +475,18 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{
&conciergeconfigv1alpha1.CredentialIssuer{
ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"},
Status: configv1alpha1.CredentialIssuerStatus{
Strategies: []configv1alpha1.CredentialIssuerStrategy{{
Status: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{{
Type: "SomeType",
Status: configv1alpha1.ErrorStrategyStatus,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: "SomeReason",
Message: "Some message",
}},
},
},
&conciergev1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
&authenticationv1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -508,36 +509,36 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{
&conciergeconfigv1alpha1.CredentialIssuer{
ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"},
Status: configv1alpha1.CredentialIssuerStatus{
Strategies: []configv1alpha1.CredentialIssuerStrategy{
Status: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{
{
Type: "SomeBrokenType",
Status: configv1alpha1.ErrorStrategyStatus,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: "SomeFailureReason",
Message: "Some error message",
LastUpdateTime: metav1.Now(),
},
{
Type: "SomeUnknownType",
Status: configv1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "SomeReason",
Message: "Some error message",
LastUpdateTime: metav1.Now(),
Frontend: &configv1alpha1.CredentialIssuerFrontend{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: "SomeUnknownFrontendType",
},
},
{
Type: "SomeType",
Status: configv1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "SomeReason",
Message: "Some message",
LastUpdateTime: metav1.Now(),
Frontend: &configv1alpha1.CredentialIssuerFrontend{
Type: configv1alpha1.ImpersonationProxyFrontendType,
ImpersonationProxyInfo: &configv1alpha1.ImpersonationProxyInfo{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.ImpersonationProxyFrontendType,
ImpersonationProxyInfo: &conciergeconfigv1alpha1.ImpersonationProxyInfo{
Endpoint: "https://impersonation-endpoint",
CertificateAuthorityData: "invalid-base-64",
},
@@ -546,7 +547,7 @@ func TestGetKubeconfig(t *testing.T) {
},
},
},
&conciergev1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
&authenticationv1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -571,7 +572,7 @@ func TestGetKubeconfig(t *testing.T) {
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
credentialIssuer(),
&conciergev1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
&authenticationv1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -597,17 +598,17 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{
&conciergeconfigv1alpha1.CredentialIssuer{
ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"},
Status: configv1alpha1.CredentialIssuerStatus{
KubeConfigInfo: &configv1alpha1.CredentialIssuerKubeConfigInfo{
Status: conciergeconfigv1alpha1.CredentialIssuerStatus{
KubeConfigInfo: &conciergeconfigv1alpha1.CredentialIssuerKubeConfigInfo{
Server: "https://concierge-endpoint",
CertificateAuthorityData: "ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==",
},
Strategies: []configv1alpha1.CredentialIssuerStrategy{{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.SuccessStrategyStatus,
Reason: configv1alpha1.FetchedKeyStrategyReason,
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: conciergeconfigv1alpha1.FetchedKeyStrategyReason,
Message: "Successfully fetched key",
LastUpdateTime: metav1.Now(),
// Simulate a previous version of CredentialIssuer that's missing this Frontend field.
@@ -615,12 +616,12 @@ func TestGetKubeconfig(t *testing.T) {
}},
},
},
&conciergev1alpha1.JWTAuthenticator{
&authenticationv1alpha1.JWTAuthenticator{
ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"},
Spec: conciergev1alpha1.JWTAuthenticatorSpec{
Spec: authenticationv1alpha1.JWTAuthenticatorSpec{
Issuer: issuerURL,
Audience: "some-test-audience",
TLS: &conciergev1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: "invalid-base64",
},
},
@@ -653,12 +654,12 @@ func TestGetKubeconfig(t *testing.T) {
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
credentialIssuer(),
&conciergev1alpha1.JWTAuthenticator{
&authenticationv1alpha1.JWTAuthenticator{
ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"},
Spec: conciergev1alpha1.JWTAuthenticatorSpec{
Spec: authenticationv1alpha1.JWTAuthenticatorSpec{
Issuer: issuerURL,
Audience: "some-test-audience.pinniped.dev-invalid-substring",
TLS: &conciergev1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(issuerCABundle)),
},
},
@@ -758,7 +759,7 @@ func TestGetKubeconfig(t *testing.T) {
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
credentialIssuer(),
&conciergev1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
&authenticationv1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -1009,9 +1010,9 @@ func TestGetKubeconfig(t *testing.T) {
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
credentialIssuer(),
&conciergev1alpha1.JWTAuthenticator{
&authenticationv1alpha1.JWTAuthenticator{
ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"},
Spec: conciergev1alpha1.JWTAuthenticatorSpec{
Spec: authenticationv1alpha1.JWTAuthenticatorSpec{
Issuer: issuerURL,
Audience: "test-audience",
},
@@ -1048,9 +1049,9 @@ func TestGetKubeconfig(t *testing.T) {
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
credentialIssuer(),
&conciergev1alpha1.JWTAuthenticator{
&authenticationv1alpha1.JWTAuthenticator{
ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"},
Spec: conciergev1alpha1.JWTAuthenticatorSpec{
Spec: authenticationv1alpha1.JWTAuthenticatorSpec{
Issuer: issuerURL,
Audience: "test-audience",
},
@@ -1398,7 +1399,7 @@ func TestGetKubeconfig(t *testing.T) {
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
credentialIssuer(),
&conciergev1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
&authenticationv1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -1462,7 +1463,7 @@ func TestGetKubeconfig(t *testing.T) {
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
credentialIssuer(),
&conciergev1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
&authenticationv1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -1616,7 +1617,7 @@ func TestGetKubeconfig(t *testing.T) {
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
credentialIssuer(),
&conciergev1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
&authenticationv1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
}
},
oidcDiscoveryResponse: onlyIssuerOIDCDiscoveryResponse,
@@ -1687,21 +1688,21 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{
&conciergeconfigv1alpha1.CredentialIssuer{
ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"},
Status: configv1alpha1.CredentialIssuerStatus{
Strategies: []configv1alpha1.CredentialIssuerStrategy{
Status: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{
// This TokenCredentialRequestAPI strategy would normally be chosen, but
// --concierge-mode=ImpersonationProxy should force it to be skipped.
{
Type: "SomeType",
Status: configv1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "SomeReason",
Message: "Some message",
LastUpdateTime: metav1.Now(),
Frontend: &configv1alpha1.CredentialIssuerFrontend{
Type: configv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &configv1alpha1.TokenCredentialRequestAPIInfo{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
Server: "https://token-credential-request-api-endpoint.test",
CertificateAuthorityData: "dGVzdC10Y3ItYXBpLWNh",
},
@@ -1710,13 +1711,13 @@ func TestGetKubeconfig(t *testing.T) {
// The endpoint and CA from this impersonation proxy strategy should be autodiscovered.
{
Type: "SomeOtherType",
Status: configv1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "SomeOtherReason",
Message: "Some other message",
LastUpdateTime: metav1.Now(),
Frontend: &configv1alpha1.CredentialIssuerFrontend{
Type: configv1alpha1.ImpersonationProxyFrontendType,
ImpersonationProxyInfo: &configv1alpha1.ImpersonationProxyInfo{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.ImpersonationProxyFrontendType,
ImpersonationProxyInfo: &conciergeconfigv1alpha1.ImpersonationProxyInfo{
Endpoint: "https://impersonation-proxy-endpoint.test",
CertificateAuthorityData: base64.StdEncoding.EncodeToString(testConciergeCA.Bundle()),
},
@@ -1798,19 +1799,19 @@ func TestGetKubeconfig(t *testing.T) {
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
&configv1alpha1.CredentialIssuer{
&conciergeconfigv1alpha1.CredentialIssuer{
ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"},
Status: configv1alpha1.CredentialIssuerStatus{
Strategies: []configv1alpha1.CredentialIssuerStrategy{
Status: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{
{
Type: "SomeType",
Status: configv1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "SomeReason",
Message: "Some message",
LastUpdateTime: metav1.Now(),
Frontend: &configv1alpha1.CredentialIssuerFrontend{
Type: configv1alpha1.ImpersonationProxyFrontendType,
ImpersonationProxyInfo: &configv1alpha1.ImpersonationProxyInfo{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.ImpersonationProxyFrontendType,
ImpersonationProxyInfo: &conciergeconfigv1alpha1.ImpersonationProxyInfo{
Endpoint: "https://impersonation-proxy-endpoint.test",
CertificateAuthorityData: "dGVzdC1jb25jaWVyZ2UtY2E=",
},
@@ -1818,13 +1819,13 @@ func TestGetKubeconfig(t *testing.T) {
},
{
Type: "SomeOtherType",
Status: configv1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "SomeOtherReason",
Message: "Some other message",
LastUpdateTime: metav1.Now(),
Frontend: &configv1alpha1.CredentialIssuerFrontend{
Type: configv1alpha1.ImpersonationProxyFrontendType,
ImpersonationProxyInfo: &configv1alpha1.ImpersonationProxyInfo{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.ImpersonationProxyFrontendType,
ImpersonationProxyInfo: &conciergeconfigv1alpha1.ImpersonationProxyInfo{
Endpoint: "https://some-other-impersonation-endpoint",
CertificateAuthorityData: "dGVzdC1jb25jaWVyZ2UtY2E=",
},
@@ -3146,7 +3147,7 @@ func TestGetKubeconfig(t *testing.T) {
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
credentialIssuer(),
&conciergev1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
&authenticationv1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
@@ -3248,12 +3249,12 @@ func TestGetKubeconfig(t *testing.T) {
if tt.getClientsetErr != nil {
return nil, tt.getClientsetErr
}
fake := fakeconciergeclientset.NewSimpleClientset()
fake := conciergefake.NewSimpleClientset()
if tt.conciergeObjects != nil {
fake = fakeconciergeclientset.NewSimpleClientset(tt.conciergeObjects(string(testServerCA), testServer.URL)...)
fake = conciergefake.NewSimpleClientset(tt.conciergeObjects(string(testServerCA), testServer.URL)...)
}
if len(tt.conciergeReactions) > 0 {
fake.ReactionChain = append(tt.conciergeReactions, fake.ReactionChain...)
fake.ReactionChain = slices.Concat(tt.conciergeReactions, fake.ReactionChain)
}
return fake, nil
},
+3 -3
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package cmd
@@ -12,7 +12,7 @@ import (
"time"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
@@ -99,7 +99,7 @@ func runWhoami(output io.Writer, getClientset getConciergeClientsetFunc, flags *
whoAmI, err := clientset.IdentityV1alpha1().WhoAmIRequests().Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
if err != nil {
hint := ""
if errors.IsNotFound(err) {
if apierrors.IsNotFound(err) {
hint = " (is the Pinniped WhoAmI API running and healthy?)"
}
return fmt.Errorf("could not complete WhoAmIRequest%s: %w", hint, err)
+4 -4
View File
@@ -8,14 +8,14 @@ import (
"testing"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
kubetesting "k8s.io/client-go/testing"
"k8s.io/client-go/tools/clientcmd"
identityv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/identity/v1alpha1"
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
fakeconciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
conciergefake "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
"go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/here"
)
@@ -273,7 +273,7 @@ func TestWhoami(t *testing.T) {
},
{
name: "calling API fails because WhoAmI API is not installed",
callingAPIErr: errors.NewNotFound(identityv1alpha1.SchemeGroupVersion.WithResource("whoamirequests").GroupResource(), "whatever"),
callingAPIErr: apierrors.NewNotFound(identityv1alpha1.SchemeGroupVersion.WithResource("whoamirequests").GroupResource(), "whatever"),
wantError: true,
wantStderr: "Error: could not complete WhoAmIRequest (is the Pinniped WhoAmI API running and healthy?): whoamirequests.identity.concierge.pinniped.dev \"whatever\" not found\n",
},
@@ -284,7 +284,7 @@ func TestWhoami(t *testing.T) {
if test.gettingClientsetErr != nil {
return nil, test.gettingClientsetErr
}
clientset := fakeconciergeclientset.NewSimpleClientset()
clientset := conciergefake.NewSimpleClientset()
clientset.PrependReactor("create", "whoamirequests", func(_ kubetesting.Action) (bool, runtime.Object, error) {
if test.callingAPIErr != nil {
return true, nil, test.callingAPIErr
+3
View File
@@ -50,6 +50,9 @@ function main() {
KUBE_PANIC_WATCH_DECODE_ERROR=${kube_panic_watch_decode_error} \
go test -short -race ./...
;;
'generate')
go generate ./internal/mocks/...
;;
*)
usage
;;
+6 -6
View File
@@ -1,4 +1,4 @@
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2023-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package celtransformer is an implementation of upstream-to-downstream identity transformations
@@ -228,8 +228,8 @@ func (c *baseCompiledTransformation) evalProgram(ctx context.Context, username s
// Evaluation is thread-safe and side effect free. Many inputs can be sent to the same cel.Program
// and if fields are present in the input, but not referenced in the expression, they are ignored.
// The argument to Eval may either be an `interpreter.Activation` or a `map[string]interface{}`.
val, _, err := c.program.ContextEval(timeoutCtx, map[string]interface{}{
// The argument to Eval may either be an `interpreter.Activation` or a `map[string]any`.
val, _, err := c.program.ContextEval(timeoutCtx, map[string]any{
usernameVariableName: username,
groupsVariableName: groups,
constStringVariableName: c.consts.StringConstants,
@@ -311,15 +311,15 @@ type CELTransformationSource struct {
Consts *TransformationConstants
}
func (c *compiledUsernameTransformation) Source() interface{} {
func (c *compiledUsernameTransformation) Source() any {
return &CELTransformationSource{Expr: c.sourceExpr, Consts: c.consts}
}
func (c *compiledGroupsTransformation) Source() interface{} {
func (c *compiledGroupsTransformation) Source() any {
return &CELTransformationSource{Expr: c.sourceExpr, Consts: c.consts}
}
func (c *compiledAllowAuthenticationPolicy) Source() interface{} {
func (c *compiledAllowAuthenticationPolicy) Source() any {
return &CELTransformationSource{Expr: c.sourceExpr, Consts: c.consts}
}
+1 -1
View File
@@ -787,7 +787,7 @@ func TestTransformer(t *testing.T) {
require.NoError(t, err)
pipeline := idtransform.NewTransformationPipeline()
expectedPipelineSource := []interface{}{}
expectedPipelineSource := []any{}
for _, transform := range tt.transforms {
compiledTransform, err := transformer.CompileTransformation(transform, tt.consts)
+3 -3
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package clientcertissuer
@@ -8,7 +8,7 @@ import (
"strings"
"time"
"k8s.io/apimachinery/pkg/util/errors"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"go.pinniped.dev/internal/constable"
)
@@ -48,7 +48,7 @@ func (c ClientCertIssuers) IssueClientCertPEM(username string, groups []string,
errs = append(errs, fmt.Errorf("%s failed to issue client cert: %w", issuer.Name(), err))
}
if err := errors.NewAggregate(errs); err != nil {
if err := utilerrors.NewAggregate(errs); err != nil {
return nil, nil, err
}
+10 -10
View File
@@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"go.pinniped.dev/internal/mocks/issuermocks"
"go.pinniped.dev/internal/mocks/mockissuer"
)
func TestName(t *testing.T) {
@@ -30,7 +30,7 @@ func TestName(t *testing.T) {
{
name: "foo issuer",
buildIssuerMocks: func() ClientCertIssuers {
fooClientCertIssuer := issuermocks.NewMockClientCertIssuer(ctrl)
fooClientCertIssuer := mockissuer.NewMockClientCertIssuer(ctrl)
fooClientCertIssuer.EXPECT().Name().Return("foo")
return ClientCertIssuers{fooClientCertIssuer}
@@ -40,10 +40,10 @@ func TestName(t *testing.T) {
{
name: "foo and bar issuers",
buildIssuerMocks: func() ClientCertIssuers {
fooClientCertIssuer := issuermocks.NewMockClientCertIssuer(ctrl)
fooClientCertIssuer := mockissuer.NewMockClientCertIssuer(ctrl)
fooClientCertIssuer.EXPECT().Name().Return("foo")
barClientCertIssuer := issuermocks.NewMockClientCertIssuer(ctrl)
barClientCertIssuer := mockissuer.NewMockClientCertIssuer(ctrl)
barClientCertIssuer.EXPECT().Name().Return("bar")
return ClientCertIssuers{fooClientCertIssuer, barClientCertIssuer}
@@ -81,7 +81,7 @@ func TestIssueClientCertPEM(t *testing.T) {
{
name: "issuers with error",
buildIssuerMocks: func() ClientCertIssuers {
errClientCertIssuer := issuermocks.NewMockClientCertIssuer(ctrl)
errClientCertIssuer := mockissuer.NewMockClientCertIssuer(ctrl)
errClientCertIssuer.EXPECT().Name().Return("error cert issuer")
errClientCertIssuer.EXPECT().
IssueClientCertPEM("username", []string{"group1", "group2"}, 32*time.Second).
@@ -93,7 +93,7 @@ func TestIssueClientCertPEM(t *testing.T) {
{
name: "valid issuer",
buildIssuerMocks: func() ClientCertIssuers {
validClientCertIssuer := issuermocks.NewMockClientCertIssuer(ctrl)
validClientCertIssuer := mockissuer.NewMockClientCertIssuer(ctrl)
validClientCertIssuer.EXPECT().
IssueClientCertPEM("username", []string{"group1", "group2"}, 32*time.Second).
Return([]byte("cert"), []byte("key"), nil)
@@ -105,13 +105,13 @@ func TestIssueClientCertPEM(t *testing.T) {
{
name: "fallthrough issuer",
buildIssuerMocks: func() ClientCertIssuers {
errClientCertIssuer := issuermocks.NewMockClientCertIssuer(ctrl)
errClientCertIssuer := mockissuer.NewMockClientCertIssuer(ctrl)
errClientCertIssuer.EXPECT().Name().Return("error cert issuer")
errClientCertIssuer.EXPECT().
IssueClientCertPEM("username", []string{"group1", "group2"}, 32*time.Second).
Return(nil, nil, errors.New("error from wrapped cert issuer"))
validClientCertIssuer := issuermocks.NewMockClientCertIssuer(ctrl)
validClientCertIssuer := mockissuer.NewMockClientCertIssuer(ctrl)
validClientCertIssuer.EXPECT().
IssueClientCertPEM("username", []string{"group1", "group2"}, 32*time.Second).
Return([]byte("cert"), []byte("key"), nil)
@@ -126,13 +126,13 @@ func TestIssueClientCertPEM(t *testing.T) {
{
name: "multiple error issuers",
buildIssuerMocks: func() ClientCertIssuers {
err1ClientCertIssuer := issuermocks.NewMockClientCertIssuer(ctrl)
err1ClientCertIssuer := mockissuer.NewMockClientCertIssuer(ctrl)
err1ClientCertIssuer.EXPECT().Name().Return("error1 cert issuer")
err1ClientCertIssuer.EXPECT().
IssueClientCertPEM("username", []string{"group1", "group2"}, 32*time.Second).
Return(nil, nil, errors.New("error1 from wrapped cert issuer"))
err2ClientCertIssuer := issuermocks.NewMockClientCertIssuer(ctrl)
err2ClientCertIssuer := mockissuer.NewMockClientCertIssuer(ctrl)
err2ClientCertIssuer.EXPECT().Name().Return("error2 cert issuer")
err2ClientCertIssuer.EXPECT().
IssueClientCertPEM("username", []string{"group1", "group2"}, 32*time.Second).
+2 -2
View File
@@ -11,7 +11,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/errors"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apiserver/pkg/registry/rest"
genericapiserver "k8s.io/apiserver/pkg/server"
@@ -105,7 +105,7 @@ func (c completedConfig) New() (*PinnipedServer, error) {
),
)
}
if err := errors.NewAggregate(errs); err != nil {
if err := utilerrors.NewAggregate(errs); err != nil {
return nil, fmt.Errorf("could not install API groups: %w", err)
}
@@ -26,7 +26,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/errors"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/httpstream"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/sets"
@@ -349,7 +349,7 @@ func newInternal(
if listener != nil {
errs = append(errs, listener.Close())
}
return nil, errors.NewAggregate(errs)
return nil, utilerrors.NewAggregate(errs)
}
return result, nil
}
@@ -21,7 +21,7 @@ import (
"github.com/stretchr/testify/require"
authenticationv1 "k8s.io/api/authentication/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme"
"k8s.io/apimachinery/pkg/runtime"
@@ -1010,7 +1010,7 @@ func TestImpersonator(t *testing.T) {
probeBody, errProbe := rc.Get().AbsPath("/probe").DoRaw(ctx)
if tt.anonymousAuthDisabled {
require.True(t, errors.IsUnauthorized(errProbe), errProbe)
require.True(t, apierrors.IsUnauthorized(errProbe), errProbe)
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(probeBody))
} else {
require.NoError(t, errProbe)
@@ -1019,7 +1019,7 @@ func TestImpersonator(t *testing.T) {
notTCRBody, errNotTCR := rc.Get().Resource("tokencredentialrequests").DoRaw(ctx)
if tt.anonymousAuthDisabled {
require.True(t, errors.IsUnauthorized(errNotTCR), errNotTCR)
require.True(t, apierrors.IsUnauthorized(errNotTCR), errNotTCR)
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(notTCRBody))
} else {
require.NoError(t, errNotTCR)
@@ -1028,7 +1028,7 @@ func TestImpersonator(t *testing.T) {
ducksBody, errDucks := rc.Get().Resource("ducks").DoRaw(ctx)
if tt.anonymousAuthDisabled {
require.True(t, errors.IsUnauthorized(errDucks), errDucks)
require.True(t, apierrors.IsUnauthorized(errDucks), errDucks)
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(ducksBody))
} else {
require.NoError(t, errDucks)
@@ -1046,7 +1046,7 @@ func TestImpersonator(t *testing.T) {
require.NoError(t, err)
_, errBadCert := tcrBadCert.PinnipedConcierge.LoginV1alpha1().TokenCredentialRequests().Create(ctx, &loginv1alpha1.TokenCredentialRequest{}, metav1.CreateOptions{})
require.True(t, errors.IsUnauthorized(errBadCert), errBadCert)
require.True(t, apierrors.IsUnauthorized(errBadCert), errBadCert)
require.EqualError(t, errBadCert, "Unauthorized")
})
}
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package scheme contains code to construct a proper runtime.Scheme for the Concierge aggregated
@@ -75,7 +75,7 @@ func New(apiGroupSuffix string) (_ *runtime.Scheme, login, identity schema.Group
// on incoming requests, restore the authenticator API group to the standard group
// note that we are responsible for duplicating this logic for every external API version
scheme.AddTypeDefaultingFunc(&loginv1alpha1.TokenCredentialRequest{}, func(obj interface{}) {
scheme.AddTypeDefaultingFunc(&loginv1alpha1.TokenCredentialRequest{}, func(obj any) {
credentialRequest := obj.(*loginv1alpha1.TokenCredentialRequest)
if credentialRequest.Spec.Authenticator.APIGroup == nil {
@@ -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 apicerts
@@ -6,7 +6,7 @@ package apicerts
import (
"fmt"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
corev1informers "k8s.io/client-go/informers/core/v1"
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
@@ -53,7 +53,7 @@ func NewAPIServiceUpdaterController(
func (c *apiServiceUpdaterController) Sync(ctx controllerlib.Context) error {
// Try to get the secret from the informer cache.
certSecret, err := c.secretInformer.Lister().Secrets(c.namespace).Get(c.certsSecretResourceName)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf("failed to get %s/%s secret: %w", c.namespace, c.certsSecretResourceName, err)
}
@@ -1,4 +1,4 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package apicerts
@@ -10,7 +10,7 @@ import (
"time"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1informers "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
@@ -74,7 +74,7 @@ func NewCertsExpirerController(
// Sync implements controller.Syncer.Sync.
func (c *certsExpirerController) Sync(ctx controllerlib.Context) error {
secret, err := c.secretInformer.Lister().Secrets(c.namespace).Get(c.certsSecretResourceName)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf("failed to get %s/%s secret: %w", c.namespace, c.certsSecretResourceName, err)
}
@@ -1,4 +1,4 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package apicerts
@@ -8,7 +8,7 @@ import (
"time"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1informers "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
@@ -83,7 +83,7 @@ func NewCertsManagerController(
func (c *certsManagerController) Sync(ctx controllerlib.Context) error {
// Try to get the secret from the informer cache.
_, err := c.secretInformer.Lister().Secrets(c.namespace).Get(c.certsSecretResourceName)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf("failed to get %s/%s secret: %w", c.namespace, c.certsSecretResourceName, err)
}
@@ -1,4 +1,4 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package apicerts
@@ -6,7 +6,7 @@ package apicerts
import (
"fmt"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
corev1informers "k8s.io/client-go/informers/core/v1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
@@ -50,7 +50,7 @@ func NewCertsObserverController(
func (c *certsObserverController) Sync(_ controllerlib.Context) error {
// Try to get the secret from the informer cache.
certSecret, err := c.secretInformer.Lister().Secrets(c.namespace).Get(c.certsSecretResourceName)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf("failed to get %s/%s secret: %w", c.namespace, c.certsSecretResourceName, err)
}
@@ -1,4 +1,4 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package authncache implements a cache of active authenticators.
@@ -65,7 +65,7 @@ func (c *Cache) Delete(key Key) {
// Keys currently stored in the cache.
func (c *Cache) Keys() []Key {
var result []Key
c.cache.Range(func(key, _ interface{}) bool {
c.cache.Range(func(key, _ any) bool {
result = append(result, key.(Key))
return true
})
@@ -17,7 +17,7 @@ import (
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
authv1alpha "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
loginapi "go.pinniped.dev/generated/latest/apis/concierge/login"
"go.pinniped.dev/internal/mocks/mocktokenauthenticator"
)
@@ -75,7 +75,7 @@ func TestAuthenticateTokenCredentialRequest(t *testing.T) {
},
Spec: loginapi.TokenCredentialRequestSpec{
Authenticator: corev1.TypedLocalObjectReference{
APIGroup: &authv1alpha.SchemeGroupVersion.Group,
APIGroup: &authenticationv1alpha1.SchemeGroupVersion.Group,
Kind: "WebhookAuthenticator",
Name: "test-name",
},
@@ -184,7 +184,7 @@ func TestAuthenticateTokenCredentialRequest(t *testing.T) {
type audienceFreeContext struct{}
func (audienceFreeContext) Matches(in interface{}) bool {
func (audienceFreeContext) Matches(in any) bool {
ctx, isCtx := in.(context.Context)
if !isCtx {
return false
@@ -1,4 +1,4 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package cachecleaner implements a controller for garbage collecting authenticators from an authenticator cache.
@@ -11,7 +11,7 @@ import (
"k8s.io/apimachinery/pkg/labels"
"k8s.io/klog/v2"
auth1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
authinformers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions/authentication/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
"go.pinniped.dev/internal/controller/authenticator"
@@ -74,7 +74,7 @@ func (c *controller) Sync(_ controllerlib.Context) error {
key := authncache.Key{
Name: webhook.Name,
Kind: "WebhookAuthenticator",
APIGroup: auth1alpha1.SchemeGroupVersion.Group,
APIGroup: authenticationv1alpha1.SchemeGroupVersion.Group,
}
authenticatorSet[key] = true
}
@@ -82,14 +82,14 @@ func (c *controller) Sync(_ controllerlib.Context) error {
key := authncache.Key{
Name: jwtAuthenticator.Name,
Kind: "JWTAuthenticator",
APIGroup: auth1alpha1.SchemeGroupVersion.Group,
APIGroup: authenticationv1alpha1.SchemeGroupVersion.Group,
}
authenticatorSet[key] = true
}
// Delete any entries from the cache which are no longer in the cluster.
for _, key := range c.cache.Keys() {
if key.APIGroup != auth1alpha1.SchemeGroupVersion.Group || (key.Kind != "WebhookAuthenticator" && key.Kind != "JWTAuthenticator") {
if key.APIGroup != authenticationv1alpha1.SchemeGroupVersion.Group || (key.Kind != "WebhookAuthenticator" && key.Kind != "JWTAuthenticator") {
continue
}
if _, exists := authenticatorSet[key]; !exists {
@@ -12,9 +12,9 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/authentication/authenticator"
authv1alpha "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
conciergefake "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
conciergeinformers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions"
controllerAuthenticator "go.pinniped.dev/internal/controller/authenticator"
"go.pinniped.dev/internal/controller/authenticator/authncache"
"go.pinniped.dev/internal/controllerlib"
@@ -65,12 +65,12 @@ func TestController(t *testing.T) {
cache.Store(testJWTAuthenticatorKey1, nil)
},
objects: []runtime.Object{
&authv1alpha.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: testWebhookKey1.Name,
},
},
&authv1alpha.JWTAuthenticator{
&authenticationv1alpha1.JWTAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: testJWTAuthenticatorKey1.Name,
},
@@ -81,22 +81,22 @@ func TestController(t *testing.T) {
{
name: "authenticators not yet added",
objects: []runtime.Object{
&authv1alpha.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: testWebhookKey1.Name,
},
},
&authv1alpha.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: testWebhookKey2.Name,
},
},
&authv1alpha.JWTAuthenticator{
&authenticationv1alpha1.JWTAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: testJWTAuthenticatorKey1.Name,
},
},
&authv1alpha.JWTAuthenticator{
&authenticationv1alpha1.JWTAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: testJWTAuthenticatorKey2.Name,
},
@@ -114,12 +114,12 @@ func TestController(t *testing.T) {
cache.Store(testKeyUnknownType, nil)
},
objects: []runtime.Object{
&authv1alpha.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: testWebhookKey1.Name,
},
},
&authv1alpha.JWTAuthenticator{
&authenticationv1alpha1.JWTAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: testJWTAuthenticatorKey1.Name,
},
@@ -136,8 +136,8 @@ func TestController(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
// When we have t.Parallel() here, this test blocks pretty consistently...y tho?
fakeClient := pinnipedfake.NewSimpleClientset(tt.objects...)
informers := pinnipedinformers.NewSharedInformerFactory(fakeClient, 0)
fakeClient := conciergefake.NewSimpleClientset(tt.objects...)
informers := conciergeinformers.NewSharedInformerFactory(fakeClient, 0)
cache := authncache.New()
if tt.initialCache != nil {
tt.initialCache(t, cache)
@@ -21,7 +21,7 @@ import (
"k8s.io/apimachinery/pkg/api/equality"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
errorsutil "k8s.io/apimachinery/pkg/util/errors"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apiserver/pkg/apis/apiserver"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/plugin/pkg/authenticator/token/oidc"
@@ -29,7 +29,7 @@ import (
"k8s.io/utils/clock"
"k8s.io/utils/ptr"
auth1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
authinformers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions/authentication/v1alpha1"
@@ -103,7 +103,7 @@ type tokenAuthenticatorCloser interface {
type cachedJWTAuthenticator struct {
authenticator.Token
spec *auth1alpha1.JWTAuthenticatorSpec
spec *authenticationv1alpha1.JWTAuthenticatorSpec
cancel context.CancelFunc
}
@@ -161,7 +161,7 @@ func (c *jwtCacheFillerController) Sync(ctx controllerlib.Context) error {
}
cacheKey := authncache.Key{
APIGroup: auth1alpha1.GroupName,
APIGroup: authenticationv1alpha1.GroupName,
Kind: "JWTAuthenticator",
Name: ctx.Key.Name,
}
@@ -229,7 +229,7 @@ func (c *jwtCacheFillerController) Sync(ctx controllerlib.Context) error {
// object. The controller simply must wait for a user to correct before running again.
// - Other errors, such as networking errors, etc. are the types of errors that should return here
// and signal the controller to retry the sync loop. These may be corrected by machines.
return errorsutil.NewAggregate(errs)
return utilerrors.NewAggregate(errs)
}
func (c *jwtCacheFillerController) extractValueAsJWTAuthenticator(value authncache.Value) *cachedJWTAuthenticator {
@@ -245,7 +245,7 @@ func (c *jwtCacheFillerController) extractValueAsJWTAuthenticator(value authncac
return jwtAuthenticator
}
func (c *jwtCacheFillerController) validateTLS(tlsSpec *auth1alpha1.TLSSpec, conditions []*metav1.Condition) (*x509.CertPool, []*metav1.Condition, bool) {
func (c *jwtCacheFillerController) validateTLS(tlsSpec *authenticationv1alpha1.TLSSpec, conditions []*metav1.Condition) (*x509.CertPool, []*metav1.Condition, bool) {
rootCAs, _, err := pinnipedcontroller.BuildCertPoolAuth(tlsSpec)
if err != nil {
msg := fmt.Sprintf("%s: %s", "invalid TLS configuration", err.Error())
@@ -504,7 +504,7 @@ func (c *jwtCacheFillerController) validateJWKSFetch(ctx context.Context, jwksUR
}
// newCachedJWTAuthenticator creates a jwt authenticator from the provided spec.
func (c *jwtCacheFillerController) newCachedJWTAuthenticator(client *http.Client, spec *auth1alpha1.JWTAuthenticatorSpec, keySet *coreosoidc.RemoteKeySet, conditions []*metav1.Condition, prereqOk bool) (*cachedJWTAuthenticator, []*metav1.Condition, error) {
func (c *jwtCacheFillerController) newCachedJWTAuthenticator(client *http.Client, spec *authenticationv1alpha1.JWTAuthenticatorSpec, keySet *coreosoidc.RemoteKeySet, conditions []*metav1.Condition, prereqOk bool) (*cachedJWTAuthenticator, []*metav1.Condition, error) {
if !prereqOk {
conditions = append(conditions, &metav1.Condition{
Type: typeAuthenticatorValid,
@@ -580,13 +580,13 @@ func (c *jwtCacheFillerController) newCachedJWTAuthenticator(client *http.Client
func (c *jwtCacheFillerController) updateStatus(
ctx context.Context,
original *auth1alpha1.JWTAuthenticator,
original *authenticationv1alpha1.JWTAuthenticator,
conditions []*metav1.Condition,
) error {
updated := original.DeepCopy()
if conditionsutil.HadErrorCondition(conditions) {
updated.Status.Phase = auth1alpha1.JWTAuthenticatorPhaseError
updated.Status.Phase = authenticationv1alpha1.JWTAuthenticatorPhaseError
conditions = append(conditions, &metav1.Condition{
Type: typeReady,
Status: metav1.ConditionFalse,
@@ -594,7 +594,7 @@ func (c *jwtCacheFillerController) updateStatus(
Message: "the JWTAuthenticator is not ready: see other conditions for details",
})
} else {
updated.Status.Phase = auth1alpha1.JWTAuthenticatorPhaseReady
updated.Status.Phase = authenticationv1alpha1.JWTAuthenticatorPhaseReady
conditions = append(conditions, &metav1.Condition{
Type: typeReady,
Status: metav1.ConditionTrue,
File diff suppressed because it is too large Load Diff
@@ -14,9 +14,9 @@ import (
k8sauthv1beta1 "k8s.io/api/authentication/v1beta1"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
errorsutil "k8s.io/apimachinery/pkg/util/errors"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
k8snetutil "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/plugin/pkg/authenticator/token/webhook"
@@ -24,7 +24,7 @@ import (
"k8s.io/klog/v2"
"k8s.io/utils/clock"
auth1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
authinformers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions/authentication/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
@@ -94,7 +94,7 @@ type webhookCacheFillerController struct {
// Sync implements controllerlib.Syncer.
func (c *webhookCacheFillerController) Sync(ctx controllerlib.Context) error {
obj, err := c.webhooks.Lister().Get(ctx.Key.Name)
if err != nil && errors.IsNotFound(err) {
if err != nil && apierrors.IsNotFound(err) {
c.log.Info("Sync() found that the WebhookAuthenticator does not exist yet or was deleted")
return nil
}
@@ -125,7 +125,7 @@ func (c *webhookCacheFillerController) Sync(ctx controllerlib.Context) error {
if !conditionsutil.HadErrorCondition(conditions) {
c.cache.Store(authncache.Key{
APIGroup: auth1alpha1.GroupName,
APIGroup: authenticationv1alpha1.GroupName,
Kind: "WebhookAuthenticator",
Name: ctx.Key.Name,
}, webhookAuthenticator)
@@ -140,7 +140,7 @@ func (c *webhookCacheFillerController) Sync(ctx controllerlib.Context) error {
// object. The controller simply must wait for a user to correct before running again.
// - other errors, such as networking errors, etc. are the types of errors that should return here
// and signal the controller to retry the sync loop. These may be corrected by machines.
return errorsutil.NewAggregate(errs)
return utilerrors.NewAggregate(errs)
}
// newWebhookAuthenticator creates a webhook from the provided API server url and caBundle
@@ -263,7 +263,7 @@ func (c *webhookCacheFillerController) validateConnection(certPool *x509.CertPoo
return conditions, nil
}
func (c *webhookCacheFillerController) validateTLSBundle(tlsSpec *auth1alpha1.TLSSpec, conditions []*metav1.Condition) (*x509.CertPool, []byte, []*metav1.Condition, bool) {
func (c *webhookCacheFillerController) validateTLSBundle(tlsSpec *authenticationv1alpha1.TLSSpec, conditions []*metav1.Condition) (*x509.CertPool, []byte, []*metav1.Condition, bool) {
rootCAs, pemBytes, err := pinnipedcontroller.BuildCertPoolAuth(tlsSpec)
if err != nil {
msg := fmt.Sprintf("%s: %s", "invalid TLS configuration", err.Error())
@@ -336,13 +336,13 @@ func (c *webhookCacheFillerController) validateEndpoint(endpoint string, conditi
func (c *webhookCacheFillerController) updateStatus(
ctx context.Context,
original *auth1alpha1.WebhookAuthenticator,
original *authenticationv1alpha1.WebhookAuthenticator,
conditions []*metav1.Condition,
) error {
updated := original.DeepCopy()
if conditionsutil.HadErrorCondition(conditions) {
updated.Status.Phase = auth1alpha1.WebhookAuthenticatorPhaseError
updated.Status.Phase = authenticationv1alpha1.WebhookAuthenticatorPhaseError
conditions = append(conditions, &metav1.Condition{
Type: typeReady,
Status: metav1.ConditionFalse,
@@ -350,7 +350,7 @@ func (c *webhookCacheFillerController) updateStatus(
Message: "the WebhookAuthenticator is not ready: see other conditions for details",
})
} else {
updated.Status.Phase = auth1alpha1.WebhookAuthenticatorPhaseReady
updated.Status.Phase = authenticationv1alpha1.WebhookAuthenticatorPhaseReady
conditions = append(conditions, &metav1.Condition{
Type: typeReady,
Status: metav1.ConditionTrue,
@@ -28,9 +28,9 @@ import (
clocktesting "k8s.io/utils/clock/testing"
"k8s.io/utils/ptr"
auth1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
conciergefake "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
conciergeinformers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions"
"go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/internal/controller/authenticator/authncache"
"go.pinniped.dev/internal/controllerlib"
@@ -139,34 +139,34 @@ func TestController(t *testing.T) {
timeInThePast := time.Date(1111, time.January, 1, 1, 1, 1, 111111, time.Local)
frozenTimeInThePast := metav1.NewTime(timeInThePast)
goodWebhookAuthenticatorSpecWithCA := auth1alpha1.WebhookAuthenticatorSpec{
goodWebhookAuthenticatorSpecWithCA := authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: goodWebhookDefaultServingCertEndpoint,
TLS: conciergetestutil.TLSSpecFromTLSConfig(hostGoodDefaultServingCertServer.TLS),
}
localWithExampleDotComWeebhookAuthenticatorSpec := auth1alpha1.WebhookAuthenticatorSpec{
localWithExampleDotComWeebhookAuthenticatorSpec := authenticationv1alpha1.WebhookAuthenticatorSpec{
// CA for example.com, TLS serving cert for example.com, but endpoint is still localhost
Endpoint: hostLocalWithExampleDotComCertServer.URL,
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
// CA Bundle for example.com
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caForExampleDotCom.Bundle()),
},
}
goodWebhookAuthenticatorSpecWithoutCA := auth1alpha1.WebhookAuthenticatorSpec{
goodWebhookAuthenticatorSpecWithoutCA := authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: goodWebhookDefaultServingCertEndpoint,
TLS: &auth1alpha1.TLSSpec{CertificateAuthorityData: ""},
TLS: &authenticationv1alpha1.TLSSpec{CertificateAuthorityData: ""},
}
goodWebhookAuthenticatorSpecWith404Endpoint := auth1alpha1.WebhookAuthenticatorSpec{
goodWebhookAuthenticatorSpecWith404Endpoint := authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: goodWebhookDefaultServingCertEndpointBut404,
TLS: conciergetestutil.TLSSpecFromTLSConfig(hostGoodDefaultServingCertServer.TLS),
}
badWebhookAuthenticatorSpecInvalidTLS := auth1alpha1.WebhookAuthenticatorSpec{
badWebhookAuthenticatorSpecInvalidTLS := authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: goodWebhookDefaultServingCertEndpoint,
TLS: &auth1alpha1.TLSSpec{CertificateAuthorityData: "invalid base64-encoded data"},
TLS: &authenticationv1alpha1.TLSSpec{CertificateAuthorityData: "invalid base64-encoded data"},
}
badWebhookAuthenticatorSpecGoodEndpointButUnknownCA := auth1alpha1.WebhookAuthenticatorSpec{
badWebhookAuthenticatorSpecGoodEndpointButUnknownCA := authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: goodWebhookDefaultServingCertEndpoint,
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(pemServerCertForUnknownServer),
},
}
@@ -363,7 +363,7 @@ func TestController(t *testing.T) {
syncKey controllerlib.Key
webhooks []runtime.Object
// for modifying the clients to hack in arbitrary api responses
configClient func(*pinnipedfake.Clientset)
configClient func(*conciergefake.Clientset)
wantSyncLoopErr testutil.RequireErrorStringFunc
wantLogs []map[string]any
wantActions func() []coretesting.Action
@@ -392,12 +392,12 @@ func TestController(t *testing.T) {
name: "Sync: valid and unchanged WebhookAuthenticator: loop will preserve existing status conditions",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: goodWebhookAuthenticatorSpecWithCA,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
Phase: "Ready",
},
@@ -410,7 +410,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -427,13 +427,13 @@ func TestController(t *testing.T) {
name: "Sync: changed WebhookAuthenticator: loop will update timestamps only on relevant statuses",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
Generation: 1234,
},
Spec: goodWebhookAuthenticatorSpecWithCA,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 1233),
[]metav1.Condition{
@@ -452,19 +452,19 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
Generation: 1234,
},
Spec: goodWebhookAuthenticatorSpecWithCA,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 1234),
[]metav1.Condition{
@@ -487,7 +487,7 @@ func TestController(t *testing.T) {
name: "Sync: valid WebhookAuthenticator with CA: will complete sync loop successfully with success conditions and ready phase",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
@@ -501,18 +501,18 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: goodWebhookAuthenticatorSpecWithCA,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
Phase: "Ready",
},
@@ -530,14 +530,14 @@ func TestController(t *testing.T) {
name: "Sync: valid WebhookAuthenticator with IPV6 and CA: will complete sync loop successfully with success conditions and ready phase",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: func() auth1alpha1.WebhookAuthenticatorSpec {
Spec: func() authenticationv1alpha1.WebhookAuthenticatorSpec {
ipv6 := goodWebhookAuthenticatorSpecWithCA.DeepCopy()
ipv6.Endpoint = hostLocalIPv6Server.URL
ipv6.TLS = ptr.To(auth1alpha1.TLSSpec{
ipv6.TLS = ptr.To(authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(ipv6CA),
})
return *ipv6
@@ -551,25 +551,25 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": hostLocalIPv6Server.URL,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: func() auth1alpha1.WebhookAuthenticatorSpec {
Spec: func() authenticationv1alpha1.WebhookAuthenticatorSpec {
ipv6 := goodWebhookAuthenticatorSpecWithCA.DeepCopy()
ipv6.Endpoint = hostLocalIPv6Server.URL
ipv6.TLS = ptr.To(auth1alpha1.TLSSpec{
ipv6.TLS = ptr.To(authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(ipv6CA),
})
return *ipv6
}(),
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: allHappyConditionsSuccess(hostLocalIPv6Server.URL, frozenMetav1Now, 0),
Phase: "Ready",
},
@@ -587,7 +587,7 @@ func TestController(t *testing.T) {
name: "Sync: valid WebhookAuthenticator without CA: loop will fail to cache the authenticator, will write failed and unknown status conditions, and will enqueue resync",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
@@ -595,12 +595,12 @@ func TestController(t *testing.T) {
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: goodWebhookAuthenticatorSpecWithoutCA,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
[]metav1.Condition{
@@ -627,7 +627,7 @@ func TestController(t *testing.T) {
name: "validateTLS: WebhookAuthenticator with invalid CA will fail sync loop and will report failed and unknown conditions and Error phase, but will not enqueue a resync due to user config error",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
@@ -635,12 +635,12 @@ func TestController(t *testing.T) {
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: badWebhookAuthenticatorSpecInvalidTLS,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
[]metav1.Condition{
@@ -666,24 +666,24 @@ func TestController(t *testing.T) {
name: "validateEndpoint: parsing error (spec.endpoint URL is invalid) will fail sync loop and will report failed and unknown conditions and Error phase, but will not enqueue a resync due to user config error",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: badEndpointInvalidURL,
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: badEndpointInvalidURL,
},
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
[]metav1.Condition{
@@ -710,24 +710,24 @@ func TestController(t *testing.T) {
name: "validateEndpoint: parsing error (spec.endpoint URL has invalid scheme, requires https) will fail sync loop, will write failed and unknown status conditions, but will not enqueue a resync due to user config error",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: badEndpointNoHTTPS,
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: badEndpointNoHTTPS,
},
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
[]metav1.Condition{
@@ -754,30 +754,30 @@ func TestController(t *testing.T) {
name: "validateEndpoint: should error if endpoint cannot be parsed",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: "https://[0:0:0:0:0:0:0:1]:69999/some/fake/path",
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caForLocalhostAs127001.Bundle()),
},
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: "https://[0:0:0:0:0:0:0:1]:69999/some/fake/path",
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caForLocalhostAs127001.Bundle()),
},
},
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess("https://[0:0:0:0:0:0:0:1]:69999/some/fake/path", frozenMetav1Now, 0),
[]metav1.Condition{
@@ -803,7 +803,7 @@ func TestController(t *testing.T) {
name: "validateConnection: CA does not validate serving certificate for host, the dialer will error, will fail sync loop, will write failed and unknown status conditions, but will not enqueue a resync due to user config error",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
@@ -812,12 +812,12 @@ func TestController(t *testing.T) {
},
wantSyncLoopErr: testutil.WantExactErrorString("cannot dial server: tls: failed to verify certificate: x509: certificate signed by unknown authority"),
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: badWebhookAuthenticatorSpecGoodEndpointButUnknownCA,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
[]metav1.Condition{
@@ -845,7 +845,7 @@ func TestController(t *testing.T) {
name: "validateConnection: 404 endpoint on a valid server will still validate server certificate, will complete sync loop successfully with success conditions and ready phase",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
@@ -859,18 +859,18 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpointBut404,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: goodWebhookAuthenticatorSpecWith404Endpoint,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpointBut404, frozenMetav1Now, 0),
Phase: "Ready",
},
@@ -888,18 +888,18 @@ func TestController(t *testing.T) {
name: "validateConnection: localhost hostname instead of 127.0.0.1 should still dial correctly as dialer should handle hostnames as well as IPv4",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: fmt.Sprintf("https://localhost:%s", localhostURL.Port()),
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
// CA Bundle for validating the server's certs
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caForLocalhostAsHostname.Bundle()),
},
},
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: allHappyConditionsSuccess(fmt.Sprintf("https://localhost:%s", localhostURL.Port()), frozenMetav1Now, 0),
Phase: "Ready",
},
@@ -912,7 +912,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": fmt.Sprintf("https://localhost:%s", localhostURL.Port()),
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -929,30 +929,30 @@ func TestController(t *testing.T) {
name: "validateConnection: IPv6 address with port: should call dialer func with correct arguments",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: "https://[0:0:0:0:0:0:0:1]:4242/some/fake/path",
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caForLocalhostAs127001.Bundle()),
},
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: "https://[0:0:0:0:0:0:0:1]:4242/some/fake/path",
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caForLocalhostAs127001.Bundle()),
},
},
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess("https://[0:0:0:0:0:0:0:1]:4242/some/fake/path", frozenMetav1Now, 0),
[]metav1.Condition{
@@ -978,30 +978,30 @@ func TestController(t *testing.T) {
name: "validateConnection: IPv6 address without port: should call dialer func with correct arguments",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: "https://[0:0:0:0:0:0:0:1]/some/fake/path",
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caForLocalhostAs127001.Bundle()),
},
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: "https://[0:0:0:0:0:0:0:1]/some/fake/path",
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caForLocalhostAs127001.Bundle()),
},
},
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess("https://[0:0:0:0:0:0:0:1]/some/fake/path", frozenMetav1Now, 0),
[]metav1.Condition{
@@ -1027,17 +1027,17 @@ func TestController(t *testing.T) {
name: "validateConnection: localhost as IP address 127.0.0.1 should still dial correctly as dialer should handle hostnames as well as IPv4 and IPv6 addresses",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: hostAs127001WebhookServer.URL,
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caForLocalhostAs127001.Bundle()),
},
},
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: allHappyConditionsSuccess(hostAs127001WebhookServer.URL, frozenMetav1Now, 0),
Phase: "Ready",
},
@@ -1050,7 +1050,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": hostAs127001WebhookServer.URL,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -1067,24 +1067,24 @@ func TestController(t *testing.T) {
name: "validateConnection: CA for example.com, serving cert for example.com, but endpoint 127.0.0.1 will fail to validate certificate and will fail sync loop and will report failed and unknown conditions and Error phase, but will not enqueue a resync due to user config error",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: localWithExampleDotComWeebhookAuthenticatorSpec,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: allHappyConditionsSuccess(hostLocalWithExampleDotComCertServer.URL, frozenMetav1Now, 0),
Phase: "Ready",
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: localWithExampleDotComWeebhookAuthenticatorSpec,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess(hostLocalWithExampleDotComCertServer.URL, frozenMetav1Now, 0),
[]metav1.Condition{
@@ -1110,30 +1110,30 @@ func TestController(t *testing.T) {
name: "validateConnection: IPv6 address without port or brackets: should succeed since IPv6 brackets are optional without port",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: "https://0:0:0:0:0:0:0:1/some/fake/path",
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caForLocalhostAs127001.Bundle()),
},
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: auth1alpha1.WebhookAuthenticatorSpec{
Spec: authenticationv1alpha1.WebhookAuthenticatorSpec{
Endpoint: "https://0:0:0:0:0:0:0:1/some/fake/path",
TLS: &auth1alpha1.TLSSpec{
TLS: &authenticationv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caForLocalhostAs127001.Bundle()),
},
},
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess("https://0:0:0:0:0:0:0:1/some/fake/path", frozenMetav1Now, 0),
[]metav1.Condition{
@@ -1159,12 +1159,12 @@ func TestController(t *testing.T) {
name: "updateStatus: called with matching original and updated conditions: will not make request to update conditions",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: goodWebhookAuthenticatorSpecWithCA,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
Phase: "Ready",
},
@@ -1177,7 +1177,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -1194,12 +1194,12 @@ func TestController(t *testing.T) {
name: "updateStatus: called with different original and updated conditions: will make request to update conditions",
syncKey: controllerlib.Key{Name: "test-name"},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: goodWebhookAuthenticatorSpecWithCA,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
[]metav1.Condition{
@@ -1217,18 +1217,18 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: goodWebhookAuthenticatorSpecWithCA,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
Phase: "Ready",
},
@@ -1245,7 +1245,7 @@ func TestController(t *testing.T) {
{
name: "updateStatus: when update request fails: error will enqueue a resync",
syncKey: controllerlib.Key{Name: "test-name"},
configClient: func(client *pinnipedfake.Clientset) {
configClient: func(client *conciergefake.Clientset) {
client.PrependReactor(
"update",
"webhookauthenticators",
@@ -1255,12 +1255,12 @@ func TestController(t *testing.T) {
)
},
webhooks: []runtime.Object{
&auth1alpha1.WebhookAuthenticator{
&authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: goodWebhookAuthenticatorSpecWithCA,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: conditionstestutil.Replace(
allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
[]metav1.Condition{
@@ -1278,18 +1278,18 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
},
wantActions: func() []coretesting.Action {
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &auth1alpha1.WebhookAuthenticator{
updateStatusAction := coretesting.NewUpdateAction(webhookAuthenticatorGVR, "", &authenticationv1alpha1.WebhookAuthenticator{
ObjectMeta: metav1.ObjectMeta{
Name: "test-name",
},
Spec: goodWebhookAuthenticatorSpecWithCA,
Status: auth1alpha1.WebhookAuthenticatorStatus{
Status: authenticationv1alpha1.WebhookAuthenticatorStatus{
Conditions: allHappyConditionsSuccess(goodWebhookDefaultServingCertEndpoint, frozenMetav1Now, 0),
Phase: "Ready",
},
@@ -1309,11 +1309,11 @@ func TestController(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
pinnipedAPIClient := pinnipedfake.NewSimpleClientset(tt.webhooks...)
pinnipedAPIClient := conciergefake.NewSimpleClientset(tt.webhooks...)
if tt.configClient != nil {
tt.configClient(pinnipedAPIClient)
}
informers := pinnipedinformers.NewSharedInformerFactory(pinnipedAPIClient, 0)
informers := conciergeinformers.NewSharedInformerFactory(pinnipedAPIClient, 0)
cache := authncache.New()
var log bytes.Buffer
@@ -19,9 +19,8 @@ import (
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/errors"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/intstr"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -33,7 +32,7 @@ import (
"k8s.io/klog/v2"
"k8s.io/utils/clock"
"go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
conciergeconfiginformers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions/config/v1alpha1"
"go.pinniped.dev/internal/certauthority"
@@ -194,9 +193,9 @@ func (c *impersonatorConfigController) Sync(syncCtx controllerlib.Context) error
strategy, err := c.doSync(syncCtx, credIssuer)
if err != nil {
strategy = &v1alpha1.CredentialIssuerStrategy{
Type: v1alpha1.ImpersonationProxyStrategyType,
Status: v1alpha1.ErrorStrategyStatus,
strategy = &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.ImpersonationProxyStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: strategyReasonForError(err),
Message: err.Error(),
LastUpdateTime: metav1.NewTime(c.clock.Now()),
@@ -219,12 +218,12 @@ func (c *impersonatorConfigController) Sync(syncCtx controllerlib.Context) error
// strategyReasonForError returns the proper v1alpha1.StrategyReason for a sync error. Some errors are occasionally
// expected because there are multiple pods running, in these cases we should report a Pending reason and we'll
// recover on a following sync.
func strategyReasonForError(err error) v1alpha1.StrategyReason {
func strategyReasonForError(err error) conciergeconfigv1alpha1.StrategyReason {
switch {
case k8serrors.IsConflict(err), k8serrors.IsAlreadyExists(err):
return v1alpha1.PendingStrategyReason
case apierrors.IsConflict(err), apierrors.IsAlreadyExists(err):
return conciergeconfigv1alpha1.PendingStrategyReason
default:
return v1alpha1.ErrorDuringSetupStrategyReason
return conciergeconfigv1alpha1.ErrorDuringSetupStrategyReason
}
}
@@ -244,7 +243,7 @@ type certNameInfo struct {
clientEndpoint string
}
func (c *impersonatorConfigController) doSync(syncCtx controllerlib.Context, credIssuer *v1alpha1.CredentialIssuer) (*v1alpha1.CredentialIssuerStrategy, error) {
func (c *impersonatorConfigController) doSync(syncCtx controllerlib.Context, credIssuer *conciergeconfigv1alpha1.CredentialIssuer) (*conciergeconfigv1alpha1.CredentialIssuerStrategy, error) {
ctx := syncCtx.Context
impersonationSpec, err := c.loadImpersonationProxyConfiguration(credIssuer)
@@ -355,7 +354,7 @@ func (c *impersonatorConfigController) ensureCAAndTLSSecrets(
func (c *impersonatorConfigController) evaluateExternallyProvidedTLSSecret(
ctx context.Context,
tlsSpec *v1alpha1.ImpersonationProxyTLSSpec,
tlsSpec *conciergeconfigv1alpha1.ImpersonationProxyTLSSpec,
) ([]byte, error) {
if tlsSpec.SecretName == "" {
return nil, fmt.Errorf("must provide impersonationSpec.TLS.secretName if impersonationSpec.TLS is provided")
@@ -397,7 +396,7 @@ func (c *impersonatorConfigController) evaluateExternallyProvidedTLSSecret(
return caBundle, nil
}
func (c *impersonatorConfigController) loadImpersonationProxyConfiguration(credIssuer *v1alpha1.CredentialIssuer) (*v1alpha1.ImpersonationProxySpec, error) {
func (c *impersonatorConfigController) loadImpersonationProxyConfiguration(credIssuer *conciergeconfigv1alpha1.CredentialIssuer) (*conciergeconfigv1alpha1.ImpersonationProxySpec, error) {
// Make a copy of the spec since we got this object from informer cache.
spec := credIssuer.Spec.DeepCopy().ImpersonationProxy
if spec == nil {
@@ -406,7 +405,7 @@ func (c *impersonatorConfigController) loadImpersonationProxyConfiguration(credI
// Default service type to LoadBalancer (this is normally already done via CRD defaulting).
if spec.Service.Type == "" {
spec.Service.Type = v1alpha1.ImpersonationProxyServiceTypeLoadBalancer
spec.Service.Type = conciergeconfigv1alpha1.ImpersonationProxyServiceTypeLoadBalancer
}
if err := validateCredentialIssuerSpec(spec); err != nil {
@@ -416,33 +415,33 @@ func (c *impersonatorConfigController) loadImpersonationProxyConfiguration(credI
return spec, nil
}
func (c *impersonatorConfigController) shouldHaveImpersonator(config *v1alpha1.ImpersonationProxySpec) bool {
return c.enabledByAutoMode(config) || config.Mode == v1alpha1.ImpersonationProxyModeEnabled
func (c *impersonatorConfigController) shouldHaveImpersonator(config *conciergeconfigv1alpha1.ImpersonationProxySpec) bool {
return c.enabledByAutoMode(config) || config.Mode == conciergeconfigv1alpha1.ImpersonationProxyModeEnabled
}
func (c *impersonatorConfigController) enabledByAutoMode(config *v1alpha1.ImpersonationProxySpec) bool {
return config.Mode == v1alpha1.ImpersonationProxyModeAuto && !*c.hasControlPlaneNodes
func (c *impersonatorConfigController) enabledByAutoMode(config *conciergeconfigv1alpha1.ImpersonationProxySpec) bool {
return config.Mode == conciergeconfigv1alpha1.ImpersonationProxyModeAuto && !*c.hasControlPlaneNodes
}
func (c *impersonatorConfigController) disabledByAutoMode(config *v1alpha1.ImpersonationProxySpec) bool {
return config.Mode == v1alpha1.ImpersonationProxyModeAuto && *c.hasControlPlaneNodes
func (c *impersonatorConfigController) disabledByAutoMode(config *conciergeconfigv1alpha1.ImpersonationProxySpec) bool {
return config.Mode == conciergeconfigv1alpha1.ImpersonationProxyModeAuto && *c.hasControlPlaneNodes
}
func (c *impersonatorConfigController) disabledExplicitly(config *v1alpha1.ImpersonationProxySpec) bool {
return config.Mode == v1alpha1.ImpersonationProxyModeDisabled
func (c *impersonatorConfigController) disabledExplicitly(config *conciergeconfigv1alpha1.ImpersonationProxySpec) bool {
return config.Mode == conciergeconfigv1alpha1.ImpersonationProxyModeDisabled
}
func (c *impersonatorConfigController) shouldHaveLoadBalancer(config *v1alpha1.ImpersonationProxySpec) bool {
return c.shouldHaveImpersonator(config) && config.Service.Type == v1alpha1.ImpersonationProxyServiceTypeLoadBalancer
func (c *impersonatorConfigController) shouldHaveLoadBalancer(config *conciergeconfigv1alpha1.ImpersonationProxySpec) bool {
return c.shouldHaveImpersonator(config) && config.Service.Type == conciergeconfigv1alpha1.ImpersonationProxyServiceTypeLoadBalancer
}
func (c *impersonatorConfigController) shouldHaveClusterIPService(config *v1alpha1.ImpersonationProxySpec) bool {
return c.shouldHaveImpersonator(config) && config.Service.Type == v1alpha1.ImpersonationProxyServiceTypeClusterIP
func (c *impersonatorConfigController) shouldHaveClusterIPService(config *conciergeconfigv1alpha1.ImpersonationProxySpec) bool {
return c.shouldHaveImpersonator(config) && config.Service.Type == conciergeconfigv1alpha1.ImpersonationProxyServiceTypeClusterIP
}
func (c *impersonatorConfigController) serviceExists(serviceName string) (bool, *corev1.Service, error) {
service, err := c.servicesInformer.Lister().Services(c.namespace).Get(serviceName)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if notFound {
return false, nil, nil
}
@@ -454,7 +453,7 @@ func (c *impersonatorConfigController) serviceExists(serviceName string) (bool,
func (c *impersonatorConfigController) tlsSecretExists() (bool, *corev1.Secret, error) {
secret, err := c.secretsInformer.Lister().Secrets(c.namespace).Get(c.tlsSecretName)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if notFound {
return false, nil, nil
}
@@ -481,7 +480,7 @@ func (c *impersonatorConfigController) ensureImpersonatorIsStarted(syncCtx contr
// and we'll have a chance to restart the server.
close(c.errorCh) // We don't want ensureImpersonatorIsStopped to block on reading this channel.
stoppingErr := c.ensureImpersonatorIsStopped(false)
return errors.NewAggregate([]error{runningErr, stoppingErr})
return utilerrors.NewAggregate([]error{runningErr, stoppingErr})
default:
// Seems like it is still running, so nothing to do.
return nil
@@ -538,7 +537,7 @@ func (c *impersonatorConfigController) ensureImpersonatorIsStopped(shouldCloseEr
return stopErr
}
func (c *impersonatorConfigController) ensureLoadBalancerIsStarted(ctx context.Context, config *v1alpha1.ImpersonationProxySpec) error {
func (c *impersonatorConfigController) ensureLoadBalancerIsStarted(ctx context.Context, config *conciergeconfigv1alpha1.ImpersonationProxySpec) error {
appNameLabel := c.labels[appLabelKey]
loadBalancer := corev1.Service{
Spec: corev1.ServiceSpec{
@@ -581,10 +580,10 @@ func (c *impersonatorConfigController) ensureLoadBalancerIsStopped(ctx context.C
ResourceVersion: &service.ResourceVersion,
},
})
return utilerrors.FilterOut(err, k8serrors.IsNotFound)
return utilerrors.FilterOut(err, apierrors.IsNotFound)
}
func (c *impersonatorConfigController) ensureClusterIPServiceIsStarted(ctx context.Context, config *v1alpha1.ImpersonationProxySpec) error {
func (c *impersonatorConfigController) ensureClusterIPServiceIsStarted(ctx context.Context, config *conciergeconfigv1alpha1.ImpersonationProxySpec) error {
appNameLabel := c.labels[appLabelKey]
clusterIP := corev1.Service{
Spec: corev1.ServiceSpec{
@@ -626,7 +625,7 @@ func (c *impersonatorConfigController) ensureClusterIPServiceIsStopped(ctx conte
ResourceVersion: &service.ResourceVersion,
},
})
return utilerrors.FilterOut(err, k8serrors.IsNotFound)
return utilerrors.FilterOut(err, apierrors.IsNotFound)
}
func (c *impersonatorConfigController) createOrUpdateService(ctx context.Context, desiredService *corev1.Service) error {
@@ -654,7 +653,7 @@ func (c *impersonatorConfigController) createOrUpdateService(ctx context.Context
// Get the Service from the informer, and create it if it does not already exist.
existingService, err := c.servicesInformer.Lister().Services(c.namespace).Get(desiredService.Name)
if k8serrors.IsNotFound(err) {
if apierrors.IsNotFound(err) {
log.Info("creating service for impersonation proxy")
_, err := c.k8sClient.CoreV1().Services(c.namespace).Create(ctx, desiredService, metav1.CreateOptions{})
return err
@@ -755,7 +754,7 @@ func (c *impersonatorConfigController) readExternalTLSSecret(externalTLSSecretNa
func (c *impersonatorConfigController) ensureTLSSecret(ctx context.Context, nameInfo *certNameInfo, ca *certauthority.CA) error {
secretFromInformer, err := c.secretsInformer.Lister().Secrets(c.namespace).Get(c.tlsSecretName)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if !notFound && err != nil {
return err
}
@@ -898,12 +897,12 @@ func (c *impersonatorConfigController) ensureTLSSecretIsCreatedAndLoaded(ctx con
func (c *impersonatorConfigController) ensureCASecretIsCreated(ctx context.Context) (*certauthority.CA, error) {
caSecret, err := c.secretsInformer.Lister().Secrets(c.namespace).Get(c.caSecretName)
if err != nil && !k8serrors.IsNotFound(err) {
if err != nil && !apierrors.IsNotFound(err) {
return nil, err
}
var impersonationCA *certauthority.CA
if k8serrors.IsNotFound(err) {
if apierrors.IsNotFound(err) {
impersonationCA, err = c.createCASecret(ctx)
} else {
crtBytes := caSecret.Data[caCrtKey]
@@ -951,16 +950,16 @@ func (c *impersonatorConfigController) createCASecret(ctx context.Context) (*cer
return impersonationCA, nil
}
func (c *impersonatorConfigController) findDesiredTLSCertificateName(config *v1alpha1.ImpersonationProxySpec) (*certNameInfo, error) {
func (c *impersonatorConfigController) findDesiredTLSCertificateName(config *conciergeconfigv1alpha1.ImpersonationProxySpec) (*certNameInfo, error) {
if config.ExternalEndpoint != "" {
return c.findTLSCertificateNameFromEndpointConfig(config), nil
} else if config.Service.Type == v1alpha1.ImpersonationProxyServiceTypeClusterIP {
} else if config.Service.Type == conciergeconfigv1alpha1.ImpersonationProxyServiceTypeClusterIP {
return c.findTLSCertificateNameFromClusterIPService()
}
return c.findTLSCertificateNameFromLoadBalancer()
}
func (c *impersonatorConfigController) findTLSCertificateNameFromEndpointConfig(config *v1alpha1.ImpersonationProxySpec) *certNameInfo {
func (c *impersonatorConfigController) findTLSCertificateNameFromEndpointConfig(config *conciergeconfigv1alpha1.ImpersonationProxySpec) *certNameInfo {
addr, _ := endpointaddr.Parse(config.ExternalEndpoint, 443)
endpoint := strings.TrimSuffix(addr.Endpoint(), ":443")
@@ -972,7 +971,7 @@ func (c *impersonatorConfigController) findTLSCertificateNameFromEndpointConfig(
func (c *impersonatorConfigController) findTLSCertificateNameFromLoadBalancer() (*certNameInfo, error) {
lb, err := c.servicesInformer.Lister().Services(c.namespace).Get(c.generatedLoadBalancerServiceName)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if notFound {
// We aren't ready and will try again later in this case.
return &certNameInfo{ready: false}, nil
@@ -1006,7 +1005,7 @@ func (c *impersonatorConfigController) findTLSCertificateNameFromLoadBalancer()
func (c *impersonatorConfigController) findTLSCertificateNameFromClusterIPService() (*certNameInfo, error) {
clusterIP, err := c.servicesInformer.Lister().Services(c.namespace).Get(c.generatedClusterIPServiceName)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if notFound {
// We aren't ready and will try again later in this case.
return &certNameInfo{ready: false}, nil
@@ -1103,7 +1102,7 @@ func (c *impersonatorConfigController) ensureTLSSecretIsRemoved(ctx context.Cont
})
// it is okay if we tried to delete and we got a not found error. This probably means
// another instance of the concierge got here first so there's nothing to delete.
return utilerrors.FilterOut(err, k8serrors.IsNotFound)
return utilerrors.FilterOut(err, apierrors.IsNotFound)
}
func (c *impersonatorConfigController) clearTLSSecret() {
@@ -1137,42 +1136,42 @@ func (c *impersonatorConfigController) clearSignerCA() {
c.impersonationSigningCertProvider.UnsetCertKeyContent()
}
func (c *impersonatorConfigController) doSyncResult(nameInfo *certNameInfo, config *v1alpha1.ImpersonationProxySpec, caBundle []byte) *v1alpha1.CredentialIssuerStrategy {
func (c *impersonatorConfigController) doSyncResult(nameInfo *certNameInfo, config *conciergeconfigv1alpha1.ImpersonationProxySpec, caBundle []byte) *conciergeconfigv1alpha1.CredentialIssuerStrategy {
switch {
case c.disabledExplicitly(config):
return &v1alpha1.CredentialIssuerStrategy{
Type: v1alpha1.ImpersonationProxyStrategyType,
Status: v1alpha1.ErrorStrategyStatus,
Reason: v1alpha1.DisabledStrategyReason,
return &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.ImpersonationProxyStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.DisabledStrategyReason,
Message: "impersonation proxy was explicitly disabled by configuration",
LastUpdateTime: metav1.NewTime(c.clock.Now()),
}
case c.disabledByAutoMode(config):
return &v1alpha1.CredentialIssuerStrategy{
Type: v1alpha1.ImpersonationProxyStrategyType,
Status: v1alpha1.ErrorStrategyStatus,
Reason: v1alpha1.DisabledStrategyReason,
return &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.ImpersonationProxyStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.DisabledStrategyReason,
Message: "automatically determined that impersonation proxy should be disabled",
LastUpdateTime: metav1.NewTime(c.clock.Now()),
}
case !nameInfo.ready:
return &v1alpha1.CredentialIssuerStrategy{
Type: v1alpha1.ImpersonationProxyStrategyType,
Status: v1alpha1.ErrorStrategyStatus,
Reason: v1alpha1.PendingStrategyReason,
return &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.ImpersonationProxyStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.PendingStrategyReason,
Message: "waiting for load balancer Service to be assigned IP or hostname",
LastUpdateTime: metav1.NewTime(c.clock.Now()),
}
default:
return &v1alpha1.CredentialIssuerStrategy{
Type: v1alpha1.ImpersonationProxyStrategyType,
Status: v1alpha1.SuccessStrategyStatus,
Reason: v1alpha1.ListeningStrategyReason,
return &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.ImpersonationProxyStrategyType,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: conciergeconfigv1alpha1.ListeningStrategyReason,
Message: "impersonation proxy is ready to accept client connections",
LastUpdateTime: metav1.NewTime(c.clock.Now()),
Frontend: &v1alpha1.CredentialIssuerFrontend{
Type: v1alpha1.ImpersonationProxyFrontendType,
ImpersonationProxyInfo: &v1alpha1.ImpersonationProxyInfo{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.ImpersonationProxyFrontendType,
ImpersonationProxyInfo: &conciergeconfigv1alpha1.ImpersonationProxyInfo{
Endpoint: "https://" + nameInfo.clientEndpoint,
CertificateAuthorityData: base64.StdEncoding.EncodeToString(caBundle),
},
@@ -1181,26 +1180,26 @@ func (c *impersonatorConfigController) doSyncResult(nameInfo *certNameInfo, conf
}
}
func validateCredentialIssuerSpec(spec *v1alpha1.ImpersonationProxySpec) error {
func validateCredentialIssuerSpec(spec *conciergeconfigv1alpha1.ImpersonationProxySpec) error {
// Validate that the mode is one of our known values.
switch spec.Mode {
case v1alpha1.ImpersonationProxyModeDisabled:
case v1alpha1.ImpersonationProxyModeAuto:
case v1alpha1.ImpersonationProxyModeEnabled:
case conciergeconfigv1alpha1.ImpersonationProxyModeDisabled:
case conciergeconfigv1alpha1.ImpersonationProxyModeAuto:
case conciergeconfigv1alpha1.ImpersonationProxyModeEnabled:
default:
return fmt.Errorf("invalid proxy mode %q (expected auto, disabled, or enabled)", spec.Mode)
}
// If disabled, ignore all other fields and consider the configuration valid.
if spec.Mode == v1alpha1.ImpersonationProxyModeDisabled {
if spec.Mode == conciergeconfigv1alpha1.ImpersonationProxyModeDisabled {
return nil
}
// Validate that the service type is one of our known values.
switch spec.Service.Type {
case v1alpha1.ImpersonationProxyServiceTypeNone:
case v1alpha1.ImpersonationProxyServiceTypeLoadBalancer:
case v1alpha1.ImpersonationProxyServiceTypeClusterIP:
case conciergeconfigv1alpha1.ImpersonationProxyServiceTypeNone:
case conciergeconfigv1alpha1.ImpersonationProxyServiceTypeLoadBalancer:
case conciergeconfigv1alpha1.ImpersonationProxyServiceTypeClusterIP:
default:
return fmt.Errorf("invalid service type %q (expected None, LoadBalancer, or ClusterIP)", spec.Service.Type)
}
@@ -1211,7 +1210,7 @@ func validateCredentialIssuerSpec(spec *v1alpha1.ImpersonationProxySpec) error {
}
// If service is type "None", a non-empty external endpoint must be specified.
if spec.ExternalEndpoint == "" && spec.Service.Type == v1alpha1.ImpersonationProxyServiceTypeNone {
if spec.ExternalEndpoint == "" && spec.Service.Type == conciergeconfigv1alpha1.ImpersonationProxyServiceTypeNone {
return fmt.Errorf("externalEndpoint must be set when service.type is None")
}
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,4 @@
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package issuerconfig contains helpers for updating CredentialIssuer status entries.
@@ -12,12 +12,12 @@ import (
apiequality "k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
"go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
)
// Update a strategy on an existing CredentialIssuer, merging into any existing strategy entries.
func Update(ctx context.Context, client versioned.Interface, issuer *v1alpha1.CredentialIssuer, strategy v1alpha1.CredentialIssuerStrategy) error {
func Update(ctx context.Context, client conciergeclientset.Interface, issuer *conciergeconfigv1alpha1.CredentialIssuer, strategy conciergeconfigv1alpha1.CredentialIssuerStrategy) error {
// Update the existing object to merge in the new strategy.
updated := issuer.DeepCopy()
mergeStrategy(&updated.Status, strategy)
@@ -33,8 +33,8 @@ func Update(ctx context.Context, client versioned.Interface, issuer *v1alpha1.Cr
return nil
}
func mergeStrategy(configToUpdate *v1alpha1.CredentialIssuerStatus, strategy v1alpha1.CredentialIssuerStrategy) {
var existing *v1alpha1.CredentialIssuerStrategy
func mergeStrategy(configToUpdate *conciergeconfigv1alpha1.CredentialIssuerStatus, strategy conciergeconfigv1alpha1.CredentialIssuerStrategy) {
var existing *conciergeconfigv1alpha1.CredentialIssuerStrategy
for i := range configToUpdate.Strategies {
if configToUpdate.Strategies[i].Type == strategy.Type {
existing = &configToUpdate.Strategies[i]
@@ -51,8 +51,8 @@ func mergeStrategy(configToUpdate *v1alpha1.CredentialIssuerStatus, strategy v1a
sort.Stable(sortableStrategies(configToUpdate.Strategies))
// Special case: the "TokenCredentialRequestAPI" data is mirrored into the deprecated status.kubeConfigInfo field.
if strategy.Frontend != nil && strategy.Frontend.Type == v1alpha1.TokenCredentialRequestAPIFrontendType {
configToUpdate.KubeConfigInfo = &v1alpha1.CredentialIssuerKubeConfigInfo{
if strategy.Frontend != nil && strategy.Frontend.Type == conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType {
configToUpdate.KubeConfigInfo = &conciergeconfigv1alpha1.CredentialIssuerKubeConfigInfo{
Server: strategy.Frontend.TokenCredentialRequestAPIInfo.Server,
CertificateAuthorityData: strategy.Frontend.TokenCredentialRequestAPIInfo.CertificateAuthorityData,
}
@@ -60,13 +60,13 @@ func mergeStrategy(configToUpdate *v1alpha1.CredentialIssuerStatus, strategy v1a
}
// weights are a set of priorities for each strategy type.
var weights = map[v1alpha1.StrategyType]int{ //nolint:gochecknoglobals
v1alpha1.KubeClusterSigningCertificateStrategyType: 2, // most preferred strategy
v1alpha1.ImpersonationProxyStrategyType: 1,
var weights = map[conciergeconfigv1alpha1.StrategyType]int{ //nolint:gochecknoglobals
conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType: 2, // most preferred strategy
conciergeconfigv1alpha1.ImpersonationProxyStrategyType: 1,
// unknown strategy types will have weight 0 by default
}
type sortableStrategies []v1alpha1.CredentialIssuerStrategy
type sortableStrategies []conciergeconfigv1alpha1.CredentialIssuerStrategy
func (s sortableStrategies) Len() int { return len(s) }
func (s sortableStrategies) Less(i, j int) bool {
@@ -77,7 +77,7 @@ func (s sortableStrategies) Less(i, j int) bool {
}
func (s sortableStrategies) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func equalExceptLastUpdated(s1, s2 *v1alpha1.CredentialIssuerStrategy) bool {
func equalExceptLastUpdated(s1, s2 *conciergeconfigv1alpha1.CredentialIssuerStrategy) bool {
s1 = s1.DeepCopy()
s2 = s2.DeepCopy()
s1.LastUpdateTime = metav1.Time{}
@@ -14,7 +14,7 @@ import (
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
)
func TestMergeStrategy(t *testing.T) {
@@ -23,27 +23,27 @@ func TestMergeStrategy(t *testing.T) {
tests := []struct {
name string
configToUpdate v1alpha1.CredentialIssuerStatus
strategy v1alpha1.CredentialIssuerStrategy
expected v1alpha1.CredentialIssuerStatus
configToUpdate conciergeconfigv1alpha1.CredentialIssuerStatus
strategy conciergeconfigv1alpha1.CredentialIssuerStrategy
expected conciergeconfigv1alpha1.CredentialIssuerStatus
}{
{
name: "new entry",
configToUpdate: v1alpha1.CredentialIssuerStatus{
configToUpdate: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: nil,
},
strategy: v1alpha1.CredentialIssuerStrategy{
strategy: conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
},
expected: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
expected: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
@@ -53,41 +53,41 @@ func TestMergeStrategy(t *testing.T) {
},
{
name: "new entry updating deprecated kubeConfigInfo",
configToUpdate: v1alpha1.CredentialIssuerStatus{
configToUpdate: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: nil,
},
strategy: v1alpha1.CredentialIssuerStrategy{
strategy: conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
Frontend: &v1alpha1.CredentialIssuerFrontend{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: "TokenCredentialRequestAPI",
TokenCredentialRequestAPIInfo: &v1alpha1.TokenCredentialRequestAPIInfo{
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
Server: "https://test-server",
CertificateAuthorityData: "test-ca-bundle",
},
},
},
expected: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
expected: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
Frontend: &v1alpha1.CredentialIssuerFrontend{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: "TokenCredentialRequestAPI",
TokenCredentialRequestAPIInfo: &v1alpha1.TokenCredentialRequestAPIInfo{
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
Server: "https://test-server",
CertificateAuthorityData: "test-ca-bundle",
},
},
},
},
KubeConfigInfo: &v1alpha1.CredentialIssuerKubeConfigInfo{
KubeConfigInfo: &conciergeconfigv1alpha1.CredentialIssuerKubeConfigInfo{
Server: "https://test-server",
CertificateAuthorityData: "test-ca-bundle",
},
@@ -95,29 +95,29 @@ func TestMergeStrategy(t *testing.T) {
},
{
name: "existing entry to update",
configToUpdate: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
configToUpdate: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.ErrorStrategyStatus,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: "some starting reason",
Message: "some starting message",
LastUpdateTime: t2,
},
},
},
strategy: v1alpha1.CredentialIssuerStrategy{
strategy: conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
},
expected: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
expected: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
@@ -127,29 +127,29 @@ func TestMergeStrategy(t *testing.T) {
},
{
name: "existing entry matches except for LastUpdated time",
configToUpdate: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
configToUpdate: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.ErrorStrategyStatus,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: "some starting reason",
Message: "some starting message",
LastUpdateTime: t1,
},
},
},
strategy: v1alpha1.CredentialIssuerStrategy{
strategy: conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: "Type1",
Status: v1alpha1.ErrorStrategyStatus,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: "some starting reason",
Message: "some starting message",
LastUpdateTime: t2,
},
expected: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
expected: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.ErrorStrategyStatus,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: "some starting reason",
Message: "some starting message",
LastUpdateTime: t1,
@@ -159,36 +159,36 @@ func TestMergeStrategy(t *testing.T) {
},
{
name: "new entry among others",
configToUpdate: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
configToUpdate: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{
{
Type: "Type0",
Status: v1alpha1.ErrorStrategyStatus,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: "some starting reason 0",
Message: "some starting message 0",
LastUpdateTime: t2,
},
{
Type: "Type2",
Status: v1alpha1.ErrorStrategyStatus,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: "some starting reason 0",
Message: "some starting message 0",
LastUpdateTime: t2,
},
},
},
strategy: v1alpha1.CredentialIssuerStrategy{
strategy: conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
},
expected: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
expected: conciergeconfigv1alpha1.CredentialIssuerStatus{
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{
{
Type: "Type0",
Status: v1alpha1.ErrorStrategyStatus,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: "some starting reason 0",
Message: "some starting message 0",
LastUpdateTime: t2,
@@ -196,14 +196,14 @@ func TestMergeStrategy(t *testing.T) {
// Expect the Type1 entry to be sorted alphanumerically between the existing entries.
{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
},
{
Type: "Type2",
Status: v1alpha1.ErrorStrategyStatus,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: "some starting reason 0",
Message: "some starting message 0",
LastUpdateTime: t2,
@@ -222,9 +222,9 @@ func TestMergeStrategy(t *testing.T) {
}
func TestStrategySorting(t *testing.T) {
expected := []v1alpha1.CredentialIssuerStrategy{
{Type: v1alpha1.KubeClusterSigningCertificateStrategyType},
{Type: v1alpha1.ImpersonationProxyStrategyType},
expected := []conciergeconfigv1alpha1.CredentialIssuerStrategy{
{Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType},
{Type: conciergeconfigv1alpha1.ImpersonationProxyStrategyType},
{Type: "Type1"},
{Type: "Type2"},
{Type: "Type3"},
@@ -233,7 +233,7 @@ func TestStrategySorting(t *testing.T) {
// Create a randomly shuffled copy of the expected output.
//nolint:gosec // this is not meant to be a secure random, just a seeded RNG for shuffling deterministically
rng := rand.New(rand.NewSource(seed))
output := make([]v1alpha1.CredentialIssuerStrategy, len(expected))
output := make([]conciergeconfigv1alpha1.CredentialIssuerStrategy, len(expected))
copy(output, expected)
rng.Shuffle(
len(output),
@@ -11,6 +11,7 @@ import (
"encoding/json"
"errors"
"fmt"
"slices"
"strings"
"time"
@@ -19,7 +20,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
@@ -32,7 +33,7 @@ import (
"k8s.io/utils/clock"
"k8s.io/utils/ptr"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
configv1alpha1informers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions/config/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
"go.pinniped.dev/internal/controller/issuerconfig"
@@ -272,7 +273,7 @@ func (c *agentController) Sync(ctx controllerlib.Context) error {
controllerManagerPods, err := c.kubeSystemPods.Lister().Pods(ControllerManagerNamespace).List(controllerManagerLabels)
if err != nil {
err := fmt.Errorf("could not list controller manager pods: %w", err)
return c.failStrategyAndErr(ctx.Context, credIssuer, err, configv1alpha1.CouldNotFetchKeyStrategyReason)
return c.failStrategyAndErr(ctx.Context, credIssuer, err, conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason)
}
newestControllerManager := newestRunningPod(controllerManagerPods)
@@ -286,7 +287,7 @@ func (c *agentController) Sync(ctx controllerlib.Context) error {
} else {
err = errors.New(msg)
}
return c.failStrategyAndErr(ctx.Context, credIssuer, err, configv1alpha1.CouldNotFetchKeyStrategyReason)
return c.failStrategyAndErr(ctx.Context, credIssuer, err, conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason)
}
depErr := c.createOrUpdateDeployment(ctx, newestControllerManager)
@@ -301,7 +302,7 @@ func (c *agentController) Sync(ctx controllerlib.Context) error {
agentPods, err := c.agentPods.Lister().Pods(c.cfg.Namespace).List(agentLabels)
if err != nil {
err := fmt.Errorf("could not list agent pods: %w", err)
return c.failStrategyAndErr(ctx.Context, credIssuer, firstErr(depErr, err), configv1alpha1.CouldNotFetchKeyStrategyReason)
return c.failStrategyAndErr(ctx.Context, credIssuer, firstErr(depErr, err), conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason)
}
newestAgentPod := newestRunningPod(agentPods)
@@ -309,42 +310,42 @@ func (c *agentController) Sync(ctx controllerlib.Context) error {
// the CredentialIssuer.
if newestAgentPod == nil {
err := fmt.Errorf("could not find a healthy agent pod (%s)", pluralize(agentPods))
return c.failStrategyAndErr(ctx.Context, credIssuer, firstErr(depErr, err), configv1alpha1.CouldNotFetchKeyStrategyReason)
return c.failStrategyAndErr(ctx.Context, credIssuer, firstErr(depErr, err), conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason)
}
// Load the Kubernetes API info from the kube-public/cluster-info ConfigMap.
configMap, err := c.kubePublicConfigMaps.Lister().ConfigMaps(ClusterInfoNamespace).Get(clusterInfoName)
if err != nil {
err := fmt.Errorf("failed to get %s/%s configmap: %w", ClusterInfoNamespace, clusterInfoName, err)
return c.failStrategyAndErr(ctx.Context, credIssuer, firstErr(depErr, err), configv1alpha1.CouldNotGetClusterInfoStrategyReason)
return c.failStrategyAndErr(ctx.Context, credIssuer, firstErr(depErr, err), conciergeconfigv1alpha1.CouldNotGetClusterInfoStrategyReason)
}
apiInfo, err := c.extractAPIInfo(configMap)
if err != nil {
err := fmt.Errorf("could not extract Kubernetes API endpoint info from %s/%s configmap: %w", ClusterInfoNamespace, clusterInfoName, err)
return c.failStrategyAndErr(ctx.Context, credIssuer, firstErr(depErr, err), configv1alpha1.CouldNotGetClusterInfoStrategyReason)
return c.failStrategyAndErr(ctx.Context, credIssuer, firstErr(depErr, err), conciergeconfigv1alpha1.CouldNotGetClusterInfoStrategyReason)
}
// Load the certificate and key from the agent pod into our in-memory signer.
if err := c.loadSigningKey(ctx.Context, newestAgentPod); err != nil {
return c.failStrategyAndErr(ctx.Context, credIssuer, firstErr(depErr, err), configv1alpha1.CouldNotFetchKeyStrategyReason)
return c.failStrategyAndErr(ctx.Context, credIssuer, firstErr(depErr, err), conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason)
}
if depErr != nil {
// if we get here, it means that we have successfully loaded a signing key but failed to reconcile the deployment.
// mark the status as failed and re-kick the sync loop until we are happy with the state of the deployment.
return c.failStrategyAndErr(ctx.Context, credIssuer, depErr, configv1alpha1.CouldNotFetchKeyStrategyReason)
return c.failStrategyAndErr(ctx.Context, credIssuer, depErr, conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason)
}
// Set the CredentialIssuer strategy to successful.
return issuerconfig.Update(ctx.Context, c.client.PinnipedConcierge, credIssuer, configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.SuccessStrategyStatus,
Reason: configv1alpha1.FetchedKeyStrategyReason,
return issuerconfig.Update(ctx.Context, c.client.PinnipedConcierge, credIssuer, conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: conciergeconfigv1alpha1.FetchedKeyStrategyReason,
Message: "key was fetched successfully",
LastUpdateTime: metav1.NewTime(c.clock.Now()),
Frontend: &configv1alpha1.CredentialIssuerFrontend{
Type: configv1alpha1.TokenCredentialRequestAPIFrontendType,
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: apiInfo,
},
})
@@ -396,7 +397,7 @@ func (c *agentController) createOrUpdateDeployment(ctx controllerlib.Context, ne
// Try to get the existing Deployment, if it exists.
existingDeployment, err := c.agentDeployments.Lister().Deployments(expectedDeployment.Namespace).Get(expectedDeployment.Name)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf("could not get deployments: %w", err)
}
@@ -454,10 +455,10 @@ func (c *agentController) createOrUpdateDeployment(ctx controllerlib.Context, ne
return err
}
func (c *agentController) failStrategyAndErr(ctx context.Context, credIssuer *configv1alpha1.CredentialIssuer, err error, reason configv1alpha1.StrategyReason) error {
updateErr := issuerconfig.Update(ctx, c.client.PinnipedConcierge, credIssuer, configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
func (c *agentController) failStrategyAndErr(ctx context.Context, credIssuer *conciergeconfigv1alpha1.CredentialIssuer, err error, reason conciergeconfigv1alpha1.StrategyReason) error {
updateErr := issuerconfig.Update(ctx, c.client.PinnipedConcierge, credIssuer, conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: reason,
Message: err.Error(),
LastUpdateTime: metav1.NewTime(c.clock.Now()),
@@ -465,7 +466,7 @@ func (c *agentController) failStrategyAndErr(ctx context.Context, credIssuer *co
return utilerrors.NewAggregate([]error{err, updateErr})
}
func (c *agentController) extractAPIInfo(configMap *corev1.ConfigMap) (*configv1alpha1.TokenCredentialRequestAPIInfo, error) {
func (c *agentController) extractAPIInfo(configMap *corev1.ConfigMap) (*conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo, error) {
kubeConfigYAML, kubeConfigPresent := configMap.Data[clusterInfoConfigMapKey]
if !kubeConfigPresent {
return nil, fmt.Errorf("missing %q key", clusterInfoConfigMapKey)
@@ -478,7 +479,7 @@ func (c *agentController) extractAPIInfo(configMap *corev1.ConfigMap) (*configv1
}
for _, v := range kubeconfig.Clusters {
result := &configv1alpha1.TokenCredentialRequestAPIInfo{
result := &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
Server: v.Server,
CertificateAuthorityData: base64.StdEncoding.EncodeToString(v.CertificateAuthorityData),
}
@@ -609,7 +610,7 @@ func getContainerArgByName(pod *corev1.Pod, name, fallbackValue string) string {
flagset.ParseErrorsWhitelist = pflag.ParseErrorsWhitelist{UnknownFlags: true}
var val string
flagset.StringVar(&val, name, "", "")
_ = flagset.Parse(append(container.Command, container.Args...))
_ = flagset.Parse(slices.Concat(container.Command, container.Args))
if val != "" {
return val
}
@@ -7,6 +7,7 @@ import (
"bytes"
"context"
"fmt"
"slices"
"testing"
"time"
@@ -15,7 +16,7 @@ import (
"go.uber.org/mock/gomock"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@@ -28,14 +29,14 @@ import (
clocktesting "k8s.io/utils/clock/testing"
"k8s.io/utils/ptr"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
conciergefake "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
conciergeinformers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions"
"go.pinniped.dev/internal/controller/kubecertagent/mocks"
"go.pinniped.dev/internal/controllerinit"
"go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/here"
"go.pinniped.dev/internal/kubeclient"
mocks "go.pinniped.dev/internal/mocks/mockkubecertagent"
"go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/testutil"
"go.pinniped.dev/test/testlib"
@@ -45,7 +46,7 @@ func TestAgentController(t *testing.T) {
t.Parallel()
now := time.Date(2021, 4, 13, 9, 57, 0, 0, time.UTC)
initialCredentialIssuer := &configv1alpha1.CredentialIssuer{
initialCredentialIssuer := &conciergeconfigv1alpha1.CredentialIssuer{
ObjectMeta: metav1.ObjectMeta{Name: "pinniped-concierge-config"},
}
@@ -247,7 +248,7 @@ func TestAgentController(t *testing.T) {
wantAgentDeployment *appsv1.Deployment
wantDeploymentActionVerbs []string
wantDeploymentDeleteActionOpts []metav1.DeleteOptions
wantStrategy *configv1alpha1.CredentialIssuerStrategy
wantStrategy *conciergeconfigv1alpha1.CredentialIssuerStrategy
}{
{
name: "no CredentialIssuer found",
@@ -273,10 +274,10 @@ func TestAgentController(t *testing.T) {
"could not find a healthy kube-controller-manager pod (0 candidates): " +
"note that this error is the expected behavior for some cluster types, including most cloud provider clusters (e.g. GKE, AKS, EKS)",
},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "could not find a healthy kube-controller-manager pod (0 candidates): " +
"note that this error is the expected behavior for some cluster types, including most cloud provider clusters (e.g. GKE, AKS, EKS)",
LastUpdateTime: metav1.NewTime(now),
@@ -317,10 +318,10 @@ func TestAgentController(t *testing.T) {
wantDistinctErrors: []string{
"could not find a healthy kube-controller-manager pod (2 candidates)",
},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "could not find a healthy kube-controller-manager pod (2 candidates)",
LastUpdateTime: metav1.NewTime(now),
},
@@ -344,10 +345,10 @@ func TestAgentController(t *testing.T) {
wantDistinctLogs: []string{
`{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","logger":"kube-cert-agent-controller","caller":"kubecertagent/kubecertagent.go:<line>$kubecertagent.(*agentController).createOrUpdateDeployment","message":"creating new deployment","deployment":{"name":"pinniped-concierge-kube-cert-agent","namespace":"concierge"},"templatePod":{"name":"kube-controller-manager-1","namespace":"kube-system"}}`,
},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "could not ensure agent deployment: some creation error",
LastUpdateTime: metav1.NewTime(now),
},
@@ -393,10 +394,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeployment,
wantDeploymentActionVerbs: []string{"list", "watch", "create"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "could not find a healthy agent pod (1 candidate)",
LastUpdateTime: metav1.NewTime(now),
},
@@ -442,10 +443,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeploymentWithDefaultedPaths,
wantDeploymentActionVerbs: []string{"list", "watch", "create"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "could not find a healthy agent pod (1 candidate)",
LastUpdateTime: metav1.NewTime(now),
},
@@ -472,10 +473,10 @@ func TestAgentController(t *testing.T) {
wantDeploymentDeleteActionOpts: []metav1.DeleteOptions{
testutil.NewPreconditions(healthyAgentDeploymentWithOldStyleSelector.UID, healthyAgentDeploymentWithOldStyleSelector.ResourceVersion),
},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "could not find a healthy agent pod (1 candidate)",
LastUpdateTime: metav1.NewTime(now),
},
@@ -508,10 +509,10 @@ func TestAgentController(t *testing.T) {
testutil.NewPreconditions(healthyAgentDeploymentWithOldStyleSelector.UID, healthyAgentDeploymentWithOldStyleSelector.ResourceVersion),
testutil.NewPreconditions(healthyAgentDeploymentWithOldStyleSelector.UID, healthyAgentDeploymentWithOldStyleSelector.ResourceVersion),
},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "could not ensure agent deployment: some delete error",
LastUpdateTime: metav1.NewTime(now),
},
@@ -545,10 +546,10 @@ func TestAgentController(t *testing.T) {
wantDeploymentDeleteActionOpts: []metav1.DeleteOptions{
testutil.NewPreconditions(healthyAgentDeploymentWithOldStyleSelector.UID, healthyAgentDeploymentWithOldStyleSelector.ResourceVersion),
},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "could not ensure agent deployment: some create error",
LastUpdateTime: metav1.NewTime(now),
},
@@ -591,10 +592,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeploymentWithExtraLabels,
wantDeploymentActionVerbs: []string{"list", "watch", "update"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "could not find a healthy agent pod (1 candidate)",
LastUpdateTime: metav1.NewTime(now),
},
@@ -614,10 +615,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeploymentWithHostNetwork,
wantDeploymentActionVerbs: []string{"list", "watch", "update"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotGetClusterInfoStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotGetClusterInfoStrategyReason,
Message: "failed to get kube-public/cluster-info configmap: configmap \"cluster-info\" not found",
LastUpdateTime: metav1.NewTime(now),
},
@@ -640,10 +641,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeployment,
wantDeploymentActionVerbs: []string{"list", "watch"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotGetClusterInfoStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotGetClusterInfoStrategyReason,
Message: "failed to get kube-public/cluster-info configmap: configmap \"cluster-info\" not found",
LastUpdateTime: metav1.NewTime(now),
},
@@ -667,10 +668,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeployment,
wantDeploymentActionVerbs: []string{"list", "watch"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotGetClusterInfoStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotGetClusterInfoStrategyReason,
Message: "could not extract Kubernetes API endpoint info from kube-public/cluster-info configmap: missing \"kubeconfig\" key",
LastUpdateTime: metav1.NewTime(now),
},
@@ -694,10 +695,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeployment,
wantDeploymentActionVerbs: []string{"list", "watch"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotGetClusterInfoStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotGetClusterInfoStrategyReason,
Message: "could not extract Kubernetes API endpoint info from kube-public/cluster-info configmap: key \"kubeconfig\" does not contain a valid kubeconfig",
LastUpdateTime: metav1.NewTime(now),
},
@@ -721,10 +722,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeployment,
wantDeploymentActionVerbs: []string{"list", "watch"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotGetClusterInfoStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotGetClusterInfoStrategyReason,
Message: "could not extract Kubernetes API endpoint info from kube-public/cluster-info configmap: kubeconfig in key \"kubeconfig\" does not contain any clusters",
LastUpdateTime: metav1.NewTime(now),
},
@@ -750,10 +751,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeployment,
wantDeploymentActionVerbs: []string{"list", "watch"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "could not exec into agent pod concierge/pinniped-concierge-kube-cert-agent-xyz-1234: some exec error",
LastUpdateTime: metav1.NewTime(now),
},
@@ -779,10 +780,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeployment,
wantDeploymentActionVerbs: []string{"list", "watch"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: `failed to decode signing cert/key JSON from agent pod concierge/pinniped-concierge-kube-cert-agent-xyz-1234: invalid character 'b' looking for beginning of value`,
LastUpdateTime: metav1.NewTime(now),
},
@@ -808,10 +809,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeployment,
wantDeploymentActionVerbs: []string{"list", "watch"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: `failed to decode signing cert base64 from agent pod concierge/pinniped-concierge-kube-cert-agent-xyz-1234: illegal base64 data at input byte 4`,
LastUpdateTime: metav1.NewTime(now),
},
@@ -837,10 +838,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeployment,
wantDeploymentActionVerbs: []string{"list", "watch"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: `failed to decode signing key base64 from agent pod concierge/pinniped-concierge-kube-cert-agent-xyz-1234: illegal base64 data at input byte 4`,
LastUpdateTime: metav1.NewTime(now),
},
@@ -869,10 +870,10 @@ func TestAgentController(t *testing.T) {
},
wantAgentDeployment: healthyAgentDeployment,
wantDeploymentActionVerbs: []string{"list", "watch"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "failed to set signing cert/key content from agent pod concierge/pinniped-concierge-kube-cert-agent-xyz-1234: some dynamic cert error",
LastUpdateTime: metav1.NewTime(now),
},
@@ -895,15 +896,15 @@ func TestAgentController(t *testing.T) {
wantDistinctErrors: []string{""},
wantAgentDeployment: healthyAgentDeployment,
wantDeploymentActionVerbs: []string{"list", "watch"},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.SuccessStrategyStatus,
Reason: configv1alpha1.FetchedKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: conciergeconfigv1alpha1.FetchedKeyStrategyReason,
Message: "key was fetched successfully",
LastUpdateTime: metav1.NewTime(now),
Frontend: &configv1alpha1.CredentialIssuerFrontend{
Type: configv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &configv1alpha1.TokenCredentialRequestAPIInfo{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
Server: "https://test-kubernetes-endpoint.example.com",
CertificateAuthorityData: "dGVzdC1rdWJlcm5ldGVzLWNh",
},
@@ -941,10 +942,10 @@ func TestAgentController(t *testing.T) {
testutil.NewPreconditions(healthyAgentDeploymentWithOldStyleSelector.UID, healthyAgentDeploymentWithOldStyleSelector.ResourceVersion),
testutil.NewPreconditions(healthyAgentDeploymentWithOldStyleSelector.UID, healthyAgentDeploymentWithOldStyleSelector.ResourceVersion),
},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.ErrorStrategyStatus,
Reason: configv1alpha1.CouldNotFetchKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.ErrorStrategyStatus,
Reason: conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason,
Message: "could not ensure agent deployment: some delete error",
LastUpdateTime: metav1.NewTime(now),
},
@@ -967,15 +968,15 @@ func TestAgentController(t *testing.T) {
wantDistinctLogs: []string{
`{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","logger":"kube-cert-agent-controller","caller":"kubecertagent/kubecertagent.go:<line>$kubecertagent.(*agentController).loadSigningKey","message":"successfully loaded signing key from agent pod into cache"}`,
},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.SuccessStrategyStatus,
Reason: configv1alpha1.FetchedKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: conciergeconfigv1alpha1.FetchedKeyStrategyReason,
Message: "key was fetched successfully",
LastUpdateTime: metav1.NewTime(now),
Frontend: &configv1alpha1.CredentialIssuerFrontend{
Type: configv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &configv1alpha1.TokenCredentialRequestAPIInfo{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
Server: "https://test-kubernetes-endpoint.example.com",
CertificateAuthorityData: "dGVzdC1rdWJlcm5ldGVzLWNh",
},
@@ -1001,15 +1002,15 @@ func TestAgentController(t *testing.T) {
wantDistinctLogs: []string{
`{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","logger":"kube-cert-agent-controller","caller":"kubecertagent/kubecertagent.go:<line>$kubecertagent.(*agentController).loadSigningKey","message":"successfully loaded signing key from agent pod into cache"}`,
},
wantStrategy: &configv1alpha1.CredentialIssuerStrategy{
Type: configv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: configv1alpha1.SuccessStrategyStatus,
Reason: configv1alpha1.FetchedKeyStrategyReason,
wantStrategy: &conciergeconfigv1alpha1.CredentialIssuerStrategy{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: conciergeconfigv1alpha1.FetchedKeyStrategyReason,
Message: "key was fetched successfully",
LastUpdateTime: metav1.NewTime(now),
Frontend: &configv1alpha1.CredentialIssuerFrontend{
Type: configv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &configv1alpha1.TokenCredentialRequestAPIInfo{
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
Server: "https://overridden-server.example.com/some/path",
CertificateAuthorityData: "dGVzdC1rdWJlcm5ldGVzLWNh",
},
@@ -1081,8 +1082,7 @@ func TestAgentController(t *testing.T) {
actualErrors := deduplicate(errorMessages)
assert.Subsetf(t, actualErrors, tt.wantDistinctErrors, "required error(s) were not found in the actual errors")
allAllowedErrors := append([]string{}, tt.wantDistinctErrors...)
allAllowedErrors = append(allAllowedErrors, tt.alsoAllowUndesiredDistinctErrors...)
allAllowedErrors := slices.Concat(tt.wantDistinctErrors, tt.alsoAllowUndesiredDistinctErrors)
assert.Subsetf(t, allAllowedErrors, actualErrors, "actual errors contained additional error(s) which is not expected by the test")
assert.Equal(t, tt.wantDistinctLogs, deduplicate(testutil.SplitByNewline(buf.String())), "unexpected logs")
@@ -1267,7 +1267,7 @@ func hasDeploymentSynced(client kubernetes.Interface, kubeInformers informers.Sh
cachedDep, cachedErr := kubeInformers.Apps().V1().Deployments().Lister().Deployments("concierge").
Get("pinniped-concierge-kube-cert-agent")
if errors.IsNotFound(realErr) && errors.IsNotFound(cachedErr) {
if apierrors.IsNotFound(realErr) && apierrors.IsNotFound(cachedErr) {
return
}
@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package kubecertagent
@@ -7,7 +7,7 @@ import (
"fmt"
"github.com/go-logr/logr"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
corev1informers "k8s.io/client-go/informers/core/v1"
@@ -44,7 +44,7 @@ func NewLegacyPodCleanerController(
// avoid blind writes to the API
agentPod, err := podClient.Get(ctx.Context, ctx.Key.Name, metav1.GetOptions{})
if err != nil {
if k8serrors.IsNotFound(err) {
if apierrors.IsNotFound(err) {
return nil
}
return fmt.Errorf("could not get legacy agent pod: %w", err)
@@ -56,7 +56,7 @@ func NewLegacyPodCleanerController(
ResourceVersion: &agentPod.ResourceVersion,
},
}); err != nil {
if k8serrors.IsNotFound(err) {
if apierrors.IsNotFound(err) {
return nil
}
return fmt.Errorf("could not delete legacy agent pod: %w", err)
@@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/informers"
@@ -111,7 +111,7 @@ func TestLegacyPodCleanerController(t *testing.T) {
},
addKubeReactions: func(clientset *kubefake.Clientset) {
clientset.PrependReactor("delete", "*", func(action coretesting.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, k8serrors.NewNotFound(action.GetResource().GroupResource(), "")
return true, nil, apierrors.NewNotFound(action.GetResource().GroupResource(), "")
})
},
wantDistinctErrors: []string{""},
@@ -129,7 +129,7 @@ func TestLegacyPodCleanerController(t *testing.T) {
},
addKubeReactions: func(clientset *kubefake.Clientset) {
clientset.PrependReactor("get", "*", func(action coretesting.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, k8serrors.NewNotFound(action.GetResource().GroupResource(), "")
return true, nil, apierrors.NewNotFound(action.GetResource().GroupResource(), "")
})
},
wantDistinctErrors: []string{""},
@@ -9,7 +9,7 @@ import (
"testing"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/client-go/rest"
"go.pinniped.dev/internal/crypto/ptls"
@@ -38,7 +38,7 @@ func TestSecureTLS(t *testing.T) {
podCommandExecutor := NewPodCommandExecutor(client.JSONConfig, client.Kubernetes)
got, err := podCommandExecutor.Exec(context.Background(), "podNamespace", "podName", "containerName", "command", "arg1", "arg2")
require.Equal(t, &errors.StatusError{}, err)
require.Equal(t, &apierrors.StatusError{}, err)
require.Empty(t, got)
require.True(t, sawRequest)
@@ -19,7 +19,7 @@ import (
"k8s.io/apimachinery/pkg/labels"
corev1informers "k8s.io/client-go/informers/core/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
idpinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
@@ -74,7 +74,7 @@ const (
)
type activeDirectoryUpstreamGenericLDAPImpl struct {
activeDirectoryIdentityProvider v1alpha1.ActiveDirectoryIdentityProvider
activeDirectoryIdentityProvider idpv1alpha1.ActiveDirectoryIdentityProvider
}
func (g *activeDirectoryUpstreamGenericLDAPImpl) Spec() upstreamwatchers.UpstreamGenericLDAPSpec {
@@ -98,14 +98,14 @@ func (g *activeDirectoryUpstreamGenericLDAPImpl) Status() upstreamwatchers.Upstr
}
type activeDirectoryUpstreamGenericLDAPSpec struct {
activeDirectoryIdentityProvider v1alpha1.ActiveDirectoryIdentityProvider
activeDirectoryIdentityProvider idpv1alpha1.ActiveDirectoryIdentityProvider
}
func (s *activeDirectoryUpstreamGenericLDAPSpec) Host() string {
return s.activeDirectoryIdentityProvider.Spec.Host
}
func (s *activeDirectoryUpstreamGenericLDAPSpec) TLSSpec() *v1alpha1.TLSSpec {
func (s *activeDirectoryUpstreamGenericLDAPSpec) TLSSpec() *idpv1alpha1.TLSSpec {
return s.activeDirectoryIdentityProvider.Spec.TLS
}
@@ -161,7 +161,7 @@ func (s *activeDirectoryUpstreamGenericLDAPSpec) DetectAndSetSearchBase(ctx cont
}
type activeDirectoryUpstreamGenericLDAPUserSearch struct {
userSearch v1alpha1.ActiveDirectoryIdentityProviderUserSearch
userSearch idpv1alpha1.ActiveDirectoryIdentityProviderUserSearch
}
func (u *activeDirectoryUpstreamGenericLDAPUserSearch) Base() string {
@@ -190,7 +190,7 @@ func (u *activeDirectoryUpstreamGenericLDAPUserSearch) UIDAttribute() string {
}
type activeDirectoryUpstreamGenericLDAPGroupSearch struct {
groupSearch v1alpha1.ActiveDirectoryIdentityProviderGroupSearch
groupSearch idpv1alpha1.ActiveDirectoryIdentityProviderGroupSearch
}
func (g *activeDirectoryUpstreamGenericLDAPGroupSearch) Base() string {
@@ -216,7 +216,7 @@ func (g *activeDirectoryUpstreamGenericLDAPGroupSearch) GroupNameAttribute() str
}
type activeDirectoryUpstreamGenericLDAPStatus struct {
activeDirectoryIdentityProvider v1alpha1.ActiveDirectoryIdentityProvider
activeDirectoryIdentityProvider idpv1alpha1.ActiveDirectoryIdentityProvider
}
func (s *activeDirectoryUpstreamGenericLDAPStatus) Conditions() []metav1.Condition {
@@ -318,7 +318,7 @@ func (c *activeDirectoryWatcherController) Sync(ctx controllerlib.Context) error
return nil
}
func (c *activeDirectoryWatcherController) validateUpstream(ctx context.Context, upstream *v1alpha1.ActiveDirectoryIdentityProvider) (p upstreamprovider.UpstreamLDAPIdentityProviderI, requeue bool) {
func (c *activeDirectoryWatcherController) validateUpstream(ctx context.Context, upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) (p upstreamprovider.UpstreamLDAPIdentityProviderI, requeue bool) {
spec := upstream.Spec
adUpstreamImpl := &activeDirectoryUpstreamGenericLDAPImpl{activeDirectoryIdentityProvider: *upstream}
@@ -364,15 +364,15 @@ func (c *activeDirectoryWatcherController) validateUpstream(ctx context.Context,
return upstreamwatchers.EvaluateConditions(conditions, config)
}
func (c *activeDirectoryWatcherController) updateStatus(ctx context.Context, upstream *v1alpha1.ActiveDirectoryIdentityProvider, conditions []*metav1.Condition) {
func (c *activeDirectoryWatcherController) updateStatus(ctx context.Context, upstream *idpv1alpha1.ActiveDirectoryIdentityProvider, conditions []*metav1.Condition) {
log := plog.WithValues("namespace", upstream.Namespace, "name", upstream.Name)
updated := upstream.DeepCopy()
hadErrorCondition := conditionsutil.MergeConditions(conditions, upstream.Generation, &updated.Status.Conditions, log, metav1.Now())
updated.Status.Phase = v1alpha1.ActiveDirectoryPhaseReady
updated.Status.Phase = idpv1alpha1.ActiveDirectoryPhaseReady
if hadErrorCondition {
updated.Status.Phase = v1alpha1.ActiveDirectoryPhaseError
updated.Status.Phase = idpv1alpha1.ActiveDirectoryPhaseError
}
if equality.Semantic.DeepEqual(upstream, updated) {
@@ -22,9 +22,9 @@ import (
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
supervisorinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers"
"go.pinniped.dev/internal/controllerlib"
@@ -74,8 +74,8 @@ func TestActiveDirectoryUpstreamWatcherControllerFilterSecrets(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
fakePinnipedClient := pinnipedfake.NewSimpleClientset()
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakePinnipedClient := supervisorfake.NewSimpleClientset()
pinnipedInformers := supervisorinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
activeDirectoryIDPInformer := pinnipedInformers.IDP().V1alpha1().ActiveDirectoryIdentityProviders()
fakeKubeClient := fake.NewSimpleClientset()
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
@@ -106,7 +106,7 @@ func TestActiveDirectoryUpstreamWatcherControllerFilterActiveDirectoryIdentityPr
}{
{
name: "any ActiveDirectoryIdentityProvider",
idp: &v1alpha1.ActiveDirectoryIdentityProvider{
idp: &idpv1alpha1.ActiveDirectoryIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Name: "some-name", Namespace: "some-namespace"},
},
wantAdd: true,
@@ -118,8 +118,8 @@ func TestActiveDirectoryUpstreamWatcherControllerFilterActiveDirectoryIdentityPr
t.Run(test.name, func(t *testing.T) {
t.Parallel()
fakePinnipedClient := pinnipedfake.NewSimpleClientset()
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakePinnipedClient := supervisorfake.NewSimpleClientset()
pinnipedInformers := supervisorinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
activeDirectoryIDPInformer := pinnipedInformers.IDP().V1alpha1().ActiveDirectoryIdentityProviders()
fakeKubeClient := fake.NewSimpleClientset()
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
@@ -176,32 +176,32 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
testCABundle := testCA.Bundle()
testCABundleBase64Encoded := base64.StdEncoding.EncodeToString(testCABundle)
validUpstream := &v1alpha1.ActiveDirectoryIdentityProvider{
validUpstream := &idpv1alpha1.ActiveDirectoryIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Name: testName, Namespace: testNamespace, Generation: 1234, UID: testResourceUID},
Spec: v1alpha1.ActiveDirectoryIdentityProviderSpec{
Spec: idpv1alpha1.ActiveDirectoryIdentityProviderSpec{
Host: testHost,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testCABundleBase64Encoded},
Bind: v1alpha1.ActiveDirectoryIdentityProviderBind{SecretName: testBindSecretName},
UserSearch: v1alpha1.ActiveDirectoryIdentityProviderUserSearch{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testCABundleBase64Encoded},
Bind: idpv1alpha1.ActiveDirectoryIdentityProviderBind{SecretName: testBindSecretName},
UserSearch: idpv1alpha1.ActiveDirectoryIdentityProviderUserSearch{
Base: testUserSearchBase,
Filter: testUserSearchFilter,
Attributes: v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{
Attributes: idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{
Username: testUserSearchUsernameAttrName,
UID: testUserSearchUIDAttrName,
},
},
GroupSearch: v1alpha1.ActiveDirectoryIdentityProviderGroupSearch{
GroupSearch: idpv1alpha1.ActiveDirectoryIdentityProviderGroupSearch{
Base: testGroupSearchBase,
Filter: testGroupSearchFilter,
UserAttributeForFilter: testGroupSearchUserAttributeForFilter,
Attributes: v1alpha1.ActiveDirectoryIdentityProviderGroupSearchAttributes{
Attributes: idpv1alpha1.ActiveDirectoryIdentityProviderGroupSearchAttributes{
GroupName: testGroupSearchNameAttrName,
},
SkipGroupRefresh: false,
},
},
}
editedValidUpstream := func(editFunc func(*v1alpha1.ActiveDirectoryIdentityProvider)) *v1alpha1.ActiveDirectoryIdentityProvider {
editedValidUpstream := func(editFunc func(*idpv1alpha1.ActiveDirectoryIdentityProvider)) *idpv1alpha1.ActiveDirectoryIdentityProvider {
deepCopy := validUpstream.DeepCopy()
editFunc(deepCopy)
return deepCopy
@@ -373,7 +373,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
dialErrors map[string]error
wantErr string
wantResultingCache []*upstreamldap.ProviderConfig
wantResultingUpstreams []v1alpha1.ActiveDirectoryIdentityProvider
wantResultingUpstreams []idpv1alpha1.ActiveDirectoryIdentityProvider
wantValidatedSettings map[string]upstreamwatchers.ValidatedSettings
}{
{
@@ -390,9 +390,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -413,9 +413,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
inputSecrets: []runtime.Object{},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -441,9 +441,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
}},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -468,9 +468,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
}},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -488,15 +488,15 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "CertificateAuthorityData is not base64 encoded",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = "this-is-not-base64-encoded"
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -514,15 +514,15 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "CertificateAuthorityData is not valid pem data",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = base64.StdEncoding.EncodeToString([]byte("this is not pem data"))
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -540,7 +540,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "nil TLS configuration is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.TLS = nil
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -578,9 +578,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -609,7 +609,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "sAMAccountName explicitly provided as group name attribute does not add an override",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.TLS = nil
upstream.Spec.GroupSearch.Attributes.GroupName = "sAMAccountName"
})},
@@ -648,9 +648,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -679,7 +679,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when TLS connection fails it tries to use StartTLS instead: without a specified port it automatically switches ports",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.Host = "ldap.example.com" // when the port is not specified, automatically switch ports for StartTLS
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -721,9 +721,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -761,7 +761,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when TLS connection fails it tries to use StartTLS instead: with a specified port it does not automatically switch ports",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.Host = "ldap.example.com:5678" // when the port is specified, do not automatically switch ports for StartTLS
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -802,9 +802,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -827,7 +827,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "non-nil TLS configuration with empty CertificateAuthorityData is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -865,9 +865,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -884,7 +884,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "one valid upstream and one invalid upstream updates the cache to include only the valid upstream",
inputUpstreams: []runtime.Object{validUpstream, editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{validUpstream, editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Name = "other-upstream"
upstream.Generation = 42
upstream.Spec.Bind.SecretName = "non-existent-secret"
@@ -898,10 +898,10 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "other-upstream", Generation: 42, UID: "other-uid"},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -918,7 +918,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -948,9 +948,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -973,8 +973,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when testing the connection to the LDAP server fails, but later querying defaultsearchbase succeeds, then the upstream is still added to the cache anyway (treated like a warning)",
// Add to cache but not to validatedSettings so we recheck next time
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
// Add to cache, but not to validatedSettings, so we recheck next time
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
@@ -1016,9 +1016,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1041,7 +1041,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when testing the connection to the LDAP server fails, and querying defaultsearchbase fails, then the upstream is not added to the cache",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
@@ -1052,9 +1052,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(3)
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1077,7 +1077,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated using TLS for the current resource generation and secret version, then do not validate it again and keep using TLS",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4242"),
@@ -1098,9 +1098,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1119,7 +1119,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
name: "when the validated cache contains LDAP server info but the search base is empty, reload everything",
// this is an invalid state that shouldn't happen now, but if it does we should consider the whole
// validatedsettings cache invalid.
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4242"),
@@ -1165,9 +1165,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
"msDS-User-Account-Control-Computed": validComputedUserAccountControl,
}},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1189,7 +1189,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated using TLS, and the search base was found, load TLS and search base info into the cache",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4242"),
@@ -1238,9 +1238,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1262,7 +1262,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated using StartTLS for the current resource generation and secret version, then do not validate it again and keep using StartTLS",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4242"),
@@ -1283,9 +1283,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithStartTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1302,7 +1302,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was validated for an older resource generation, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234 // current generation
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1233, "4242"), // older spec generation!
@@ -1324,9 +1324,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1343,7 +1343,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection condition failed to update previously, then write the cached condition from the previous connection validation",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234 // current generation
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4200"), // old version of the condition, as if the previous update of conditions had failed
@@ -1364,9 +1364,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"), // updated version of the condition using the cached condition value
},
@@ -1383,7 +1383,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection validation previously failed for this resource generation, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
{
@@ -1403,9 +1403,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1422,7 +1422,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated for this resource generation but the bind secret has changed, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4241"), // same spec generation, old secret version
@@ -1444,9 +1444,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1463,11 +1463,11 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the input activedirectoryidentityprovider leaves user attributes blank, provide default values",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.UserSearch.Filter = ""
upstream.Spec.GroupSearch.Filter = ""
upstream.Spec.GroupSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderGroupSearchAttributes{}
upstream.Spec.GroupSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderGroupSearchAttributes{}
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
setupMocks: func(conn *mockldapconn.MockConn) {
@@ -1505,9 +1505,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1524,8 +1524,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the input activedirectoryidentityprovider leaves user and group search base blank, query for defaultNamingContext",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.UserSearch.Base = ""
upstream.Spec.GroupSearch.Base = ""
})},
@@ -1565,9 +1565,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1589,8 +1589,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the input activedirectoryidentityprovider leaves user search base blank but provides group search base, query for defaultNamingContext",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.UserSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1629,9 +1629,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1653,8 +1653,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the input activedirectoryidentityprovider leaves group search base blank but provides user search base, query for defaultNamingContext",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1693,9 +1693,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1717,8 +1717,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the input activedirectoryidentityprovider leaves group search base blank and query for defaultNamingContext fails",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1729,9 +1729,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Search(expectedDefaultNamingContextSearch()).Return(nil, errors.New("some error")).Times(1)
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1745,8 +1745,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when query for defaultNamingContext returns empty string",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1765,9 +1765,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
}}, nil).Times(1)
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1781,8 +1781,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when query for defaultNamingContext returns multiple entries",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1807,9 +1807,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
}}, nil).Times(1)
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1823,8 +1823,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when query for defaultNamingContext returns no entries",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1836,9 +1836,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
Entries: []*ldap.Entry{}}, nil).Times(1)
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1852,12 +1852,12 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when search base was previously found but the bind secret has changed",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
searchBaseFoundInRootDSECondition(1234),
}
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1905,9 +1905,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1929,7 +1929,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "skipping group refresh is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.GroupSearch.SkipGroupRefresh = true
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1968,9 +1968,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -2003,8 +2003,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
fakePinnipedClient := pinnipedfake.NewSimpleClientset(tt.inputUpstreams...)
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakePinnipedClient := supervisorfake.NewSimpleClientset(tt.inputUpstreams...)
pinnipedInformers := supervisorinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakeKubeClient := fake.NewSimpleClientset(tt.inputSecrets...)
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
cache := dynamicupstreamprovider.NewDynamicUpstreamIDPProvider()
@@ -2133,13 +2133,13 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
}
}
func normalizeActiveDirectoryUpstreams(upstreams []v1alpha1.ActiveDirectoryIdentityProvider, now metav1.Time) []v1alpha1.ActiveDirectoryIdentityProvider {
result := make([]v1alpha1.ActiveDirectoryIdentityProvider, 0, len(upstreams))
func normalizeActiveDirectoryUpstreams(upstreams []idpv1alpha1.ActiveDirectoryIdentityProvider, now metav1.Time) []idpv1alpha1.ActiveDirectoryIdentityProvider {
result := make([]idpv1alpha1.ActiveDirectoryIdentityProvider, 0, len(upstreams))
for _, u := range upstreams {
normalized := u.DeepCopy()
// We're only interested in comparing the status, so zero out the spec.
normalized.Spec = v1alpha1.ActiveDirectoryIdentityProviderSpec{}
normalized.Spec = idpv1alpha1.ActiveDirectoryIdentityProviderSpec{}
// Round down the LastTransitionTime values to `now` if they were just updated. This makes
// it much easier to encode assertions about the expected timestamps.
@@ -13,15 +13,15 @@ import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
errorsutil "k8s.io/apimachinery/pkg/util/errors"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/utils/clock"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
configinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/config/v1alpha1"
idpinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1"
@@ -196,15 +196,15 @@ func (c *federationDomainWatcherController) Sync(ctx controllerlib.Context) erro
}
}
return errorsutil.NewAggregate(errs)
return utilerrors.NewAggregate(errs)
}
func (c *federationDomainWatcherController) processAllFederationDomains(
ctx context.Context,
federationDomains []*configv1alpha1.FederationDomain,
) ([]*federationdomainproviders.FederationDomainIssuer, map[*configv1alpha1.FederationDomain][]*metav1.Condition, error) {
federationDomains []*supervisorconfigv1alpha1.FederationDomain,
) ([]*federationdomainproviders.FederationDomainIssuer, map[*supervisorconfigv1alpha1.FederationDomain][]*metav1.Condition, error) {
federationDomainIssuers := make([]*federationdomainproviders.FederationDomainIssuer, 0)
fdToConditionsMap := map[*configv1alpha1.FederationDomain][]*metav1.Condition{}
fdToConditionsMap := map[*supervisorconfigv1alpha1.FederationDomain][]*metav1.Condition{}
crossDomainConfigValidator := newCrossFederationDomainConfigValidator(federationDomains)
for _, federationDomain := range federationDomains {
@@ -233,7 +233,7 @@ func (c *federationDomainWatcherController) processAllFederationDomains(
func (c *federationDomainWatcherController) makeFederationDomainIssuer(
ctx context.Context,
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
conditions []*metav1.Condition,
) (*federationdomainproviders.FederationDomainIssuer, []*metav1.Condition, error) {
var err error
@@ -257,7 +257,7 @@ func (c *federationDomainWatcherController) makeFederationDomainIssuer(
}
func (c *federationDomainWatcherController) makeLegacyFederationDomainIssuer(
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
conditions []*metav1.Condition,
) (*federationdomainproviders.FederationDomainIssuer, []*metav1.Condition, error) {
var defaultFederationDomainIdentityProvider *federationdomainproviders.FederationDomainIdentityProvider
@@ -355,7 +355,7 @@ func (c *federationDomainWatcherController) makeLegacyFederationDomainIssuer(
//nolint:funlen
func (c *federationDomainWatcherController) makeFederationDomainIssuerWithExplicitIDPs(
ctx context.Context,
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
conditions []*metav1.Condition,
) (*federationdomainproviders.FederationDomainIssuer, []*metav1.Condition, error) {
federationDomainIdentityProviders := []*federationdomainproviders.FederationDomainIdentityProvider{}
@@ -474,7 +474,7 @@ func (c *federationDomainWatcherController) findIDPsUIDByObjectRef(objectRef cor
switch {
case err == nil:
idpResourceUID = foundIDP.GetUID()
case errors.IsNotFound(err):
case apierrors.IsNotFound(err):
return "", false, nil
default:
return "", false, err // unexpected error from the informer
@@ -484,7 +484,7 @@ func (c *federationDomainWatcherController) findIDPsUIDByObjectRef(objectRef cor
func (c *federationDomainWatcherController) makeTransformationPipelineAndEvaluateExamplesForIdentityProvider(
ctx context.Context,
idp configv1alpha1.FederationDomainIdentityProvider,
idp supervisorconfigv1alpha1.FederationDomainIdentityProvider,
idpIndex int,
validationErrorMessages *transformsValidationErrorMessages,
) (*idtransform.TransformationPipeline, bool, error) {
@@ -510,7 +510,7 @@ func (c *federationDomainWatcherController) makeTransformationPipelineAndEvaluat
}
func (c *federationDomainWatcherController) makeTransformsConstantsForIdentityProvider(
idp configv1alpha1.FederationDomainIdentityProvider,
idp supervisorconfigv1alpha1.FederationDomainIdentityProvider,
) (*celtransformer.TransformationConstants, error) {
consts := &celtransformer.TransformationConstants{
StringConstants: map[string]string{},
@@ -538,7 +538,7 @@ func (c *federationDomainWatcherController) makeTransformsConstantsForIdentityPr
}
func (c *federationDomainWatcherController) makeTransformationPipelineForIdentityProvider(
idp configv1alpha1.FederationDomainIdentityProvider,
idp supervisorconfigv1alpha1.FederationDomainIdentityProvider,
idpIndex int,
consts *celtransformer.TransformationConstants,
) (*idtransform.TransformationPipeline, string, error) {
@@ -584,7 +584,7 @@ func (c *federationDomainWatcherController) makeTransformationPipelineForIdentit
func (c *federationDomainWatcherController) evaluateExamplesForIdentityProvider(
ctx context.Context,
idp configv1alpha1.FederationDomainIdentityProvider,
idp supervisorconfigv1alpha1.FederationDomainIdentityProvider,
idpIndex int,
pipeline *idtransform.TransformationPipeline,
) (bool, string) {
@@ -682,7 +682,7 @@ func appendIdentityProviderObjectRefKindCondition(expectedKinds []string, badSuf
func appendIdentityProvidersFoundCondition(
idpNotFoundIndices []int,
federationDomainIdentityProviders []configv1alpha1.FederationDomainIdentityProvider,
federationDomainIdentityProviders []supervisorconfigv1alpha1.FederationDomainIdentityProvider,
conditions []*metav1.Condition,
) []*metav1.Condition {
if len(idpNotFoundIndices) != 0 {
@@ -809,13 +809,13 @@ func appendIssuerURLValidCondition(err error, conditions []*metav1.Condition) []
func (c *federationDomainWatcherController) updateStatus(
ctx context.Context,
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
conditions []*metav1.Condition,
) error {
updated := federationDomain.DeepCopy()
if conditionsutil.HadErrorCondition(conditions) {
updated.Status.Phase = configv1alpha1.FederationDomainPhaseError
updated.Status.Phase = supervisorconfigv1alpha1.FederationDomainPhaseError
conditions = append(conditions, &metav1.Condition{
Type: typeReady,
Status: metav1.ConditionFalse,
@@ -823,7 +823,7 @@ func (c *federationDomainWatcherController) updateStatus(
Message: "the FederationDomain is not ready: see other conditions for details",
})
} else {
updated.Status.Phase = configv1alpha1.FederationDomainPhaseReady
updated.Status.Phase = supervisorconfigv1alpha1.FederationDomainPhaseReady
conditions = append(conditions, &metav1.Condition{
Type: typeReady,
Status: metav1.ConditionTrue,
@@ -878,7 +878,7 @@ func issuerURLToIssuerKey(issuerURL *url.URL) string {
return fmt.Sprintf("%s://%s%s", issuerURL.Scheme, strings.ToLower(issuerURL.Host), issuerURL.Path)
}
func (v *crossFederationDomainConfigValidator) Validate(federationDomain *configv1alpha1.FederationDomain, conditions []*metav1.Condition) []*metav1.Condition {
func (v *crossFederationDomainConfigValidator) Validate(federationDomain *supervisorconfigv1alpha1.FederationDomain, conditions []*metav1.Condition) []*metav1.Condition {
issuerURL, urlParseErr := url.Parse(federationDomain.Spec.Issuer)
if urlParseErr != nil {
@@ -933,7 +933,7 @@ func (v *crossFederationDomainConfigValidator) Validate(federationDomain *config
return conditions
}
func newCrossFederationDomainConfigValidator(federationDomains []*configv1alpha1.FederationDomain) *crossFederationDomainConfigValidator {
func newCrossFederationDomainConfigValidator(federationDomains []*supervisorconfigv1alpha1.FederationDomain) *crossFederationDomainConfigValidator {
// Make a map of issuer strings -> count of how many times we saw that issuer string.
// This will help us complain when there are duplicate issuer strings.
// Also make a helper function for forming keys into this map.
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package generator
@@ -9,14 +9,14 @@ import (
"reflect"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1informers "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/util/retry"
"k8s.io/klog/v2"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
configinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/config/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
@@ -26,7 +26,7 @@ import (
type federationDomainSecretsController struct {
secretHelper SecretHelper
secretRefFunc func(domain *configv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference
secretRefFunc func(domain *supervisorconfigv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference
kubeClient kubernetes.Interface
pinnipedClient supervisorclientset.Interface
federationDomainInformer configinformers.FederationDomainInformer
@@ -38,7 +38,7 @@ type federationDomainSecretsController struct {
// provides the parent/child mapping logic.
func NewFederationDomainSecretsController(
secretHelper SecretHelper,
secretRefFunc func(domain *configv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference,
secretRefFunc func(domain *supervisorconfigv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference,
kubeClient kubernetes.Interface,
pinnipedClient supervisorclientset.Interface,
secretInformer corev1informers.SecretInformer,
@@ -75,7 +75,7 @@ func NewFederationDomainSecretsController(
func (c *federationDomainSecretsController) Sync(ctx controllerlib.Context) error {
federationDomain, err := c.federationDomainInformer.Lister().FederationDomains(ctx.Key.Namespace).Get(ctx.Key.Name)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf(
"failed to get %s/%s FederationDomain: %w",
@@ -144,12 +144,12 @@ func (c *federationDomainSecretsController) Sync(ctx controllerlib.Context) erro
// secretNeedsUpdate returns whether or not the Secret, with name secretName, for the federationDomain param
// needs to be updated. It returns the existing secret as its second argument.
func (c *federationDomainSecretsController) secretNeedsUpdate(
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
secretName string,
) (bool, *corev1.Secret, error) {
// This FederationDomain says it has a secret associated with it. Let's try to get it from the cache.
secret, err := c.secretInformer.Lister().Secrets(federationDomain.Namespace).Get(secretName)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if err != nil && !notFound {
return false, nil, fmt.Errorf("cannot get secret: %w", err)
}
@@ -168,13 +168,13 @@ func (c *federationDomainSecretsController) secretNeedsUpdate(
func (c *federationDomainSecretsController) createOrUpdateSecret(
ctx context.Context,
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
newSecret **corev1.Secret,
) error {
secretClient := c.kubeClient.CoreV1().Secrets((*newSecret).Namespace)
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
oldSecret, err := secretClient.Get(ctx, (*newSecret).Name, metav1.GetOptions{})
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf("failed to get secret %s/%s: %w", (*newSecret).Namespace, (*newSecret).Name, err)
}
@@ -207,7 +207,7 @@ func (c *federationDomainSecretsController) createOrUpdateSecret(
func (c *federationDomainSecretsController) updateFederationDomainStatus(
ctx context.Context,
newFederationDomain *configv1alpha1.FederationDomain,
newFederationDomain *supervisorconfigv1alpha1.FederationDomain,
) error {
federationDomainClient := c.pinnipedClient.ConfigV1alpha1().FederationDomains(newFederationDomain.Namespace)
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
@@ -14,7 +14,7 @@ import (
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -22,9 +22,9 @@ import (
kubernetesfake "k8s.io/client-go/kubernetes/fake"
kubetesting "k8s.io/client-go/testing"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
supervisorinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/mocks/mocksecrethelper"
"go.pinniped.dev/internal/testutil"
@@ -72,7 +72,7 @@ func TestFederationDomainControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Name: "some-name",
Controller: boolPtr(true),
},
@@ -88,7 +88,7 @@ func TestFederationDomainControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
},
@@ -104,7 +104,7 @@ func TestFederationDomainControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -128,7 +128,7 @@ func TestFederationDomainControllerFilterSecret(t *testing.T) {
Kind: "UnrelatedKind",
},
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -149,7 +149,7 @@ func TestFederationDomainControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -183,8 +183,8 @@ func TestFederationDomainControllerFilterSecret(t *testing.T) {
kubernetesfake.NewSimpleClientset(),
0,
).Core().V1().Secrets()
federationDomainInformer := pinnipedinformers.NewSharedInformerFactory(
pinnipedfake.NewSimpleClientset(),
federationDomainInformer := supervisorinformers.NewSharedInformerFactory(
supervisorfake.NewSimpleClientset(),
0,
).Config().V1alpha1().FederationDomains()
withInformer := testutil.NewObservableWithInformerOption()
@@ -214,7 +214,7 @@ func TestNewFederationDomainSecretsControllerFilterFederationDomain(t *testing.T
tests := []struct {
name string
federationDomain configv1alpha1.FederationDomain
federationDomain supervisorconfigv1alpha1.FederationDomain
wantAdd bool
wantUpdate bool
wantDelete bool
@@ -222,7 +222,7 @@ func TestNewFederationDomainSecretsControllerFilterFederationDomain(t *testing.T
}{
{
name: "anything goes",
federationDomain: configv1alpha1.FederationDomain{},
federationDomain: supervisorconfigv1alpha1.FederationDomain{},
wantAdd: true,
wantUpdate: true,
wantDelete: true,
@@ -245,8 +245,8 @@ func TestNewFederationDomainSecretsControllerFilterFederationDomain(t *testing.T
kubernetesfake.NewSimpleClientset(),
0,
).Core().V1().Secrets()
federationDomainInformer := pinnipedinformers.NewSharedInformerFactory(
pinnipedfake.NewSimpleClientset(),
federationDomainInformer := supervisorinformers.NewSharedInformerFactory(
supervisorfake.NewSimpleClientset(),
0,
).Config().V1alpha1().FederationDomains()
withInformer := testutil.NewObservableWithInformerOption()
@@ -260,7 +260,7 @@ func TestNewFederationDomainSecretsControllerFilterFederationDomain(t *testing.T
withInformer.WithInformer,
)
unrelated := configv1alpha1.FederationDomain{}
unrelated := supervisorconfigv1alpha1.FederationDomain{}
filter := withInformer.GetFilterForInformer(federationDomainInformer)
require.Equal(t, test.wantAdd, filter.Add(test.federationDomain.DeepCopy()))
require.Equal(t, test.wantUpdate, filter.Update(&unrelated, test.federationDomain.DeepCopy()))
@@ -285,8 +285,8 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
)
federationDomainGVR := schema.GroupVersionResource{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Resource: "federationdomains",
}
@@ -296,7 +296,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
Resource: "secrets",
}
goodFederationDomain := &configv1alpha1.FederationDomain{
goodFederationDomain := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: federationDomainName,
Namespace: namespace,
@@ -359,8 +359,8 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
tests := []struct {
name string
storage func(**configv1alpha1.FederationDomain, **corev1.Secret)
client func(*pinnipedfake.Clientset, *kubernetesfake.Clientset)
storage func(**supervisorconfigv1alpha1.FederationDomain, **corev1.Secret)
client func(*supervisorfake.Clientset, *kubernetesfake.Clientset)
secretHelper func(*mocksecrethelper.MockSecretHelper)
wantFederationDomainActions []kubetesting.Action
wantSecretActions []kubetesting.Action
@@ -368,20 +368,20 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
}{
{
name: "FederationDomain does not exist and secret does not exist",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*federationDomain = nil
*s = nil
},
},
{
name: "FederationDomain does not exist and secret exists",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*federationDomain = nil
},
},
{
name: "FederationDomain exists and secret does not exist",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = nil
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -399,14 +399,14 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and secret does not exist and upon updating FederationDomain we learn a new status field has been set",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = nil
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
secretHelper.EXPECT().Generate(goodFederationDomain).Times(1).Return(goodSecret, nil)
secretHelper.EXPECT().ObserveActiveSecretAndUpdateParentFederationDomain(goodFederationDomain, goodSecret).Times(1).Return(goodFederationDomainWithTokenSigningKey)
},
client: func(c *pinnipedfake.Clientset, _ *kubernetesfake.Clientset) {
client: func(c *supervisorfake.Clientset, _ *kubernetesfake.Clientset) {
c.PrependReactor("get", "federationdomains", func(_ kubetesting.Action) (bool, runtime.Object, error) {
return true, goodFederationDomainWithJWKS, nil
})
@@ -422,14 +422,14 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and secret does not exist and upon updating FederationDomain we learn all status fields have been set",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = nil
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
secretHelper.EXPECT().Generate(goodFederationDomain).Times(1).Return(goodSecret, nil)
secretHelper.EXPECT().ObserveActiveSecretAndUpdateParentFederationDomain(goodFederationDomain, goodSecret).Times(1).Return(goodFederationDomainWithTokenSigningKey)
},
client: func(c *pinnipedfake.Clientset, _ *kubernetesfake.Clientset) {
client: func(c *supervisorfake.Clientset, _ *kubernetesfake.Clientset) {
c.PrependReactor("get", "federationdomains", func(_ kubetesting.Action) (bool, runtime.Object, error) {
return true, goodFederationDomainWithJWKSAndTokenSigningKey, nil
})
@@ -444,7 +444,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and invalid secret exists",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = invalidSecret.DeepCopy()
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -493,7 +493,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
secretHelper.EXPECT().Generate(goodFederationDomain).Times(1).Return(goodSecret, nil)
secretHelper.EXPECT().IsValid(goodFederationDomain, goodSecret).Times(1).Return(false)
},
client: func(_ *pinnipedfake.Clientset, c *kubernetesfake.Clientset) {
client: func(_ *supervisorfake.Clientset, c *kubernetesfake.Clientset) {
c.PrependReactor("get", "secrets", func(_ kubetesting.Action) (bool, runtime.Object, error) {
return true, nil, errors.New("some get error")
})
@@ -505,13 +505,13 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and secret does not exist and creating secret fails",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = nil
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
secretHelper.EXPECT().Generate(goodFederationDomain).Times(1).Return(goodSecret, nil)
},
client: func(_ *pinnipedfake.Clientset, c *kubernetesfake.Clientset) {
client: func(_ *supervisorfake.Clientset, c *kubernetesfake.Clientset) {
c.PrependReactor("create", "secrets", func(_ kubetesting.Action) (bool, runtime.Object, error) {
return true, nil, errors.New("some create error")
})
@@ -528,7 +528,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
secretHelper.EXPECT().Generate(goodFederationDomain).Times(1).Return(goodSecret, nil)
secretHelper.EXPECT().IsValid(goodFederationDomain, goodSecret).Times(2).Return(false)
},
client: func(_ *pinnipedfake.Clientset, c *kubernetesfake.Clientset) {
client: func(_ *supervisorfake.Clientset, c *kubernetesfake.Clientset) {
c.PrependReactor("update", "secrets", func(_ kubetesting.Action) (bool, runtime.Object, error) {
return true, nil, errors.New("some update error")
})
@@ -541,7 +541,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and invalid secret exists and updating secret fails due to conflict",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = invalidSecret.DeepCopy()
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -549,11 +549,11 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
secretHelper.EXPECT().IsValid(goodFederationDomain, invalidSecret).Times(3).Return(false)
secretHelper.EXPECT().ObserveActiveSecretAndUpdateParentFederationDomain(goodFederationDomain, goodSecret).Times(1).Return(goodFederationDomainWithTokenSigningKey)
},
client: func(_ *pinnipedfake.Clientset, c *kubernetesfake.Clientset) {
client: func(_ *supervisorfake.Clientset, c *kubernetesfake.Clientset) {
once := sync.Once{}
c.PrependReactor("update", "secrets", func(_ kubetesting.Action) (bool, runtime.Object, error) {
var err error
once.Do(func() { err = k8serrors.NewConflict(secretGVR.GroupResource(), namespace, errors.New("some error")) })
once.Do(func() { err = apierrors.NewConflict(secretGVR.GroupResource(), namespace, errors.New("some error")) })
return true, nil, err
})
},
@@ -570,7 +570,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and invalid secret exists and getting FederationDomain fails",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = invalidSecret.DeepCopy()
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -578,7 +578,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
secretHelper.EXPECT().IsValid(goodFederationDomain, invalidSecret).Times(2).Return(false)
secretHelper.EXPECT().ObserveActiveSecretAndUpdateParentFederationDomain(goodFederationDomain, goodSecret).Times(1).Return(goodFederationDomainWithTokenSigningKey)
},
client: func(c *pinnipedfake.Clientset, _ *kubernetesfake.Clientset) {
client: func(c *supervisorfake.Clientset, _ *kubernetesfake.Clientset) {
c.PrependReactor("get", "federationdomains", func(_ kubetesting.Action) (bool, runtime.Object, error) {
return true, nil, errors.New("some get error")
})
@@ -594,7 +594,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and invalid secret exists and updating FederationDomain fails due to conflict",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = invalidSecret.DeepCopy()
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -602,11 +602,11 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
secretHelper.EXPECT().IsValid(goodFederationDomain, invalidSecret).Times(2).Return(false)
secretHelper.EXPECT().ObserveActiveSecretAndUpdateParentFederationDomain(goodFederationDomain, goodSecret).Times(1).Return(goodFederationDomainWithTokenSigningKey)
},
client: func(c *pinnipedfake.Clientset, _ *kubernetesfake.Clientset) {
client: func(c *supervisorfake.Clientset, _ *kubernetesfake.Clientset) {
once := sync.Once{}
c.PrependReactor("update", "federationdomains", func(_ kubetesting.Action) (bool, runtime.Object, error) {
var err error
once.Do(func() { err = k8serrors.NewConflict(secretGVR.GroupResource(), namespace, errors.New("some error")) })
once.Do(func() { err = apierrors.NewConflict(secretGVR.GroupResource(), namespace, errors.New("some error")) })
return true, nil, err
})
},
@@ -629,8 +629,8 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
pinnipedAPIClient := pinnipedfake.NewSimpleClientset()
pinnipedInformerClient := pinnipedfake.NewSimpleClientset()
pinnipedAPIClient := supervisorfake.NewSimpleClientset()
pinnipedInformerClient := supervisorfake.NewSimpleClientset()
kubeAPIClient := kubernetesfake.NewSimpleClientset()
kubeInformerClient := kubernetesfake.NewSimpleClientset()
@@ -657,7 +657,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
kubeInformerClient,
0,
)
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(
pinnipedInformers := supervisorinformers.NewSharedInformerFactory(
pinnipedInformerClient,
0,
)
@@ -673,7 +673,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
c := NewFederationDomainSecretsController(
secretHelper,
func(fd *configv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference {
func(fd *supervisorconfigv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference {
return &fd.Secrets.TokenSigningKey
},
kubeAPIClient,
@@ -11,7 +11,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
)
// SecretHelper describes an object that can Generate() a Secret and determine whether a Secret
@@ -20,9 +20,9 @@ import (
// A SecretHelper has a NamePrefix() that can be used to identify it from other SecretHelper instances.
type SecretHelper interface {
NamePrefix() string
Generate(*configv1alpha1.FederationDomain) (*corev1.Secret, error)
IsValid(*configv1alpha1.FederationDomain, *corev1.Secret) bool
ObserveActiveSecretAndUpdateParentFederationDomain(*configv1alpha1.FederationDomain, *corev1.Secret) *configv1alpha1.FederationDomain
Generate(*supervisorconfigv1alpha1.FederationDomain) (*corev1.Secret, error)
IsValid(*supervisorconfigv1alpha1.FederationDomain, *corev1.Secret) bool
ObserveActiveSecretAndUpdateParentFederationDomain(*supervisorconfigv1alpha1.FederationDomain, *corev1.Secret) *supervisorconfigv1alpha1.FederationDomain
Handles(metav1.Object) bool
}
@@ -89,7 +89,7 @@ type symmetricSecretHelper struct {
func (s *symmetricSecretHelper) NamePrefix() string { return s.namePrefix }
// Generate implements SecretHelper.Generate().
func (s *symmetricSecretHelper) Generate(parent *configv1alpha1.FederationDomain) (*corev1.Secret, error) {
func (s *symmetricSecretHelper) Generate(parent *supervisorconfigv1alpha1.FederationDomain) (*corev1.Secret, error) {
key := make([]byte, symmetricKeySize)
if _, err := s.rand.Read(key); err != nil {
return nil, err
@@ -102,8 +102,8 @@ func (s *symmetricSecretHelper) Generate(parent *configv1alpha1.FederationDomain
Labels: s.labels,
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(parent, schema.GroupVersionKind{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Kind: federationDomainKind,
}),
},
@@ -116,7 +116,7 @@ func (s *symmetricSecretHelper) Generate(parent *configv1alpha1.FederationDomain
}
// IsValid implements SecretHelper.IsValid().
func (s *symmetricSecretHelper) IsValid(parent *configv1alpha1.FederationDomain, secret *corev1.Secret) bool {
func (s *symmetricSecretHelper) IsValid(parent *supervisorconfigv1alpha1.FederationDomain, secret *corev1.Secret) bool {
if !metav1.IsControlledBy(secret, parent) {
return false
}
@@ -138,9 +138,9 @@ func (s *symmetricSecretHelper) IsValid(parent *configv1alpha1.FederationDomain,
// ObserveActiveSecretAndUpdateParentFederationDomain implements SecretHelper.ObserveActiveSecretAndUpdateParentFederationDomain().
func (s *symmetricSecretHelper) ObserveActiveSecretAndUpdateParentFederationDomain(
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
secret *corev1.Secret,
) *configv1alpha1.FederationDomain {
) *supervisorconfigv1alpha1.FederationDomain {
s.updateCacheFunc(federationDomain.Spec.Issuer, secret.Data[symmetricSecretDataKey])
switch s.secretUsage {
@@ -189,6 +189,6 @@ func IsFederationDomainSecretOfType(obj metav1.Object, secretType corev1.SecretT
func isFederationDomainControllee(obj metav1.Object) bool {
controller := metav1.GetControllerOf(obj)
return controller != nil &&
controller.APIVersion == configv1alpha1.SchemeGroupVersion.String() &&
controller.APIVersion == supervisorconfigv1alpha1.SchemeGroupVersion.String() &&
controller.Kind == federationDomainKind
}
@@ -12,7 +12,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
)
const keyWith32Bytes = "0123456789abcdef0123456789abcdef"
@@ -24,13 +24,13 @@ func TestSymmetricSecretHelper(t *testing.T) {
name string
secretUsage SecretUsage
wantSecretType corev1.SecretType
wantSetFederationDomainField func(*configv1alpha1.FederationDomain) string
wantSetFederationDomainField func(*supervisorconfigv1alpha1.FederationDomain) string
}{
{
name: "token signing key",
secretUsage: SecretUsageTokenSigningKey,
wantSecretType: "secrets.pinniped.dev/federation-domain-token-signing-key",
wantSetFederationDomainField: func(federationDomain *configv1alpha1.FederationDomain) string {
wantSetFederationDomainField: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.TokenSigningKey.Name
},
},
@@ -38,7 +38,7 @@ func TestSymmetricSecretHelper(t *testing.T) {
name: "state signing key",
secretUsage: SecretUsageStateSigningKey,
wantSecretType: "secrets.pinniped.dev/federation-domain-state-signing-key",
wantSetFederationDomainField: func(federationDomain *configv1alpha1.FederationDomain) string {
wantSetFederationDomainField: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.StateSigningKey.Name
},
},
@@ -46,7 +46,7 @@ func TestSymmetricSecretHelper(t *testing.T) {
name: "state encryption key",
secretUsage: SecretUsageStateEncryptionKey,
wantSecretType: "secrets.pinniped.dev/federation-domain-state-encryption-key",
wantSetFederationDomainField: func(federationDomain *configv1alpha1.FederationDomain) string {
wantSetFederationDomainField: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.StateEncryptionKey.Name
},
},
@@ -74,7 +74,7 @@ func TestSymmetricSecretHelper(t *testing.T) {
},
)
parent := &configv1alpha1.FederationDomain{
parent := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
UID: "some-uid",
Namespace: "some-namespace",
@@ -89,8 +89,8 @@ func TestSymmetricSecretHelper(t *testing.T) {
Labels: labels,
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(parent, schema.GroupVersionKind{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Kind: "FederationDomain",
}),
},
@@ -124,7 +124,7 @@ func TestSymmetricSecretHelperIsValid(t *testing.T) {
name string
secretUsage SecretUsage
child func(*corev1.Secret)
parent func(*configv1alpha1.FederationDomain)
parent func(*supervisorconfigv1alpha1.FederationDomain)
want bool
}{
{
@@ -167,7 +167,7 @@ func TestSymmetricSecretHelperIsValid(t *testing.T) {
child: func(s *corev1.Secret) {
s.Type = FederationDomainTokenSigningKeyType
},
parent: func(federationDomain *configv1alpha1.FederationDomain) {
parent: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) {
federationDomain.UID = "wrong"
},
want: false,
@@ -184,7 +184,7 @@ func TestSymmetricSecretHelperIsValid(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
h := NewSymmetricSecretHelper("none of these args matter", nil, nil, test.secretUsage, nil)
parent := &configv1alpha1.FederationDomain{
parent := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "some-parent-name",
Namespace: "some-namespace",
@@ -197,8 +197,8 @@ func TestSymmetricSecretHelperIsValid(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(parent, schema.GroupVersionKind{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Kind: "FederationDomain",
}),
},
@@ -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 generator provides a supervisorSecretsController that can ensure existence of a generated secret.
@@ -11,7 +11,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1informers "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
@@ -75,7 +75,7 @@ func NewSupervisorSecretsController(
// Sync implements controllerlib.Syncer.Sync().
func (c *supervisorSecretsController) Sync(ctx controllerlib.Context) error {
secret, err := c.secretInformer.Lister().Secrets(ctx.Key.Namespace).Get(ctx.Key.Name)
isNotFound := k8serrors.IsNotFound(err)
isNotFound := apierrors.IsNotFound(err)
if !isNotFound && err != nil {
return fmt.Errorf("failed to list secret %s/%s: %w", ctx.Key.Namespace, ctx.Key.Name, err)
}
@@ -115,7 +115,7 @@ func (c *supervisorSecretsController) updateSecret(ctx context.Context, newSecre
secrets := c.kubeClient.CoreV1().Secrets((*newSecret).Namespace)
return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
currentSecret, err := secrets.Get(ctx, secretName, metav1.GetOptions{})
isNotFound := k8serrors.IsNotFound(err)
isNotFound := apierrors.IsNotFound(err)
if !isNotFound && err != nil {
return fmt.Errorf("failed to get secret: %w", err)
}
@@ -12,7 +12,7 @@ import (
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -306,7 +306,7 @@ func TestSupervisorSecretsControllerSync(t *testing.T) {
client.PrependReactor("update", "secrets", func(action kubetesting.Action) (bool, runtime.Object, error) {
var err error
once.Do(func() {
err = k8serrors.NewConflict(secretsGVR.GroupResource(), generatedSecretName, errors.New("some error"))
err = apierrors.NewConflict(secretsGVR.GroupResource(), generatedSecretName, errors.New("some error"))
})
return true, nil, err
})
@@ -363,7 +363,7 @@ func TestSupervisorSecretsControllerSync(t *testing.T) {
},
apiClient: func(t *testing.T, client *kubernetesfake.Clientset) {
client.PrependReactor("get", "secrets", func(action kubetesting.Action) (bool, runtime.Object, error) {
return true, nil, k8serrors.NewNotFound(secretsGVR.GroupResource(), generatedSecretName)
return true, nil, apierrors.NewNotFound(secretsGVR.GroupResource(), generatedSecretName)
})
client.PrependReactor("create", "secrets", func(action kubetesting.Action) (bool, runtime.Object, error) {
return true, nil, nil
@@ -382,7 +382,7 @@ func TestSupervisorSecretsControllerSync(t *testing.T) {
},
apiClient: func(t *testing.T, client *kubernetesfake.Clientset) {
client.PrependReactor("get", "secrets", func(action kubetesting.Action) (bool, runtime.Object, error) {
return true, nil, k8serrors.NewNotFound(secretsGVR.GroupResource(), generatedSecretName)
return true, nil, apierrors.NewNotFound(secretsGVR.GroupResource(), generatedSecretName)
})
client.PrependReactor("create", "secrets", func(action kubetesting.Action) (bool, runtime.Object, error) {
return true, nil, errors.New("some create error")
@@ -18,15 +18,14 @@ import (
"golang.org/x/oauth2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
k8sapierrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
errorsutil "k8s.io/apimachinery/pkg/util/errors"
k8sutilerrors "k8s.io/apimachinery/pkg/util/errors"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
corev1informers "k8s.io/client-go/informers/core/v1"
"k8s.io/utils/clock"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
idpinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
@@ -106,7 +105,7 @@ func New(
withInformer(
gitHubIdentityProviderInformer,
pinnipedcontroller.SimpleFilter(func(obj metav1.Object) bool {
gitHubIDP, ok := obj.(*v1alpha1.GitHubIdentityProvider)
gitHubIDP, ok := obj.(*idpv1alpha1.GitHubIdentityProvider)
return ok && gitHubIDP.Namespace == namespace
}, pinnipedcontroller.SingletonQueue()),
controllerlib.InformerOption{},
@@ -127,7 +126,7 @@ func (c *gitHubWatcherController) Sync(ctx controllerlib.Context) error {
}
// Sort them by name just so that the logs output is consistent
slices.SortStableFunc(actualUpstreams, func(a, b *v1alpha1.GitHubIdentityProvider) int {
slices.SortStableFunc(actualUpstreams, func(a, b *idpv1alpha1.GitHubIdentityProvider) int {
return strings.Compare(a.Name, b.Name)
})
@@ -151,14 +150,14 @@ func (c *gitHubWatcherController) Sync(ctx controllerlib.Context) error {
applicationErrors = append([]error{controllerlib.ErrSyntheticRequeue}, applicationErrors...)
}
return errorsutil.NewAggregate(applicationErrors)
return utilerrors.NewAggregate(applicationErrors)
}
func (c *gitHubWatcherController) validateClientSecret(secretName string) (*metav1.Condition, string, string, error) {
secret, unableToRetrieveSecretErr := c.secretInformer.Lister().Secrets(c.namespace).Get(secretName)
// This error requires user interaction, so ignore it.
if k8sapierrors.IsNotFound(unableToRetrieveSecretErr) {
if apierrors.IsNotFound(unableToRetrieveSecretErr) {
unableToRetrieveSecretErr = nil
}
@@ -207,16 +206,16 @@ func (c *gitHubWatcherController) validateClientSecret(secretName string) (*meta
}, clientID, clientSecret, nil
}
func validateOrganizationsPolicy(organizationsSpec *v1alpha1.GitHubOrganizationsSpec) *metav1.Condition {
var policy v1alpha1.GitHubAllowedAuthOrganizationsPolicy
func validateOrganizationsPolicy(organizationsSpec *idpv1alpha1.GitHubOrganizationsSpec) *metav1.Condition {
var policy idpv1alpha1.GitHubAllowedAuthOrganizationsPolicy
if organizationsSpec.Policy != nil {
policy = *organizationsSpec.Policy
}
// Should not happen due to CRD defaulting, enum validation, and CEL validation (for recent versions of K8s only!)
// That is why the message here is very minimal
if (policy == v1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers && len(organizationsSpec.Allowed) == 0) ||
(policy == v1alpha1.GitHubAllowedAuthOrganizationsPolicyOnlyUsersFromAllowedOrganizations && len(organizationsSpec.Allowed) > 0) {
if (policy == idpv1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers && len(organizationsSpec.Allowed) == 0) ||
(policy == idpv1alpha1.GitHubAllowedAuthOrganizationsPolicyOnlyUsersFromAllowedOrganizations && len(organizationsSpec.Allowed) > 0) {
return &metav1.Condition{
Type: OrganizationsPolicyValid,
Status: metav1.ConditionTrue,
@@ -242,7 +241,7 @@ func validateOrganizationsPolicy(organizationsSpec *v1alpha1.GitHubOrganizations
}
}
func (c *gitHubWatcherController) validateUpstreamAndUpdateConditions(ctx controllerlib.Context, upstream *v1alpha1.GitHubIdentityProvider) (
func (c *gitHubWatcherController) validateUpstreamAndUpdateConditions(ctx controllerlib.Context, upstream *idpv1alpha1.GitHubIdentityProvider) (
*upstreamgithub.Provider, // If validated, returns the config
error, // This error will only refer to programmatic errors such as inability to perform a Dial or dereference a pointer, not configuration errors
) {
@@ -285,7 +284,7 @@ func (c *gitHubWatcherController) validateUpstreamAndUpdateConditions(ctx contro
// Status: metav1.ConditionFalse, never be omitted.
if len(conditions) != countExpectedConditions { // untested since all code paths return the same number of conditions
applicationErrors = append(applicationErrors, fmt.Errorf("expected %d conditions but found %d conditions", countExpectedConditions, len(conditions)))
return nil, k8sutilerrors.NewAggregate(applicationErrors)
return nil, utilerrors.NewAggregate(applicationErrors)
}
hadErrorCondition, updateStatusErr := c.updateStatus(ctx.Context, upstream, conditions)
if updateStatusErr != nil {
@@ -293,7 +292,7 @@ func (c *gitHubWatcherController) validateUpstreamAndUpdateConditions(ctx contro
}
// Any error condition means we will not add the IDP to the cache, so just return nil here
if hadErrorCondition {
return nil, k8sutilerrors.NewAggregate(applicationErrors)
return nil, utilerrors.NewAggregate(applicationErrors)
}
provider := upstreamgithub.New(
@@ -320,7 +319,7 @@ func (c *gitHubWatcherController) validateUpstreamAndUpdateConditions(ctx contro
HttpClient: httpClient,
},
)
return provider, k8sutilerrors.NewAggregate(applicationErrors)
return provider, utilerrors.NewAggregate(applicationErrors)
}
func apiBaseUrl(upstreamSpecHost string, hostURL string) string {
@@ -330,7 +329,7 @@ func apiBaseUrl(upstreamSpecHost string, hostURL string) string {
return defaultApiBaseURL
}
func validateHost(gitHubAPIConfig v1alpha1.GitHubAPIConfig) (*metav1.Condition, *endpointaddr.HostPort) {
func validateHost(gitHubAPIConfig idpv1alpha1.GitHubAPIConfig) (*metav1.Condition, *endpointaddr.HostPort) {
buildInvalidHost := func(host, reason string) *metav1.Condition {
return &metav1.Condition{
Type: HostValid,
@@ -360,7 +359,7 @@ func validateHost(gitHubAPIConfig v1alpha1.GitHubAPIConfig) (*metav1.Condition,
}, &hostPort
}
func (c *gitHubWatcherController) validateTLSConfiguration(tlsSpec *v1alpha1.TLSSpec) (*metav1.Condition, *x509.CertPool) {
func (c *gitHubWatcherController) validateTLSConfiguration(tlsSpec *idpv1alpha1.TLSSpec) (*metav1.Condition, *x509.CertPool) {
certPool, _, buildCertPoolErr := pinnipedcontroller.BuildCertPoolIDP(tlsSpec)
if buildCertPoolErr != nil {
// buildCertPoolErr is not recoverable with a resync.
@@ -428,7 +427,7 @@ func buildDialErrorMessage(tlsDialErr error) string {
return reason
}
func validateUserAndGroupAttributes(upstream *v1alpha1.GitHubIdentityProvider) (*metav1.Condition, v1alpha1.GitHubGroupNameAttribute, v1alpha1.GitHubUsernameAttribute) {
func validateUserAndGroupAttributes(upstream *idpv1alpha1.GitHubIdentityProvider) (*metav1.Condition, idpv1alpha1.GitHubGroupNameAttribute, idpv1alpha1.GitHubUsernameAttribute) {
buildInvalidCondition := func(message string) *metav1.Condition {
return &metav1.Condition{
Type: ClaimsValid,
@@ -438,14 +437,14 @@ func validateUserAndGroupAttributes(upstream *v1alpha1.GitHubIdentityProvider) (
}
}
var usernameAttribute v1alpha1.GitHubUsernameAttribute
var usernameAttribute idpv1alpha1.GitHubUsernameAttribute
if upstream.Spec.Claims.Username == nil {
return buildInvalidCondition("spec.claims.username is required"), "", ""
} else {
usernameAttribute = *upstream.Spec.Claims.Username
}
var groupNameAttribute v1alpha1.GitHubGroupNameAttribute
var groupNameAttribute idpv1alpha1.GitHubGroupNameAttribute
if upstream.Spec.Claims.Groups == nil {
return buildInvalidCondition("spec.claims.groups is required"), "", ""
} else {
@@ -453,17 +452,17 @@ func validateUserAndGroupAttributes(upstream *v1alpha1.GitHubIdentityProvider) (
}
switch usernameAttribute {
case v1alpha1.GitHubUsernameLoginAndID:
case v1alpha1.GitHubUsernameLogin:
case v1alpha1.GitHubUsernameID:
case idpv1alpha1.GitHubUsernameLoginAndID:
case idpv1alpha1.GitHubUsernameLogin:
case idpv1alpha1.GitHubUsernameID:
default:
// Should not happen due to CRD enum validation
return buildInvalidCondition(fmt.Sprintf("spec.claims.username (%q) is not valid", usernameAttribute)), "", ""
}
switch groupNameAttribute {
case v1alpha1.GitHubUseTeamNameForGroupName:
case v1alpha1.GitHubUseTeamSlugForGroupName:
case idpv1alpha1.GitHubUseTeamNameForGroupName:
case idpv1alpha1.GitHubUseTeamSlugForGroupName:
default:
// Should not happen due to CRD enum validation
return buildInvalidCondition(fmt.Sprintf("spec.claims.groups (%q) is not valid", groupNameAttribute)), "", ""
@@ -479,7 +478,7 @@ func validateUserAndGroupAttributes(upstream *v1alpha1.GitHubIdentityProvider) (
func (c *gitHubWatcherController) updateStatus(
ctx context.Context,
upstream *v1alpha1.GitHubIdentityProvider,
upstream *idpv1alpha1.GitHubIdentityProvider,
conditions []*metav1.Condition) (bool, error) {
log := c.log.WithValues("namespace", upstream.Namespace, "name", upstream.Name)
updated := upstream.DeepCopy()
@@ -492,9 +491,9 @@ func (c *gitHubWatcherController) updateStatus(
metav1.NewTime(c.clock.Now()),
)
updated.Status.Phase = v1alpha1.GitHubPhaseReady
updated.Status.Phase = idpv1alpha1.GitHubPhaseReady
if hadErrorCondition {
updated.Status.Phase = v1alpha1.GitHubPhaseError
updated.Status.Phase = idpv1alpha1.GitHubPhaseError
}
if equality.Semantic.DeepEqual(upstream, updated) {
@@ -30,9 +30,9 @@ import (
clocktesting "k8s.io/utils/clock/testing"
"k8s.io/utils/ptr"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
supervisorinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/certauthority"
pinnipedcontroller "go.pinniped.dev/internal/controller"
"go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers"
@@ -49,12 +49,12 @@ import (
var (
githubIDPGVR = schema.GroupVersionResource{
Group: v1alpha1.SchemeGroupVersion.Group,
Version: v1alpha1.SchemeGroupVersion.Version,
Group: idpv1alpha1.SchemeGroupVersion.Group,
Version: idpv1alpha1.SchemeGroupVersion.Version,
Resource: "githubidentityproviders",
}
githubIDPKind = v1alpha1.SchemeGroupVersion.WithKind("GitHubIdentityProvider")
githubIDPKind = idpv1alpha1.SchemeGroupVersion.WithKind("GitHubIdentityProvider")
)
func TestController(t *testing.T) {
@@ -98,62 +98,62 @@ func TestController(t *testing.T) {
},
}
validMinimalIDP := &v1alpha1.GitHubIdentityProvider{
validMinimalIDP := &idpv1alpha1.GitHubIdentityProvider{
ObjectMeta: metav1.ObjectMeta{
Name: "minimal-idp-name",
Namespace: namespace,
UID: types.UID("minimal-uid"),
Generation: wantObservedGeneration,
},
Spec: v1alpha1.GitHubIdentityProviderSpec{
GitHubAPI: v1alpha1.GitHubAPIConfig{
Spec: idpv1alpha1.GitHubIdentityProviderSpec{
GitHubAPI: idpv1alpha1.GitHubAPIConfig{
Host: ptr.To(goodServerDomain),
TLS: &v1alpha1.TLSSpec{
TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: goodServerCAB64,
},
},
Client: v1alpha1.GitHubClientSpec{
Client: idpv1alpha1.GitHubClientSpec{
SecretName: goodSecret.Name,
},
// These claims are optional when using the actual Kubernetes CRD.
// However, they are required here because CRD defaulting/validation does not occur during testing.
Claims: v1alpha1.GitHubClaims{
Username: ptr.To(v1alpha1.GitHubUsernameLogin),
Groups: ptr.To(v1alpha1.GitHubUseTeamSlugForGroupName),
Claims: idpv1alpha1.GitHubClaims{
Username: ptr.To(idpv1alpha1.GitHubUsernameLogin),
Groups: ptr.To(idpv1alpha1.GitHubUseTeamSlugForGroupName),
},
AllowAuthentication: v1alpha1.GitHubAllowAuthenticationSpec{
Organizations: v1alpha1.GitHubOrganizationsSpec{
Policy: ptr.To(v1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers),
AllowAuthentication: idpv1alpha1.GitHubAllowAuthenticationSpec{
Organizations: idpv1alpha1.GitHubOrganizationsSpec{
Policy: ptr.To(idpv1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers),
},
},
},
}
validFilledOutIDP := &v1alpha1.GitHubIdentityProvider{
validFilledOutIDP := &idpv1alpha1.GitHubIdentityProvider{
ObjectMeta: metav1.ObjectMeta{
Name: "some-idp-name",
Namespace: namespace,
UID: types.UID("some-resource-uid"),
Generation: wantObservedGeneration,
},
Spec: v1alpha1.GitHubIdentityProviderSpec{
GitHubAPI: v1alpha1.GitHubAPIConfig{
Spec: idpv1alpha1.GitHubIdentityProviderSpec{
GitHubAPI: idpv1alpha1.GitHubAPIConfig{
Host: ptr.To(goodServerDomain),
TLS: &v1alpha1.TLSSpec{
TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: goodServerCAB64,
},
},
Claims: v1alpha1.GitHubClaims{
Username: ptr.To(v1alpha1.GitHubUsernameID),
Groups: ptr.To(v1alpha1.GitHubUseTeamNameForGroupName),
Claims: idpv1alpha1.GitHubClaims{
Username: ptr.To(idpv1alpha1.GitHubUsernameID),
Groups: ptr.To(idpv1alpha1.GitHubUseTeamNameForGroupName),
},
AllowAuthentication: v1alpha1.GitHubAllowAuthenticationSpec{
Organizations: v1alpha1.GitHubOrganizationsSpec{
Policy: ptr.To(v1alpha1.GitHubAllowedAuthOrganizationsPolicyOnlyUsersFromAllowedOrganizations),
AllowAuthentication: idpv1alpha1.GitHubAllowAuthenticationSpec{
Organizations: idpv1alpha1.GitHubOrganizationsSpec{
Policy: ptr.To(idpv1alpha1.GitHubAllowedAuthOrganizationsPolicyOnlyUsersFromAllowedOrganizations),
Allowed: []string{"organization1", "org2"},
},
},
Client: v1alpha1.GitHubClientSpec{
Client: idpv1alpha1.GitHubClientSpec{
SecretName: goodSecret.Name,
},
},
@@ -211,7 +211,7 @@ func TestController(t *testing.T) {
}
}
buildOrganizationsPolicyValidTrue := func(t *testing.T, policy v1alpha1.GitHubAllowedAuthOrganizationsPolicy) metav1.Condition {
buildOrganizationsPolicyValidTrue := func(t *testing.T, policy idpv1alpha1.GitHubAllowedAuthOrganizationsPolicy) metav1.Condition {
t.Helper()
return metav1.Condition{
@@ -377,12 +377,12 @@ func TestController(t *testing.T) {
wantErr string
wantLogs []string
wantResultingCache []*upstreamgithub.ProviderConfig
wantResultingUpstreams []v1alpha1.GitHubIdentityProvider
wantResultingUpstreams []idpv1alpha1.GitHubIdentityProvider
}{
{
name: "no GitHubIdentityProviders",
wantResultingCache: []*upstreamgithub.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{},
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{},
wantLogs: []string{},
},
{
@@ -414,12 +414,12 @@ func TestController(t *testing.T) {
HttpClient: nil, // let the test runner populate this for us
},
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: validFilledOutIDP.Spec,
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseReady,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseReady,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -470,12 +470,12 @@ func TestController(t *testing.T) {
HttpClient: nil, // let the test runner populate this for us
},
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: validMinimalIDP.Spec,
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseReady,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseReady,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validMinimalIDP.Spec.Client.SecretName),
@@ -540,17 +540,17 @@ func TestController(t *testing.T) {
HttpClient: nil, // let the test runner populate this for us
},
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
githubIDP := validMinimalIDP.DeepCopy()
githubIDP.Spec.GitHubAPI.Host = ptr.To("github.com")
// don't change the CA because we are not really going to dial github.com in this test
return githubIDP.Spec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseReady,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseReady,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validMinimalIDP.Spec.Client.SecretName),
@@ -579,7 +579,7 @@ func TestController(t *testing.T) {
func() runtime.Object {
ipv6IDP := validMinimalIDP.DeepCopy()
ipv6IDP.Spec.GitHubAPI.Host = ptr.To(goodServerIPv6Domain)
ipv6IDP.Spec.GitHubAPI.TLS = &v1alpha1.TLSSpec{
ipv6IDP.Spec.GitHubAPI.TLS = &idpv1alpha1.TLSSpec{
CertificateAuthorityData: goodServerIPv6CAB64,
}
return ipv6IDP
@@ -608,20 +608,20 @@ func TestController(t *testing.T) {
HttpClient: nil, // let the test runner populate this for us
},
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
otherSpec := validMinimalIDP.Spec.DeepCopy()
otherSpec.GitHubAPI.Host = ptr.To(goodServerIPv6Domain)
otherSpec.GitHubAPI.TLS = &v1alpha1.TLSSpec{
otherSpec.GitHubAPI.TLS = &idpv1alpha1.TLSSpec{
CertificateAuthorityData: goodServerIPv6CAB64,
}
return *otherSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseReady,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseReady,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validMinimalIDP.Spec.Client.SecretName),
@@ -663,7 +663,7 @@ func TestController(t *testing.T) {
otherIDP.Spec.Client.SecretName = "other-secret-name"
// No other test happens to that this particular value passes validation
otherIDP.Spec.Claims.Username = ptr.To(v1alpha1.GitHubUsernameLoginAndID)
otherIDP.Spec.Claims.Username = ptr.To(idpv1alpha1.GitHubUsernameLoginAndID)
return otherIDP
}(),
func() runtime.Object {
@@ -717,20 +717,20 @@ func TestController(t *testing.T) {
HttpClient: nil, // let the test runner populate this for us
},
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: func() metav1.ObjectMeta {
otherMeta := validFilledOutIDP.ObjectMeta.DeepCopy()
otherMeta.Name = "invalid-idp-name"
return *otherMeta
}(),
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
otherSpec := validFilledOutIDP.Spec.DeepCopy()
otherSpec.Client.SecretName = "no-secret-with-this-name"
return *otherSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidFalse(
@@ -753,14 +753,14 @@ func TestController(t *testing.T) {
otherMeta.Name = "other-idp-name"
return *otherMeta
}(),
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
otherSpec := validFilledOutIDP.Spec.DeepCopy()
otherSpec.Client.SecretName = "other-secret-name"
otherSpec.Claims.Username = ptr.To(v1alpha1.GitHubUsernameLoginAndID)
otherSpec.Claims.Username = ptr.To(idpv1alpha1.GitHubUsernameLoginAndID)
return *otherSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseReady,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseReady,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, "other-secret-name"),
@@ -774,8 +774,8 @@ func TestController(t *testing.T) {
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: validFilledOutIDP.Spec,
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseReady,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseReady,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -823,16 +823,16 @@ func TestController(t *testing.T) {
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.GitHubAPI.Host = nil
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -864,16 +864,16 @@ func TestController(t *testing.T) {
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validMinimalIDP.Spec.DeepCopy()
badSpec.GitHubAPI.Host = ptr.To("https://example.com")
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -905,16 +905,16 @@ func TestController(t *testing.T) {
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validMinimalIDP.Spec.DeepCopy()
badSpec.GitHubAPI.Host = ptr.To("example.com/foo")
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validMinimalIDP.Spec.Client.SecretName),
@@ -946,16 +946,16 @@ func TestController(t *testing.T) {
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validMinimalIDP.Spec.DeepCopy()
badSpec.GitHubAPI.Host = ptr.To("u:p@example.com")
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validMinimalIDP.Spec.Client.SecretName),
@@ -987,16 +987,16 @@ func TestController(t *testing.T) {
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validMinimalIDP.Spec.DeepCopy()
badSpec.GitHubAPI.Host = ptr.To("example.com?a=b")
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validMinimalIDP.Spec.Client.SecretName),
@@ -1028,16 +1028,16 @@ func TestController(t *testing.T) {
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validMinimalIDP.Spec.DeepCopy()
badSpec.GitHubAPI.Host = ptr.To("example.com#a")
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validMinimalIDP.Spec.Client.SecretName),
@@ -1065,24 +1065,24 @@ func TestController(t *testing.T) {
githubIdentityProviders: []runtime.Object{
func() runtime.Object {
badIDP := validFilledOutIDP.DeepCopy()
badIDP.Spec.GitHubAPI.TLS = &v1alpha1.TLSSpec{
badIDP.Spec.GitHubAPI.TLS = &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte("foo")),
}
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.GitHubAPI.TLS = &v1alpha1.TLSSpec{
badSpec.GitHubAPI.TLS = &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte("foo")),
}
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -1115,16 +1115,16 @@ func TestController(t *testing.T) {
}(),
},
wantErr: "dial tcp: lookup nowhere.bad-tld: no such host",
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validMinimalIDP.Spec.DeepCopy()
badSpec.GitHubAPI.Host = ptr.To("nowhere.bad-tld")
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validMinimalIDP.Spec.Client.SecretName),
@@ -1156,16 +1156,16 @@ func TestController(t *testing.T) {
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validMinimalIDP.Spec.DeepCopy()
badSpec.GitHubAPI.Host = ptr.To("0:0:0:0:0:0:0:1:9876")
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validMinimalIDP.Spec.Client.SecretName),
@@ -1198,16 +1198,16 @@ func TestController(t *testing.T) {
}(),
},
wantErr: "tls: failed to verify certificate: x509: certificate signed by unknown authority",
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.GitHubAPI.TLS = nil
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -1235,25 +1235,25 @@ func TestController(t *testing.T) {
githubIdentityProviders: []runtime.Object{
func() runtime.Object {
badIDP := validFilledOutIDP.DeepCopy()
badIDP.Spec.GitHubAPI.TLS = &v1alpha1.TLSSpec{
badIDP.Spec.GitHubAPI.TLS = &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(unknownServerCABytes),
}
return badIDP
}(),
},
wantErr: "tls: failed to verify certificate: x509: certificate signed by unknown authority",
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.GitHubAPI.TLS = &v1alpha1.TLSSpec{
badSpec.GitHubAPI.TLS = &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString(unknownServerCABytes),
}
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -1285,16 +1285,16 @@ func TestController(t *testing.T) {
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.AllowAuthentication.Organizations.Policy = nil
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -1322,20 +1322,20 @@ func TestController(t *testing.T) {
githubIdentityProviders: []runtime.Object{
func() runtime.Object {
badIDP := validFilledOutIDP.DeepCopy()
badIDP.Spec.AllowAuthentication.Organizations.Policy = ptr.To[v1alpha1.GitHubAllowedAuthOrganizationsPolicy]("a")
badIDP.Spec.AllowAuthentication.Organizations.Policy = ptr.To[idpv1alpha1.GitHubAllowedAuthOrganizationsPolicy]("a")
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.AllowAuthentication.Organizations.Policy = ptr.To[v1alpha1.GitHubAllowedAuthOrganizationsPolicy]("a")
badSpec.AllowAuthentication.Organizations.Policy = ptr.To[idpv1alpha1.GitHubAllowedAuthOrganizationsPolicy]("a")
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -1363,20 +1363,20 @@ func TestController(t *testing.T) {
githubIdentityProviders: []runtime.Object{
func() runtime.Object {
badIDP := validFilledOutIDP.DeepCopy()
badIDP.Spec.AllowAuthentication.Organizations.Policy = ptr.To(v1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers)
badIDP.Spec.AllowAuthentication.Organizations.Policy = ptr.To(idpv1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers)
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.AllowAuthentication.Organizations.Policy = ptr.To(v1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers)
badSpec.AllowAuthentication.Organizations.Policy = ptr.To(idpv1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers)
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -1408,16 +1408,16 @@ func TestController(t *testing.T) {
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.AllowAuthentication.Organizations.Allowed = nil
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -1449,16 +1449,16 @@ func TestController(t *testing.T) {
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.Claims.Username = nil
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedFalse(t, "spec.claims.username is required"),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -1486,20 +1486,20 @@ func TestController(t *testing.T) {
githubIdentityProviders: []runtime.Object{
func() runtime.Object {
badIDP := validFilledOutIDP.DeepCopy()
badIDP.Spec.Claims.Username = ptr.To[v1alpha1.GitHubUsernameAttribute]("a")
badIDP.Spec.Claims.Username = ptr.To[idpv1alpha1.GitHubUsernameAttribute]("a")
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.Claims.Username = ptr.To[v1alpha1.GitHubUsernameAttribute]("a")
badSpec.Claims.Username = ptr.To[idpv1alpha1.GitHubUsernameAttribute]("a")
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedFalse(t, `spec.claims.username ("a") is not valid`),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -1531,16 +1531,16 @@ func TestController(t *testing.T) {
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.Claims.Groups = nil
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedFalse(t, "spec.claims.groups is required"),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -1568,20 +1568,20 @@ func TestController(t *testing.T) {
githubIdentityProviders: []runtime.Object{
func() runtime.Object {
badIDP := validFilledOutIDP.DeepCopy()
badIDP.Spec.Claims.Groups = ptr.To[v1alpha1.GitHubGroupNameAttribute]("b")
badIDP.Spec.Claims.Groups = ptr.To[idpv1alpha1.GitHubGroupNameAttribute]("b")
return badIDP
}(),
},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validFilledOutIDP.ObjectMeta,
Spec: func() v1alpha1.GitHubIdentityProviderSpec {
Spec: func() idpv1alpha1.GitHubIdentityProviderSpec {
badSpec := validFilledOutIDP.Spec.DeepCopy()
badSpec.Claims.Groups = ptr.To[v1alpha1.GitHubGroupNameAttribute]("b")
badSpec.Claims.Groups = ptr.To[idpv1alpha1.GitHubGroupNameAttribute]("b")
return *badSpec
}(),
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedFalse(t, `spec.claims.groups ("b") is not valid`),
buildClientCredentialsSecretValidTrue(t, validFilledOutIDP.Spec.Client.SecretName),
@@ -1613,12 +1613,12 @@ func TestController(t *testing.T) {
}(),
},
githubIdentityProviders: []runtime.Object{validMinimalIDP},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: validMinimalIDP.Spec,
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidFalse(
@@ -1656,12 +1656,12 @@ func TestController(t *testing.T) {
}(),
},
githubIdentityProviders: []runtime.Object{validMinimalIDP},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: validMinimalIDP.Spec,
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidFalse(
@@ -1699,12 +1699,12 @@ func TestController(t *testing.T) {
}(),
},
githubIdentityProviders: []runtime.Object{validMinimalIDP},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: validMinimalIDP.Spec,
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidFalse(
@@ -1742,12 +1742,12 @@ func TestController(t *testing.T) {
}(),
},
githubIdentityProviders: []runtime.Object{validMinimalIDP},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: validMinimalIDP.Spec,
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidFalse(
@@ -1785,12 +1785,12 @@ func TestController(t *testing.T) {
}(),
},
githubIdentityProviders: []runtime.Object{validMinimalIDP},
wantResultingUpstreams: []v1alpha1.GitHubIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.GitHubIdentityProvider{
{
ObjectMeta: validMinimalIDP.ObjectMeta,
Spec: validMinimalIDP.Spec,
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
buildClaimsValidatedTrue(t),
buildClientCredentialsSecretValidFalse(
@@ -1825,7 +1825,7 @@ func TestController(t *testing.T) {
t.Parallel()
fakeSupervisorClient := supervisorfake.NewSimpleClientset(tt.githubIdentityProviders...)
supervisorInformers := pinnipedinformers.NewSharedInformerFactory(fakeSupervisorClient, 0)
supervisorInformers := supervisorinformers.NewSharedInformerFactory(fakeSupervisorClient, 0)
fakeKubeClient := kubernetesfake.NewSimpleClientset(tt.secrets...)
kubeInformers := k8sinformers.NewSharedInformerFactoryWithOptions(fakeKubeClient, 0)
@@ -1898,7 +1898,7 @@ func TestController(t *testing.T) {
require.Equal(t, tt.wantResultingCache[i].AllowedOrganizations, actualProvider.GetAllowedOrganizations())
require.GreaterOrEqual(t, len(tt.githubIdentityProviders), i+1, "there must be at least as many input identity providers as items in the cache")
githubIDP, ok := tt.githubIdentityProviders[i].(*v1alpha1.GitHubIdentityProvider)
githubIDP, ok := tt.githubIdentityProviders[i].(*idpv1alpha1.GitHubIdentityProvider)
require.True(t, ok)
certPool, _, err := pinnipedcontroller.BuildCertPoolIDP(githubIDP.Spec.GitHubAPI.TLS)
require.NoError(t, err)
@@ -1917,7 +1917,7 @@ func TestController(t *testing.T) {
require.Len(t, tt.wantResultingUpstreams[i].Status.Conditions, countExpectedConditions)
// Do not expect any particular order in the K8s objects
var actualIDP *v1alpha1.GitHubIdentityProvider
var actualIDP *idpv1alpha1.GitHubIdentityProvider
for _, possibleMatch := range allGitHubIDPs.Items {
if possibleMatch.GetName() == tt.wantResultingUpstreams[i].Name {
actualIDP = ptr.To(possibleMatch)
@@ -1977,65 +1977,65 @@ func TestController_OnlyWantActions(t *testing.T) {
},
}
validMinimalIDP := &v1alpha1.GitHubIdentityProvider{
validMinimalIDP := &idpv1alpha1.GitHubIdentityProvider{
ObjectMeta: metav1.ObjectMeta{
Name: "minimal-idp-name",
Namespace: namespace,
UID: types.UID("minimal-uid"),
Generation: 1234,
},
Spec: v1alpha1.GitHubIdentityProviderSpec{
GitHubAPI: v1alpha1.GitHubAPIConfig{
Spec: idpv1alpha1.GitHubIdentityProviderSpec{
GitHubAPI: idpv1alpha1.GitHubAPIConfig{
Host: ptr.To(goodServerDomain),
TLS: &v1alpha1.TLSSpec{
TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: goodServerCAB64,
},
},
// These claims are optional when using the actual Kubernetes CRD.
// However, they are required here because CRD defaulting/validation does not occur during testing.
Claims: v1alpha1.GitHubClaims{
Username: ptr.To(v1alpha1.GitHubUsernameLogin),
Groups: ptr.To(v1alpha1.GitHubUseTeamSlugForGroupName),
Claims: idpv1alpha1.GitHubClaims{
Username: ptr.To(idpv1alpha1.GitHubUsernameLogin),
Groups: ptr.To(idpv1alpha1.GitHubUseTeamSlugForGroupName),
},
Client: v1alpha1.GitHubClientSpec{
Client: idpv1alpha1.GitHubClientSpec{
SecretName: goodSecret.Name,
},
AllowAuthentication: v1alpha1.GitHubAllowAuthenticationSpec{
Organizations: v1alpha1.GitHubOrganizationsSpec{
Policy: ptr.To(v1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers),
AllowAuthentication: idpv1alpha1.GitHubAllowAuthenticationSpec{
Organizations: idpv1alpha1.GitHubOrganizationsSpec{
Policy: ptr.To(idpv1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers),
},
},
},
}
alreadyInvalidExistingIDP := &v1alpha1.GitHubIdentityProvider{
alreadyInvalidExistingIDP := &idpv1alpha1.GitHubIdentityProvider{
ObjectMeta: metav1.ObjectMeta{
Name: "already-existing-invalid-idp-name",
Namespace: namespace,
UID: types.UID("some-resource-uid"),
Generation: 333,
},
Spec: v1alpha1.GitHubIdentityProviderSpec{
GitHubAPI: v1alpha1.GitHubAPIConfig{
Spec: idpv1alpha1.GitHubIdentityProviderSpec{
GitHubAPI: idpv1alpha1.GitHubAPIConfig{
Host: ptr.To(goodServerDomain),
TLS: &v1alpha1.TLSSpec{
TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: goodServerCAB64,
},
},
AllowAuthentication: v1alpha1.GitHubAllowAuthenticationSpec{
Organizations: v1alpha1.GitHubOrganizationsSpec{
Policy: ptr.To(v1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers),
AllowAuthentication: idpv1alpha1.GitHubAllowAuthenticationSpec{
Organizations: idpv1alpha1.GitHubOrganizationsSpec{
Policy: ptr.To(idpv1alpha1.GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers),
},
},
Claims: v1alpha1.GitHubClaims{
Groups: ptr.To(v1alpha1.GitHubUseTeamSlugForGroupName),
Claims: idpv1alpha1.GitHubClaims{
Groups: ptr.To(idpv1alpha1.GitHubUseTeamSlugForGroupName),
},
Client: v1alpha1.GitHubClientSpec{
Client: idpv1alpha1.GitHubClientSpec{
SecretName: "unknown-secret",
},
},
Status: v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseError,
Status: idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseError,
Conditions: []metav1.Condition{
{
Type: ClaimsValid,
@@ -2114,7 +2114,7 @@ func TestController_OnlyWantActions(t *testing.T) {
func() runtime.Object {
otherIDP := alreadyInvalidExistingIDP.DeepCopy()
otherIDP.Generation = 400
otherIDP.Status.Phase = v1alpha1.GitHubPhaseReady
otherIDP.Status.Phase = idpv1alpha1.GitHubPhaseReady
otherIDP.Status.Conditions[0].Status = metav1.ConditionTrue
otherIDP.Status.Conditions[0].Message = "some other message indicating that things are good"
return otherIDP
@@ -2146,8 +2146,8 @@ func TestController_OnlyWantActions(t *testing.T) {
wantActions: []coretesting.Action{
coretesting.NewUpdateSubresourceAction(githubIDPGVR, "status", namespace, func() runtime.Object {
idpWithConditions := validMinimalIDP.DeepCopy()
idpWithConditions.Status = v1alpha1.GitHubIdentityProviderStatus{
Phase: v1alpha1.GitHubPhaseReady,
idpWithConditions.Status = idpv1alpha1.GitHubIdentityProviderStatus{
Phase: idpv1alpha1.GitHubPhaseReady,
Conditions: []metav1.Condition{
{
Type: ClaimsValid,
@@ -2210,7 +2210,7 @@ func TestController_OnlyWantActions(t *testing.T) {
t.Parallel()
fakeSupervisorClient := supervisorfake.NewSimpleClientset(tt.githubIdentityProviders...)
supervisorInformers := pinnipedinformers.NewSharedInformerFactory(supervisorfake.NewSimpleClientset(tt.githubIdentityProviders...), 0)
supervisorInformers := supervisorinformers.NewSharedInformerFactory(supervisorfake.NewSimpleClientset(tt.githubIdentityProviders...), 0)
if tt.addSupervisorReactors != nil {
tt.addSupervisorReactors(fakeSupervisorClient)
@@ -2335,7 +2335,7 @@ func TestGitHubUpstreamWatcherControllerFilterSecret(t *testing.T) {
namespace,
dynamicupstreamprovider.NewDynamicUpstreamIDPProvider(),
supervisorfake.NewSimpleClientset(),
pinnipedinformers.NewSharedInformerFactory(supervisorfake.NewSimpleClientset(), 0).IDP().V1alpha1().GitHubIdentityProviders(),
supervisorinformers.NewSharedInformerFactory(supervisorfake.NewSimpleClientset(), 0).IDP().V1alpha1().GitHubIdentityProviders(),
secretInformer,
logger,
observableInformers.WithInformer,
@@ -2355,7 +2355,7 @@ func TestGitHubUpstreamWatcherControllerFilterSecret(t *testing.T) {
func TestGitHubUpstreamWatcherControllerFilterGitHubIDP(t *testing.T) {
namespace := "some-namespace"
goodIDP := &v1alpha1.GitHubIdentityProvider{
goodIDP := &idpv1alpha1.GitHubIdentityProvider{
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
},
@@ -2397,7 +2397,7 @@ func TestGitHubUpstreamWatcherControllerFilterGitHubIDP(t *testing.T) {
var log bytes.Buffer
logger := plog.TestLogger(t, &log)
gitHubIdentityProviderInformer := pinnipedinformers.NewSharedInformerFactory(supervisorfake.NewSimpleClientset(), 0).IDP().V1alpha1().GitHubIdentityProviders()
gitHubIdentityProviderInformer := supervisorinformers.NewSharedInformerFactory(supervisorfake.NewSimpleClientset(), 0).IDP().V1alpha1().GitHubIdentityProviders()
observableInformers := testutil.NewObservableWithInformerOption()
_ = New(
@@ -2412,7 +2412,7 @@ func TestGitHubUpstreamWatcherControllerFilterGitHubIDP(t *testing.T) {
tls.Dial,
)
unrelated := &v1alpha1.GitHubIdentityProvider{}
unrelated := &idpv1alpha1.GitHubIdentityProvider{}
filter := observableInformers.GetFilterForInformer(gitHubIdentityProviderInformer)
require.Equal(t, tt.wantAdd, filter.Add(tt.idp))
require.Equal(t, tt.wantUpdate, filter.Update(unrelated, tt.idp))
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package supervisorconfig
@@ -17,9 +17,9 @@ import (
k8sinformers "k8s.io/client-go/informers"
kubernetesfake "k8s.io/client-go/kubernetes/fake"
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
supervisorinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/testutil"
)
@@ -37,7 +37,7 @@ func TestJWKSObserverControllerInformerFilters(t *testing.T) {
r = require.New(t)
observableWithInformerOption = testutil.NewObservableWithInformerOption()
secretsInformer := k8sinformers.NewSharedInformerFactory(nil, 0).Core().V1().Secrets()
federationDomainInformer := pinnipedinformers.NewSharedInformerFactory(nil, 0).Config().V1alpha1().FederationDomains()
federationDomainInformer := supervisorinformers.NewSharedInformerFactory(nil, 0).Config().V1alpha1().FederationDomains()
_ = NewJWKSObserverController(
nil,
secretsInformer,
@@ -82,13 +82,13 @@ func TestJWKSObserverControllerInformerFilters(t *testing.T) {
when("watching FederationDomain objects", func() {
var (
subject controllerlib.Filter
provider, otherProvider *v1alpha1.FederationDomain
provider, otherProvider *supervisorconfigv1alpha1.FederationDomain
)
it.Before(func() {
subject = federationDomainInformerFilter
provider = &v1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-name", Namespace: "any-namespace"}}
otherProvider = &v1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-other-name", Namespace: "any-other-namespace"}}
provider = &supervisorconfigv1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-name", Namespace: "any-namespace"}}
otherProvider = &supervisorconfigv1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-other-name", Namespace: "any-other-namespace"}}
})
when("any FederationDomain changes", func() {
@@ -125,9 +125,9 @@ func TestJWKSObserverControllerSync(t *testing.T) {
var (
r *require.Assertions
subject controllerlib.Controller
pinnipedInformerClient *pinnipedfake.Clientset
pinnipedInformerClient *supervisorfake.Clientset
kubeInformerClient *kubernetesfake.Clientset
pinnipedInformers pinnipedinformers.SharedInformerFactory
pinnipedInformers supervisorinformers.SharedInformerFactory
kubeInformers k8sinformers.SharedInformerFactory
cancelContext context.Context
cancelContextCancelFunc context.CancelFunc
@@ -169,8 +169,8 @@ func TestJWKSObserverControllerSync(t *testing.T) {
kubeInformerClient = kubernetesfake.NewSimpleClientset()
kubeInformers = k8sinformers.NewSharedInformerFactory(kubeInformerClient, 0)
pinnipedInformerClient = pinnipedfake.NewSimpleClientset()
pinnipedInformers = pinnipedinformers.NewSharedInformerFactory(pinnipedInformerClient, 0)
pinnipedInformerClient = supervisorfake.NewSimpleClientset()
pinnipedInformers = supervisorinformers.NewSharedInformerFactory(pinnipedInformerClient, 0)
issuerToJWKSSetter = &fakeIssuerToJWKSMapSetter{}
unrelatedSecret := &corev1.Secret{
@@ -204,78 +204,78 @@ func TestJWKSObserverControllerSync(t *testing.T) {
)
it.Before(func() {
federationDomainWithoutSecret1 := &v1alpha1.FederationDomain{
federationDomainWithoutSecret1 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "no-secret-federationdomain1",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer1.com"},
Status: v1alpha1.FederationDomainStatus{}, // no Secrets.JWKS field
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer1.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{}, // no Secrets.JWKS field
}
federationDomainWithoutSecret2 := &v1alpha1.FederationDomain{
federationDomainWithoutSecret2 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "no-secret-federationdomain2",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer2.com"},
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer2.com"},
// no Status field
}
federationDomainWithBadSecret := &v1alpha1.FederationDomain{
federationDomainWithBadSecret := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "bad-secret-federationdomain",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://bad-secret-issuer.com"},
Status: v1alpha1.FederationDomainStatus{
Secrets: v1alpha1.FederationDomainSecrets{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://bad-secret-issuer.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{
Secrets: supervisorconfigv1alpha1.FederationDomainSecrets{
JWKS: corev1.LocalObjectReference{Name: "bad-secret-name"},
},
},
}
federationDomainWithBadJWKSSecret := &v1alpha1.FederationDomain{
federationDomainWithBadJWKSSecret := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "bad-jwks-secret-federationdomain",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://bad-jwks-secret-issuer.com"},
Status: v1alpha1.FederationDomainStatus{
Secrets: v1alpha1.FederationDomainSecrets{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://bad-jwks-secret-issuer.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{
Secrets: supervisorconfigv1alpha1.FederationDomainSecrets{
JWKS: corev1.LocalObjectReference{Name: "bad-jwks-secret-name"},
},
},
}
federationDomainWithBadActiveJWKSecret := &v1alpha1.FederationDomain{
federationDomainWithBadActiveJWKSecret := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "bad-active-jwk-secret-federationdomain",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://bad-active-jwk-secret-issuer.com"},
Status: v1alpha1.FederationDomainStatus{
Secrets: v1alpha1.FederationDomainSecrets{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://bad-active-jwk-secret-issuer.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{
Secrets: supervisorconfigv1alpha1.FederationDomainSecrets{
JWKS: corev1.LocalObjectReference{Name: "bad-active-jwk-secret-name"},
},
},
}
federationDomainWithGoodSecret1 := &v1alpha1.FederationDomain{
federationDomainWithGoodSecret1 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "good-secret-federationdomain1",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://issuer-with-good-secret1.com"},
Status: v1alpha1.FederationDomainStatus{
Secrets: v1alpha1.FederationDomainSecrets{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://issuer-with-good-secret1.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{
Secrets: supervisorconfigv1alpha1.FederationDomainSecrets{
JWKS: corev1.LocalObjectReference{Name: "good-jwks-secret-name1"},
},
},
}
federationDomainWithGoodSecret2 := &v1alpha1.FederationDomain{
federationDomainWithGoodSecret2 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "good-secret-federationdomain2",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://issuer-with-good-secret2.com"},
Status: v1alpha1.FederationDomainStatus{
Secrets: v1alpha1.FederationDomainSecrets{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://issuer-with-good-secret2.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{
Secrets: supervisorconfigv1alpha1.FederationDomainSecrets{
JWKS: corev1.LocalObjectReference{Name: "good-jwks-secret-name2"},
},
},
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package supervisorconfig
@@ -14,7 +14,7 @@ import (
"github.com/go-jose/go-jose/v3"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
corev1informers "k8s.io/client-go/informers/core/v1"
@@ -22,7 +22,7 @@ import (
"k8s.io/client-go/util/retry"
"k8s.io/klog/v2"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
configinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/config/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
@@ -52,7 +52,7 @@ const (
// generateKey is stubbed out for the purpose of testing. The default behavior is to generate an EC key.
var generateKey = generateECKey //nolint:gochecknoglobals
func generateECKey(r io.Reader) (interface{}, error) {
func generateECKey(r io.Reader) (any, error) {
return ecdsa.GenerateKey(elliptic.P256(), r)
}
@@ -110,7 +110,7 @@ func NewJWKSWriterController(
// Sync implements controllerlib.Syncer.
func (c *jwksWriterController) Sync(ctx controllerlib.Context) error {
federationDomain, err := c.federationDomainInformer.Lister().FederationDomains(ctx.Key.Namespace).Get(ctx.Key.Name)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf(
"failed to get %s/%s FederationDomain: %w",
@@ -168,7 +168,7 @@ func (c *jwksWriterController) Sync(ctx controllerlib.Context) error {
return nil
}
func (c *jwksWriterController) secretNeedsUpdate(federationDomain *configv1alpha1.FederationDomain) (bool, error) {
func (c *jwksWriterController) secretNeedsUpdate(federationDomain *supervisorconfigv1alpha1.FederationDomain) (bool, error) {
if federationDomain.Status.Secrets.JWKS.Name == "" {
// If the FederationDomain says it doesn't have a secret associated with it, then let's create one.
return true, nil
@@ -176,7 +176,7 @@ func (c *jwksWriterController) secretNeedsUpdate(federationDomain *configv1alpha
// This FederationDomain says it has a secret associated with it. Let's try to get it from the cache.
secret, err := c.secretInformer.Lister().Secrets(federationDomain.Namespace).Get(federationDomain.Status.Secrets.JWKS.Name)
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if err != nil && !notFound {
return false, fmt.Errorf("cannot get secret: %w", err)
}
@@ -193,7 +193,7 @@ func (c *jwksWriterController) secretNeedsUpdate(federationDomain *configv1alpha
return false, nil
}
func (c *jwksWriterController) generateSecret(federationDomain *configv1alpha1.FederationDomain) (*corev1.Secret, error) {
func (c *jwksWriterController) generateSecret(federationDomain *supervisorconfigv1alpha1.FederationDomain) (*corev1.Secret, error) {
// Note! This is where we could potentially add more handling of FederationDomain spec fields which tell us how
// this FederationDomain should sign and verify ID tokens (e.g., hardcoded token secret, gRPC
// connection to KMS, etc).
@@ -231,8 +231,8 @@ func (c *jwksWriterController) generateSecret(federationDomain *configv1alpha1.F
Labels: c.jwksSecretLabels,
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(federationDomain, schema.GroupVersionKind{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Kind: federationDomainKind,
}),
},
@@ -254,7 +254,7 @@ func (c *jwksWriterController) createOrUpdateSecret(
secretClient := c.kubeClient.CoreV1().Secrets(newSecret.Namespace)
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
oldSecret, err := secretClient.Get(ctx, newSecret.Name, metav1.GetOptions{})
notFound := k8serrors.IsNotFound(err)
notFound := apierrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf("cannot get secret: %w", err)
}
@@ -284,7 +284,7 @@ func (c *jwksWriterController) createOrUpdateSecret(
func (c *jwksWriterController) updateFederationDomainStatus(
ctx context.Context,
newFederationDomain *configv1alpha1.FederationDomain,
newFederationDomain *supervisorconfigv1alpha1.FederationDomain,
) error {
federationDomainClient := c.pinnipedClient.ConfigV1alpha1().FederationDomains(newFederationDomain.Namespace)
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
@@ -22,9 +22,9 @@ import (
kubernetesfake "k8s.io/client-go/kubernetes/fake"
kubetesting "k8s.io/client-go/testing"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
supervisorinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/testutil"
)
@@ -71,7 +71,7 @@ func TestJWKSWriterControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Name: "some-name",
Controller: boolPtr(true),
},
@@ -87,7 +87,7 @@ func TestJWKSWriterControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
},
@@ -103,7 +103,7 @@ func TestJWKSWriterControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -127,7 +127,7 @@ func TestJWKSWriterControllerFilterSecret(t *testing.T) {
Kind: "UnrelatedKind",
},
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -148,7 +148,7 @@ func TestJWKSWriterControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -174,8 +174,8 @@ func TestJWKSWriterControllerFilterSecret(t *testing.T) {
kubernetesfake.NewSimpleClientset(),
0,
).Core().V1().Secrets()
federationDomainInformer := pinnipedinformers.NewSharedInformerFactory(
pinnipedfake.NewSimpleClientset(),
federationDomainInformer := supervisorinformers.NewSharedInformerFactory(
supervisorfake.NewSimpleClientset(),
0,
).Config().V1alpha1().FederationDomains()
withInformer := testutil.NewObservableWithInformerOption()
@@ -204,7 +204,7 @@ func TestJWKSWriterControllerFilterFederationDomain(t *testing.T) {
tests := []struct {
name string
federationDomain configv1alpha1.FederationDomain
federationDomain supervisorconfigv1alpha1.FederationDomain
wantAdd bool
wantUpdate bool
wantDelete bool
@@ -212,7 +212,7 @@ func TestJWKSWriterControllerFilterFederationDomain(t *testing.T) {
}{
{
name: "anything goes",
federationDomain: configv1alpha1.FederationDomain{},
federationDomain: supervisorconfigv1alpha1.FederationDomain{},
wantAdd: true,
wantUpdate: true,
wantDelete: true,
@@ -227,8 +227,8 @@ func TestJWKSWriterControllerFilterFederationDomain(t *testing.T) {
kubernetesfake.NewSimpleClientset(),
0,
).Core().V1().Secrets()
federationDomainInformer := pinnipedinformers.NewSharedInformerFactory(
pinnipedfake.NewSimpleClientset(),
federationDomainInformer := supervisorinformers.NewSharedInformerFactory(
supervisorfake.NewSimpleClientset(),
0,
).Config().V1alpha1().FederationDomains()
withInformer := testutil.NewObservableWithInformerOption()
@@ -241,7 +241,7 @@ func TestJWKSWriterControllerFilterFederationDomain(t *testing.T) {
withInformer.WithInformer,
)
unrelated := configv1alpha1.FederationDomain{}
unrelated := supervisorconfigv1alpha1.FederationDomain{}
filter := withInformer.GetFilterForInformer(federationDomainInformer)
require.Equal(t, test.wantAdd, filter.Add(test.federationDomain.DeepCopy()))
require.Equal(t, test.wantUpdate, filter.Update(&unrelated, test.federationDomain.DeepCopy()))
@@ -265,18 +265,18 @@ func TestJWKSWriterControllerSync(t *testing.T) {
require.NoError(t, err)
federationDomainGVR := schema.GroupVersionResource{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Resource: "federationdomains",
}
goodFederationDomain := &configv1alpha1.FederationDomain{
goodFederationDomain := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "good-federationDomain",
Namespace: namespace,
UID: "good-federationDomain-uid",
},
Spec: configv1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://some-issuer.com",
},
}
@@ -331,8 +331,8 @@ func TestJWKSWriterControllerSync(t *testing.T) {
key controllerlib.Key
secrets []*corev1.Secret
configKubeClient func(*kubernetesfake.Clientset)
configPinnipedClient func(*pinnipedfake.Clientset)
federationDomains []*configv1alpha1.FederationDomain
configPinnipedClient func(*supervisorfake.Clientset)
federationDomains []*supervisorconfigv1alpha1.FederationDomain
generateKeyErr error
wantGenerateKeyCount int
wantSecretActions []kubetesting.Action
@@ -342,7 +342,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "new federationDomain with no secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
wantGenerateKeyCount: 1,
@@ -358,7 +358,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "federationDomain without status with existing secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
secrets: []*corev1.Secret{
@@ -376,7 +376,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "existing federationDomain with no secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
wantGenerateKeyCount: 1,
@@ -391,7 +391,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "existing federationDomain with existing secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -406,7 +406,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "missing jwk in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -424,7 +424,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "missing jwks in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -442,7 +442,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "wrong type in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -460,7 +460,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "invalid jwk JSON in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -478,7 +478,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "invalid jwks JSON in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -496,7 +496,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "public jwk in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -514,7 +514,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "private jwks in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -532,7 +532,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "invalid jwk key in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -550,7 +550,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "invalid jwks key in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -568,7 +568,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "missing active jwks in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -586,7 +586,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "generate key fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
generateKeyErr: errors.New("some generate error"),
@@ -595,7 +595,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "get secret fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
configKubeClient: func(client *kubernetesfake.Clientset) {
@@ -608,7 +608,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "create secret fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
configKubeClient: func(client *kubernetesfake.Clientset) {
@@ -621,7 +621,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "update secret fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
secrets: []*corev1.Secret{
@@ -637,10 +637,10 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "get FederationDomain fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
configPinnipedClient: func(client *pinnipedfake.Clientset) {
configPinnipedClient: func(client *supervisorfake.Clientset) {
client.PrependReactor("get", "federationdomains", func(_ kubetesting.Action) (bool, runtime.Object, error) {
return true, nil, errors.New("some get error")
})
@@ -650,10 +650,10 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "update federationDomain fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
configPinnipedClient: func(client *pinnipedfake.Clientset) {
configPinnipedClient: func(client *supervisorfake.Clientset) {
client.PrependReactor("update", "federationdomains", func(_ kubetesting.Action) (bool, runtime.Object, error) {
return true, nil, errors.New("some update error")
})
@@ -665,7 +665,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
// We shouldn't run this test in parallel since it messes with a global function (generateKey).
generateKeyCount := 0
generateKey = func(_ io.Reader) (interface{}, error) {
generateKey = func(_ io.Reader) (any, error) {
generateKeyCount++
return goodKey, test.generateKeyErr
}
@@ -683,8 +683,8 @@ func TestJWKSWriterControllerSync(t *testing.T) {
test.configKubeClient(kubeAPIClient)
}
pinnipedAPIClient := pinnipedfake.NewSimpleClientset()
pinnipedInformerClient := pinnipedfake.NewSimpleClientset()
pinnipedAPIClient := supervisorfake.NewSimpleClientset()
pinnipedInformerClient := supervisorfake.NewSimpleClientset()
for _, federationDomain := range test.federationDomains {
require.NoError(t, pinnipedAPIClient.Tracker().Add(federationDomain))
require.NoError(t, pinnipedInformerClient.Tracker().Add(federationDomain))
@@ -697,7 +697,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
kubeInformerClient,
0,
)
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(
pinnipedInformers := supervisorinformers.NewSharedInformerFactory(
pinnipedInformerClient,
0,
)
@@ -13,7 +13,7 @@ import (
"k8s.io/apimachinery/pkg/labels"
corev1informers "k8s.io/client-go/informers/core/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
idpinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
@@ -30,7 +30,7 @@ const (
)
type ldapUpstreamGenericLDAPImpl struct {
ldapIdentityProvider v1alpha1.LDAPIdentityProvider
ldapIdentityProvider idpv1alpha1.LDAPIdentityProvider
}
func (g *ldapUpstreamGenericLDAPImpl) Spec() upstreamwatchers.UpstreamGenericLDAPSpec {
@@ -54,14 +54,14 @@ func (g *ldapUpstreamGenericLDAPImpl) Status() upstreamwatchers.UpstreamGenericL
}
type ldapUpstreamGenericLDAPSpec struct {
ldapIdentityProvider v1alpha1.LDAPIdentityProvider
ldapIdentityProvider idpv1alpha1.LDAPIdentityProvider
}
func (s *ldapUpstreamGenericLDAPSpec) Host() string {
return s.ldapIdentityProvider.Spec.Host
}
func (s *ldapUpstreamGenericLDAPSpec) TLSSpec() *v1alpha1.TLSSpec {
func (s *ldapUpstreamGenericLDAPSpec) TLSSpec() *idpv1alpha1.TLSSpec {
return s.ldapIdentityProvider.Spec.TLS
}
@@ -84,7 +84,7 @@ func (s *ldapUpstreamGenericLDAPSpec) DetectAndSetSearchBase(_ context.Context,
}
type ldapUpstreamGenericLDAPUserSearch struct {
userSearch v1alpha1.LDAPIdentityProviderUserSearch
userSearch idpv1alpha1.LDAPIdentityProviderUserSearch
}
func (u *ldapUpstreamGenericLDAPUserSearch) Base() string {
@@ -104,7 +104,7 @@ func (u *ldapUpstreamGenericLDAPUserSearch) UIDAttribute() string {
}
type ldapUpstreamGenericLDAPGroupSearch struct {
groupSearch v1alpha1.LDAPIdentityProviderGroupSearch
groupSearch idpv1alpha1.LDAPIdentityProviderGroupSearch
}
func (g *ldapUpstreamGenericLDAPGroupSearch) Base() string {
@@ -124,7 +124,7 @@ func (g *ldapUpstreamGenericLDAPGroupSearch) GroupNameAttribute() string {
}
type ldapUpstreamGenericLDAPStatus struct {
ldapIdentityProvider v1alpha1.LDAPIdentityProvider
ldapIdentityProvider idpv1alpha1.LDAPIdentityProvider
}
func (s *ldapUpstreamGenericLDAPStatus) Conditions() []metav1.Condition {
@@ -226,7 +226,7 @@ func (c *ldapWatcherController) Sync(ctx controllerlib.Context) error {
return nil
}
func (c *ldapWatcherController) validateUpstream(ctx context.Context, upstream *v1alpha1.LDAPIdentityProvider) (p upstreamprovider.UpstreamLDAPIdentityProviderI, requeue bool) {
func (c *ldapWatcherController) validateUpstream(ctx context.Context, upstream *idpv1alpha1.LDAPIdentityProvider) (p upstreamprovider.UpstreamLDAPIdentityProviderI, requeue bool) {
spec := upstream.Spec
config := &upstreamldap.ProviderConfig{
@@ -256,15 +256,15 @@ func (c *ldapWatcherController) validateUpstream(ctx context.Context, upstream *
return upstreamwatchers.EvaluateConditions(conditions, config)
}
func (c *ldapWatcherController) updateStatus(ctx context.Context, upstream *v1alpha1.LDAPIdentityProvider, conditions []*metav1.Condition) {
func (c *ldapWatcherController) updateStatus(ctx context.Context, upstream *idpv1alpha1.LDAPIdentityProvider, conditions []*metav1.Condition) {
log := plog.WithValues("namespace", upstream.Namespace, "name", upstream.Name)
updated := upstream.DeepCopy()
hadErrorCondition := conditionsutil.MergeConditions(conditions, upstream.Generation, &updated.Status.Conditions, log, metav1.Now())
updated.Status.Phase = v1alpha1.LDAPPhaseReady
updated.Status.Phase = idpv1alpha1.LDAPPhaseReady
if hadErrorCondition {
updated.Status.Phase = v1alpha1.LDAPPhaseError
updated.Status.Phase = idpv1alpha1.LDAPPhaseError
}
if equality.Semantic.DeepEqual(upstream, updated) {
@@ -21,9 +21,9 @@ import (
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
supervisorinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers"
"go.pinniped.dev/internal/controllerlib"
@@ -73,8 +73,8 @@ func TestLDAPUpstreamWatcherControllerFilterSecrets(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
fakePinnipedClient := pinnipedfake.NewSimpleClientset()
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakePinnipedClient := supervisorfake.NewSimpleClientset()
pinnipedInformers := supervisorinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
ldapIDPInformer := pinnipedInformers.IDP().V1alpha1().LDAPIdentityProviders()
fakeKubeClient := fake.NewSimpleClientset()
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
@@ -105,7 +105,7 @@ func TestLDAPUpstreamWatcherControllerFilterLDAPIdentityProviders(t *testing.T)
}{
{
name: "any LDAPIdentityProvider",
idp: &v1alpha1.LDAPIdentityProvider{
idp: &idpv1alpha1.LDAPIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Name: "some-name", Namespace: "some-namespace"},
},
wantAdd: true,
@@ -117,8 +117,8 @@ func TestLDAPUpstreamWatcherControllerFilterLDAPIdentityProviders(t *testing.T)
t.Run(test.name, func(t *testing.T) {
t.Parallel()
fakePinnipedClient := pinnipedfake.NewSimpleClientset()
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakePinnipedClient := supervisorfake.NewSimpleClientset()
pinnipedInformers := supervisorinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
ldapIDPInformer := pinnipedInformers.IDP().V1alpha1().LDAPIdentityProviders()
fakeKubeClient := fake.NewSimpleClientset()
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
@@ -175,37 +175,37 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
testCABundle := testCA.Bundle()
testCABundleBase64Encoded := base64.StdEncoding.EncodeToString(testCABundle)
validUpstream := &v1alpha1.LDAPIdentityProvider{
validUpstream := &idpv1alpha1.LDAPIdentityProvider{
ObjectMeta: metav1.ObjectMeta{
Name: testName,
Namespace: testNamespace,
Generation: 1234,
UID: testResourceUID,
},
Spec: v1alpha1.LDAPIdentityProviderSpec{
Spec: idpv1alpha1.LDAPIdentityProviderSpec{
Host: testHost,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testCABundleBase64Encoded},
Bind: v1alpha1.LDAPIdentityProviderBind{SecretName: testBindSecretName},
UserSearch: v1alpha1.LDAPIdentityProviderUserSearch{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testCABundleBase64Encoded},
Bind: idpv1alpha1.LDAPIdentityProviderBind{SecretName: testBindSecretName},
UserSearch: idpv1alpha1.LDAPIdentityProviderUserSearch{
Base: testUserSearchBase,
Filter: testUserSearchFilter,
Attributes: v1alpha1.LDAPIdentityProviderUserSearchAttributes{
Attributes: idpv1alpha1.LDAPIdentityProviderUserSearchAttributes{
Username: testUserSearchUsernameAttrName,
UID: testUserSearchUIDAttrName,
},
},
GroupSearch: v1alpha1.LDAPIdentityProviderGroupSearch{
GroupSearch: idpv1alpha1.LDAPIdentityProviderGroupSearch{
Base: testGroupSearchBase,
Filter: testGroupSearchFilter,
UserAttributeForFilter: testGroupSearchUserAttributeForFilter,
Attributes: v1alpha1.LDAPIdentityProviderGroupSearchAttributes{
Attributes: idpv1alpha1.LDAPIdentityProviderGroupSearchAttributes{
GroupName: testGroupSearchNameAttrName,
},
SkipGroupRefresh: false,
},
},
}
editedValidUpstream := func(editFunc func(*v1alpha1.LDAPIdentityProvider)) *v1alpha1.LDAPIdentityProvider {
editedValidUpstream := func(editFunc func(*idpv1alpha1.LDAPIdentityProvider)) *idpv1alpha1.LDAPIdentityProvider {
deepCopy := validUpstream.DeepCopy()
editFunc(deepCopy)
return deepCopy
@@ -303,7 +303,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
dialErrors map[string]error
wantErr string
wantResultingCache []*upstreamldap.ProviderConfig
wantResultingUpstreams []v1alpha1.LDAPIdentityProvider
wantResultingUpstreams []idpv1alpha1.LDAPIdentityProvider
wantValidatedSettings map[string]upstreamwatchers.ValidatedSettings
}{
{
@@ -320,9 +320,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -342,9 +342,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
inputSecrets: []runtime.Object{},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -370,9 +370,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
}},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -397,9 +397,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
}},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -417,15 +417,15 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "CertificateAuthorityData is not base64 encoded",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = "this-is-not-base64-encoded"
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -443,15 +443,15 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "CertificateAuthorityData is not valid pem data",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = base64.StdEncoding.EncodeToString([]byte("this is not pem data"))
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -469,7 +469,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "nil TLS configuration is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.TLS = nil
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -501,9 +501,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -530,7 +530,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when TLS connection fails it tries to use StartTLS instead: without a specified port it automatically switches ports",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.Host = "ldap.example.com" // when the port is not specified, automatically switch ports for StartTLS
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -566,9 +566,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -604,7 +604,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when TLS connection fails it tries to use StartTLS instead: with a specified port it does not automatically switch ports",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.Host = "ldap.example.com:5678" // when the port is specified, do not automatically switch ports for StartTLS
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -639,9 +639,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -663,7 +663,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "non-nil TLS configuration with empty CertificateAuthorityData is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -695,9 +695,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -713,7 +713,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "one valid upstream and one invalid upstream updates the cache to include only the valid upstream",
inputUpstreams: []runtime.Object{validUpstream, editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{validUpstream, editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Name = "other-upstream"
upstream.Generation = 42
upstream.Spec.Bind.SecretName = "non-existent-secret"
@@ -727,10 +727,10 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "other-upstream", Generation: 42, UID: "other-uid"},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -747,7 +747,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -774,9 +774,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -798,7 +798,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated using TLS for the current resource generation and secret version, then do not validate it again and keep using TLS",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
ldapConnectionValidTrueCondition(1234, "4242"),
@@ -817,9 +817,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -835,7 +835,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated using StartTLS for the current resource generation and secret version, then do not validate it again and keep using StartTLS",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
ldapConnectionValidTrueCondition(1234, "4242"),
@@ -854,9 +854,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithStartTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -872,7 +872,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was validated for an older resource generation, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234 // current generation
upstream.Status.Conditions = []metav1.Condition{
ldapConnectionValidTrueCondition(1233, "4242"), // older spec generation!
@@ -892,9 +892,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -910,7 +910,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection condition failed to update previously, then write the cached condition from the previous connection validation",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234 // current generation
upstream.Status.Conditions = []metav1.Condition{
ldapConnectionValidTrueCondition(1234, "4200"), // old version of the condition, as if the previous update of conditions had failed
@@ -930,9 +930,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"), // updated version of the condition using the cached condition value
},
@@ -948,7 +948,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection validation previously failed for this resource generation, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
{
@@ -968,9 +968,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -987,7 +987,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
{
name: "when the validated settings cache is incomplete, then try to validate it again",
// this shouldn't happen, but if it does, just throw it out and try again.
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
{
@@ -1011,9 +1011,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1029,7 +1029,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated for this resource generation but the bind secret has changed, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
ldapConnectionValidTrueCondition(1234, "4241"), // same spec generation, old secret version
@@ -1049,9 +1049,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1066,7 +1066,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
}}},
{
name: "skipping group refresh is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.GroupSearch.SkipGroupRefresh = true
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1099,9 +1099,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1132,8 +1132,8 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
fakePinnipedClient := pinnipedfake.NewSimpleClientset(tt.inputUpstreams...)
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakePinnipedClient := supervisorfake.NewSimpleClientset(tt.inputUpstreams...)
pinnipedInformers := supervisorinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakeKubeClient := fake.NewSimpleClientset(tt.inputSecrets...)
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
cache := dynamicupstreamprovider.NewDynamicUpstreamIDPProvider()
@@ -1226,13 +1226,13 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
}
}
func normalizeLDAPUpstreams(upstreams []v1alpha1.LDAPIdentityProvider, now metav1.Time) []v1alpha1.LDAPIdentityProvider {
result := make([]v1alpha1.LDAPIdentityProvider, 0, len(upstreams))
func normalizeLDAPUpstreams(upstreams []idpv1alpha1.LDAPIdentityProvider, now metav1.Time) []idpv1alpha1.LDAPIdentityProvider {
result := make([]idpv1alpha1.LDAPIdentityProvider, 0, len(upstreams))
for _, u := range upstreams {
normalized := u.DeepCopy()
// We're only interested in comparing the status, so zero out the spec.
normalized.Spec = v1alpha1.LDAPIdentityProviderSpec{}
normalized.Spec = idpv1alpha1.LDAPIdentityProviderSpec{}
// Round down the LastTransitionTime values to `now` if they were just updated. This makes
// it much easier to encode assertions about the expected timestamps.
@@ -9,12 +9,12 @@ import (
"strings"
"k8s.io/apimachinery/pkg/api/equality"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
corev1informers "k8s.io/client-go/informers/core/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
configInformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/config/v1alpha1"
@@ -94,7 +94,7 @@ func (c *oidcClientWatcherController) Sync(ctx controllerlib.Context) error {
secret, err := c.secretInformer.Lister().Secrets(oidcClient.Namespace).Get(correspondingSecretName)
if err != nil {
if !k8serrors.IsNotFound(err) {
if !apierrors.IsNotFound(err) {
// Anything other than a NotFound error is unexpected when reading from an informer.
return fmt.Errorf("failed to get %s/%s secret: %w", oidcClient.Namespace, correspondingSecretName, err)
}
@@ -127,7 +127,7 @@ func (c *oidcClientWatcherController) Sync(ctx controllerlib.Context) error {
func (c *oidcClientWatcherController) updateStatus(
ctx context.Context,
upstream *v1alpha1.OIDCClient,
upstream *supervisorconfigv1alpha1.OIDCClient,
conditions []*metav1.Condition,
totalClientSecrets int,
) error {
@@ -136,9 +136,9 @@ func (c *oidcClientWatcherController) updateStatus(
hadErrorCondition := conditionsutil.MergeConditions(conditions,
upstream.Generation, &updated.Status.Conditions, plog.New(), metav1.Now())
updated.Status.Phase = v1alpha1.OIDCClientPhaseReady
updated.Status.Phase = supervisorconfigv1alpha1.OIDCClientPhaseReady
if hadErrorCondition {
updated.Status.Phase = v1alpha1.OIDCClientPhaseError
updated.Status.Phase = supervisorconfigv1alpha1.OIDCClientPhaseError
}
updated.Status.TotalClientSecrets = int32(totalClientSecrets)
@@ -16,9 +16,9 @@ import (
k8sinformers "k8s.io/client-go/informers"
kubernetesfake "k8s.io/client-go/kubernetes/fake"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
supervisorinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/testutil"
)
@@ -66,8 +66,8 @@ func TestOIDCClientWatcherControllerFilterSecret(t *testing.T) {
kubernetesfake.NewSimpleClientset(),
0,
).Core().V1().Secrets()
oidcClientsInformer := pinnipedinformers.NewSharedInformerFactory(
pinnipedfake.NewSimpleClientset(),
oidcClientsInformer := supervisorinformers.NewSharedInformerFactory(
supervisorfake.NewSimpleClientset(),
0,
).Config().V1alpha1().OIDCClients()
withInformer := testutil.NewObservableWithInformerOption()
@@ -93,14 +93,14 @@ func TestOIDCClientWatcherControllerFilterOIDCClient(t *testing.T) {
tests := []struct {
name string
oidcClient configv1alpha1.OIDCClient
oidcClient supervisorconfigv1alpha1.OIDCClient
wantAdd bool
wantUpdate bool
wantDelete bool
}{
{
name: "name has client.oauth.pinniped.dev- prefix",
oidcClient: configv1alpha1.OIDCClient{
oidcClient: supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Name: "client.oauth.pinniped.dev-foo"},
},
wantAdd: true,
@@ -109,7 +109,7 @@ func TestOIDCClientWatcherControllerFilterOIDCClient(t *testing.T) {
},
{
name: "name does not have client.oauth.pinniped.dev- prefix",
oidcClient: configv1alpha1.OIDCClient{
oidcClient: supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Name: "something.oauth.pinniped.dev-foo"},
},
wantAdd: false,
@@ -118,7 +118,7 @@ func TestOIDCClientWatcherControllerFilterOIDCClient(t *testing.T) {
},
{
name: "other names without any particular pinniped.dev prefixes",
oidcClient: configv1alpha1.OIDCClient{
oidcClient: supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Name: "something"},
},
wantAdd: false,
@@ -135,8 +135,8 @@ func TestOIDCClientWatcherControllerFilterOIDCClient(t *testing.T) {
kubernetesfake.NewSimpleClientset(),
0,
).Core().V1().Secrets()
oidcClientsInformer := pinnipedinformers.NewSharedInformerFactory(
pinnipedfake.NewSimpleClientset(),
oidcClientsInformer := supervisorinformers.NewSharedInformerFactory(
supervisorfake.NewSimpleClientset(),
0,
).Config().V1alpha1().OIDCClients()
withInformer := testutil.NewObservableWithInformerOption()
@@ -147,7 +147,7 @@ func TestOIDCClientWatcherControllerFilterOIDCClient(t *testing.T) {
withInformer.WithInformer,
)
unrelated := configv1alpha1.OIDCClient{}
unrelated := supervisorconfigv1alpha1.OIDCClient{}
filter := withInformer.GetFilterForInformer(oidcClientsInformer)
require.Equal(t, tt.wantAdd, filter.Add(&tt.oidcClient))
require.Equal(t, tt.wantUpdate, filter.Update(&unrelated, &tt.oidcClient))
@@ -251,7 +251,7 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
inputObjects []runtime.Object
inputSecrets []runtime.Object
wantErr string
wantResultingOIDCClients []configv1alpha1.OIDCClient
wantResultingOIDCClients []supervisorconfigv1alpha1.OIDCClient
wantAPIActions int
}{
{
@@ -260,37 +260,37 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "OIDCClient with wrong prefix is ignored",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "wrong-prefix-name", Generation: 1234, UID: testUID},
}},
wantAPIActions: 0, // no updates
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "wrong-prefix-name", Generation: 1234, UID: testUID},
}},
},
{
name: "successfully validate minimal OIDCClient and one client secret stored (while ignoring client with wrong prefix)",
inputObjects: []runtime.Object{
&configv1alpha1.OIDCClient{
&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "wrong-prefix-name", Generation: 1234, UID: testUID},
},
&configv1alpha1.OIDCClient{
&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
},
},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "wrong-prefix-name", Generation: 1234, UID: testUID},
},
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -304,18 +304,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate minimal OIDCClient and two client secrets stored",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost, testutil.HashedPassword2AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -328,13 +328,13 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "an already validated OIDCClient does not have its conditions updated when everything is still valid",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(earlier, 1234),
@@ -346,9 +346,9 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 0, // no updates
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(earlier, 1234),
@@ -361,14 +361,14 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "missing required minimum settings and missing client secret storage",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{},
}},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 1234, `"authorization_code" must always be included in "allowedGrantTypes"`),
@@ -380,18 +380,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "client secret storage exists but cannot be read",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUIDWithWrongVersion(t, testNamespace, testUID)},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -403,18 +403,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "client secret storage exists but does not contain any client secrets",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -427,11 +427,11 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "client secret storage exists but some of the client secrets are invalid bcrypt hashes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{
@@ -439,9 +439,9 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
[]string{testutil.HashedPassword1AtSupervisorMinCost, testutil.HashedPassword1JustBelowSupervisorMinCost, testutil.HashedPassword1InvalidFormat}),
},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -458,24 +458,24 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
{
name: "can operate on multiple at a time, e.g. one is valid one another is missing required minimum settings",
inputObjects: []runtime.Object{
&configv1alpha1.OIDCClient{
&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "client.oauth.pinniped.dev-test1", Generation: 1234, UID: "uid1"},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
},
&configv1alpha1.OIDCClient{
&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "client.oauth.pinniped.dev-test2", Generation: 4567, UID: "uid2"},
Spec: configv1alpha1.OIDCClientSpec{},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{},
},
},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, "uid1", []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 2, // one update for each OIDCClient
wantResultingOIDCClients: []configv1alpha1.OIDCClient{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "client.oauth.pinniped.dev-test1", Generation: 1234, UID: "uid1"},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -487,7 +487,7 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "client.oauth.pinniped.dev-test2", Generation: 4567, UID: "uid2"},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 4567, `"authorization_code" must always be included in "allowedGrantTypes"`),
@@ -501,14 +501,14 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "a previously invalid OIDCClient has its spec changed to become valid so the conditions are updated",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 4567, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
// was invalid on previous run of controller which observed an old generation at an earlier time
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(earlier, 1234, `"authorization_code" must always be included in "allowedGrantTypes"`),
@@ -520,10 +520,10 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 4567, UID: testUID},
// status was updated to reflect the current generation at the current time
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 4567),
@@ -536,18 +536,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "refresh_token must be included in allowedGrantTypes when offline_access is included in allowedScopes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access"},
},
}},
wantAPIActions: 1, // one update
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 1234, `"refresh_token" must be included in "allowedGrantTypes" when "offline_access" is included in "allowedScopes"`),
@@ -560,18 +560,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "multiple errors on allowedScopes and allowedGrantTypes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"pinniped:request-audience"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"pinniped:request-audience"},
},
}},
wantAPIActions: 1, // one update
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 1234,
@@ -589,18 +589,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "another combination of multiple errors on allowedScopes and allowedGrantTypes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []configv1alpha1.Scope{"offline_access"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"offline_access"},
},
}},
wantAPIActions: 1, // one update
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 1234,
@@ -617,18 +617,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "urn:ietf:params:oauth:grant-type:token-exchange must be included in allowedGrantTypes when pinniped:request-audience is included in allowedScopes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid", "pinniped:request-audience", "username", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "pinniped:request-audience", "username", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 1234, `"urn:ietf:params:oauth:grant-type:token-exchange" must be included in "allowedGrantTypes" when "pinniped:request-audience" is included in "allowedScopes"`),
@@ -641,18 +641,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "offline_access must be included in allowedScopes when refresh_token is included in allowedGrantTypes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -665,18 +665,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "username and groups must also be included in allowedScopes when pinniped:request-audience is included in allowedScopes: both missing",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []configv1alpha1.Scope{"openid", "pinniped:request-audience"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "pinniped:request-audience"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -689,18 +689,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "username and groups must also be included in allowedScopes when pinniped:request-audience is included in allowedScopes: username missing",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []configv1alpha1.Scope{"openid", "pinniped:request-audience", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "pinniped:request-audience", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -713,18 +713,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "username and groups must also be included in allowedScopes when pinniped:request-audience is included in allowedScopes: groups missing",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []configv1alpha1.Scope{"openid", "pinniped:request-audience", "username"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "pinniped:request-audience", "username"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -737,18 +737,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "pinniped:request-audience must be included in allowedScopes when urn:ietf:params:oauth:grant-type:token-exchange is included in allowedGrantTypes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -761,18 +761,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient with all allowedGrantTypes and all allowedScopes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -785,18 +785,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient for offline access without kube API access without username/groups",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -809,18 +809,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient for offline access without kube API access with username",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "username"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -833,18 +833,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient for offline access without kube API access with groups",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -857,18 +857,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient for offline access without kube API access with both username and groups",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "username", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -881,18 +881,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient without offline access without kube API access with username",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid", "username"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "username"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -905,18 +905,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient without offline access without kube API access with groups",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid", "username"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "username"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -929,18 +929,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient without offline access without kube API access with both username and groups",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid", "username", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "username", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -956,9 +956,9 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
fakePinnipedClient := pinnipedfake.NewSimpleClientset(tt.inputObjects...)
fakePinnipedClientForInformers := pinnipedfake.NewSimpleClientset(tt.inputObjects...)
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClientForInformers, 0)
fakePinnipedClient := supervisorfake.NewSimpleClientset(tt.inputObjects...)
fakePinnipedClientForInformers := supervisorfake.NewSimpleClientset(tt.inputObjects...)
pinnipedInformers := supervisorinformers.NewSharedInformerFactory(fakePinnipedClientForInformers, 0)
fakeKubeClient := kubernetesfake.NewSimpleClientset(tt.inputSecrets...)
kubeInformers := k8sinformers.NewSharedInformerFactoryWithOptions(fakeKubeClient, 0)
@@ -995,13 +995,13 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
}
}
func normalizeOIDCClients(oidcClients []configv1alpha1.OIDCClient, now metav1.Time) []configv1alpha1.OIDCClient {
result := make([]configv1alpha1.OIDCClient, 0, len(oidcClients))
func normalizeOIDCClients(oidcClients []supervisorconfigv1alpha1.OIDCClient, now metav1.Time) []supervisorconfigv1alpha1.OIDCClient {
result := make([]supervisorconfigv1alpha1.OIDCClient, 0, len(oidcClients))
for _, u := range oidcClients {
normalized := u.DeepCopy()
// We're only interested in comparing the status, so zero out the spec.
normalized.Spec = configv1alpha1.OIDCClientSpec{}
normalized.Spec = supervisorconfigv1alpha1.OIDCClientSpec{}
// Round down the LastTransitionTime values to `now` if they were just updated. This makes
// it much easier to encode assertions about the expected timestamps.
@@ -25,7 +25,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
corev1informers "k8s.io/client-go/informers/core/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
idpinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1"
@@ -102,7 +102,7 @@ type lruValidatorCacheEntry struct {
client *http.Client
}
func (c *lruValidatorCache) getProvider(spec *v1alpha1.OIDCIdentityProviderSpec) (*coreosoidc.Provider, *http.Client) {
func (c *lruValidatorCache) getProvider(spec *idpv1alpha1.OIDCIdentityProviderSpec) (*coreosoidc.Provider, *http.Client) {
if result, ok := c.cache.Get(c.cacheKey(spec)); ok {
entry := result.(*lruValidatorCacheEntry)
return entry.provider, entry.client
@@ -110,11 +110,11 @@ func (c *lruValidatorCache) getProvider(spec *v1alpha1.OIDCIdentityProviderSpec)
return nil, nil
}
func (c *lruValidatorCache) putProvider(spec *v1alpha1.OIDCIdentityProviderSpec, provider *coreosoidc.Provider, client *http.Client) {
func (c *lruValidatorCache) putProvider(spec *idpv1alpha1.OIDCIdentityProviderSpec, provider *coreosoidc.Provider, client *http.Client) {
c.cache.Set(c.cacheKey(spec), &lruValidatorCacheEntry{provider: provider, client: client}, oidcValidatorCacheTTL)
}
func (c *lruValidatorCache) cacheKey(spec *v1alpha1.OIDCIdentityProviderSpec) interface{} {
func (c *lruValidatorCache) cacheKey(spec *idpv1alpha1.OIDCIdentityProviderSpec) any {
var key struct{ issuer, caBundle string }
key.issuer = spec.Issuer
if spec.TLS != nil {
@@ -130,8 +130,8 @@ type oidcWatcherController struct {
oidcIdentityProviderInformer idpinformers.OIDCIdentityProviderInformer
secretInformer corev1informers.SecretInformer
validatorCache interface {
getProvider(*v1alpha1.OIDCIdentityProviderSpec) (*coreosoidc.Provider, *http.Client)
putProvider(*v1alpha1.OIDCIdentityProviderSpec, *coreosoidc.Provider, *http.Client)
getProvider(*idpv1alpha1.OIDCIdentityProviderSpec) (*coreosoidc.Provider, *http.Client)
putProvider(*idpv1alpha1.OIDCIdentityProviderSpec, *coreosoidc.Provider, *http.Client)
}
}
@@ -191,9 +191,9 @@ func (c *oidcWatcherController) Sync(ctx controllerlib.Context) error {
return nil
}
// validateUpstream validates the provided v1alpha1.OIDCIdentityProvider and returns the validated configuration as a
// provider.UpstreamOIDCIdentityProvider. As a side effect, it also updates the status of the v1alpha1.OIDCIdentityProvider.
func (c *oidcWatcherController) validateUpstream(ctx controllerlib.Context, upstream *v1alpha1.OIDCIdentityProvider) *upstreamoidc.ProviderConfig {
// validateUpstream validates the provided idpv1alpha1.OIDCIdentityProvider and returns the validated configuration as a
// provider.UpstreamOIDCIdentityProvider. As a side effect, it also updates the status of the idpv1alpha1.OIDCIdentityProvider.
func (c *oidcWatcherController) validateUpstream(ctx controllerlib.Context, upstream *idpv1alpha1.OIDCIdentityProvider) *upstreamoidc.ProviderConfig {
authorizationConfig := upstream.Spec.AuthorizationConfig
additionalAuthcodeAuthorizeParameters := map[string]string{}
@@ -261,7 +261,7 @@ func (c *oidcWatcherController) validateUpstream(ctx controllerlib.Context, upst
}
// validateSecret validates the .spec.client.secretName field and returns the appropriate ClientCredentialsSecretValid condition.
func (c *oidcWatcherController) validateSecret(upstream *v1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *metav1.Condition {
func (c *oidcWatcherController) validateSecret(upstream *idpv1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *metav1.Condition {
secretName := upstream.Spec.Client.SecretName
// Fetch the Secret from informer cache.
@@ -309,7 +309,7 @@ func (c *oidcWatcherController) validateSecret(upstream *v1alpha1.OIDCIdentityPr
}
// validateIssuer validates the .spec.issuer field, performs OIDC discovery, and returns the appropriate OIDCDiscoverySucceeded condition.
func (c *oidcWatcherController) validateIssuer(ctx context.Context, upstream *v1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *metav1.Condition {
func (c *oidcWatcherController) validateIssuer(ctx context.Context, upstream *idpv1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *metav1.Condition {
// Get the provider and HTTP Client from cache if possible.
discoveredProvider, httpClient := c.validatorCache.getProvider(&upstream.Spec)
@@ -408,15 +408,15 @@ func (c *oidcWatcherController) validateIssuer(ctx context.Context, upstream *v1
}
}
func (c *oidcWatcherController) updateStatus(ctx context.Context, upstream *v1alpha1.OIDCIdentityProvider, conditions []*metav1.Condition) {
func (c *oidcWatcherController) updateStatus(ctx context.Context, upstream *idpv1alpha1.OIDCIdentityProvider, conditions []*metav1.Condition) {
log := c.log.WithValues("namespace", upstream.Namespace, "name", upstream.Name)
updated := upstream.DeepCopy()
hadErrorCondition := conditionsutil.MergeConditions(conditions, upstream.Generation, &updated.Status.Conditions, log, metav1.Now())
updated.Status.Phase = v1alpha1.PhaseReady
updated.Status.Phase = idpv1alpha1.PhaseReady
if hadErrorCondition {
updated.Status.Phase = v1alpha1.PhaseError
updated.Status.Phase = idpv1alpha1.PhaseError
}
if equality.Semantic.DeepEqual(upstream, updated) {
@@ -432,7 +432,7 @@ func (c *oidcWatcherController) updateStatus(ctx context.Context, upstream *v1al
}
}
func getClient(upstream *v1alpha1.OIDCIdentityProvider) (*http.Client, error) {
func getClient(upstream *idpv1alpha1.OIDCIdentityProvider) (*http.Client, error) {
if upstream.Spec.TLS == nil || upstream.Spec.TLS.CertificateAuthorityData == "" {
return defaultClientShortTimeout(nil), nil
}
@@ -23,9 +23,9 @@ import (
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
supervisorinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/federationdomain/dynamicupstreamprovider"
@@ -76,8 +76,8 @@ func TestOIDCUpstreamWatcherControllerFilterSecret(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
fakePinnipedClient := pinnipedfake.NewSimpleClientset()
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakePinnipedClient := supervisorfake.NewSimpleClientset()
pinnipedInformers := supervisorinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakeKubeClient := fake.NewSimpleClientset()
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
cache := dynamicupstreamprovider.NewDynamicUpstreamIDPProvider()
@@ -140,7 +140,7 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
testAdditionalScopes = []string{"scope1", "scope2", "scope3"}
testExpectedScopes = []string{"openid", "scope1", "scope2", "scope3"}
testDefaultExpectedScopes = []string{"openid", "offline_access", "email", "profile"}
testAdditionalParams = []v1alpha1.Parameter{{Name: "prompt", Value: "consent"}, {Name: "foo", Value: "bar"}}
testAdditionalParams = []idpv1alpha1.Parameter{{Name: "prompt", Value: "consent"}, {Name: "foo", Value: "bar"}}
testExpectedAdditionalParams = map[string]string{"prompt": "consent", "foo": "bar"}
testClientID = "test-oidc-client-id"
testClientSecret = "test-oidc-client-secret"
@@ -156,19 +156,19 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
wantErr string
wantLogs []string
wantResultingCache []*oidctestutil.TestUpstreamOIDCIdentityProvider
wantResultingUpstreams []v1alpha1.OIDCIdentityProvider
wantResultingUpstreams []idpv1alpha1.OIDCIdentityProvider
}{
{
name: "no upstreams",
},
{
name: "missing secret",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{},
@@ -180,9 +180,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="secret \"test-client-secret\" not found" "name"="test-name" "namespace"="test-namespace" "reason"="SecretNotFound" "type"="ClientCredentialsSecretValid"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -206,12 +206,12 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "secret has wrong type",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -227,9 +227,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="referenced Secret \"test-client-secret\" has wrong type \"some-other-type\" (should be \"secrets.pinniped.dev/oidc-client\")" "name"="test-name" "namespace"="test-namespace" "reason"="SecretWrongType" "type"="ClientCredentialsSecretValid"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -253,12 +253,12 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "secret is missing key",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -273,9 +273,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="referenced Secret \"test-client-secret\" is missing required keys [\"clientID\" \"clientSecret\"]" "name"="test-name" "namespace"="test-namespace" "reason"="SecretMissingKeys" "type"="ClientCredentialsSecretValid"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -299,14 +299,14 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "TLS CA bundle is invalid base64",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "test-name"},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{
TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: "invalid-base64",
},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -322,9 +322,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="spec.certificateAuthorityData is invalid: illegal base64 data at input byte 7" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -348,14 +348,14 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "TLS CA bundle does not have any certificates",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "test-name"},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{
TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte("not-a-pem-ca-bundle")),
},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -371,9 +371,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="spec.certificateAuthorityData is invalid: no certificates found" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -397,11 +397,11 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "issuer is invalid URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: "%invalid-url-that-is-really-really-long-nanananananananannanananan-batman-nanananananananananananananana-batman-lalalalalalalalalal-batman-weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -417,9 +417,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to parse issuer URL: parse \"%invalid-url-that-is-really-really-long-nanananananananannanananan-batman-nanananananananananananananana-batman-lalalalalalalalalal-batman-weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": invalid URL escape \"%in\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -443,11 +443,11 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "issuer is insecure http URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: strings.Replace(testIssuerURL, "https", "http", 1),
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -463,9 +463,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="issuer URL '` + strings.Replace(testIssuerURL, "https", "http", 1) + `' must have \"https\" scheme, not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -489,11 +489,11 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "issuer contains a query param",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "?sub=foo",
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -509,9 +509,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="issuer URL '` + testIssuerURL + "?sub=foo" + `' cannot contain query or fragment component" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -535,11 +535,11 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "issuer contains a fragment",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "#fragment",
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -555,9 +555,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="issuer URL '` + testIssuerURL + "#fragment" + `' cannot contain query or fragment component" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -581,12 +581,12 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "really long issuer with invalid CA bundle",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/valid-url-that-is-really-really-long-nanananananananannanananan-batman-nanananananananananananananana-batman-lalalalalalalalalal-batman-weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: wrongCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: wrongCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -603,9 +603,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/valid-url-that-is-really-really-long-nanananananananannanananan-batman-nanananananananananananananana-batman-lalalalalalalalalal-batman-weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\":\nGet \"` + testIssuerURL + `/valid-url-that-is-really-really-long-nanananananananannanananan-batman-nanananananananananananananana-batman-lalalalalalalalalal-batman-weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee/.well-known/openid-configuration\": tls: failed to verify certificate: x509: certificate signed by unknown authority" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -630,12 +630,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns invalid authorize URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/invalid",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -651,9 +651,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to parse authorization endpoint URL: parse \"%\": invalid URL escape \"%\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -677,12 +677,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns invalid revocation URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/invalid-revocation-url",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -698,9 +698,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to parse revocation endpoint URL: parse \"%\": invalid URL escape \"%\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -724,12 +724,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns insecure authorize URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/insecure",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -745,9 +745,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="authorization endpoint URL 'http://example.com/authorize' must have \"https\" scheme, not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -771,12 +771,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns insecure revocation URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/insecure-revocation-url",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -792,9 +792,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="revocation endpoint URL 'http://example.com/revoke' must have \"https\" scheme, not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -818,12 +818,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns insecure token URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/insecure-token-url",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -839,9 +839,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="token endpoint URL 'http://example.com/token' must have \"https\" scheme, not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -865,12 +865,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns no token URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/missing-token-url",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -886,9 +886,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="token endpoint URL '' must have \"https\" scheme, not \"\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -912,12 +912,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns no auth URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/missing-auth-url",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -933,9 +933,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="authorization endpoint URL '' must have \"https\" scheme, not \"\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -959,19 +959,19 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "upstream with error becomes valid",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "test-name", UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: idpv1alpha1.OIDCAuthorizationConfig{
AdditionalScopes: append(testAdditionalScopes, "xyz", "openid"), // adds openid unnecessarily
AllowPasswordGrant: true,
},
Claims: v1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
Claims: idpv1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{Type: "ClientCredentialsSecretValid", Status: "False", LastTransitionTime: earlier, Reason: "SomeError1", Message: "some previous error 1"},
@@ -1004,9 +1004,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
ResourceUID: testUID,
},
},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -1018,15 +1018,15 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "existing valid upstream with default authorizationConfig",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Claims: v1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
Claims: idpv1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidConditionEarlier,
@@ -1060,9 +1060,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
ResourceUID: testUID,
},
},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
{Type: "AdditionalAuthorizeParametersValid", Status: "True", LastTransitionTime: earlier, Reason: "Success", Message: "additionalAuthorizeParameters parameter names are allowed", ObservedGeneration: 1234},
@@ -1074,15 +1074,15 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "existing valid upstream with no revocation endpoint in the discovery document",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/valid-without-revocation",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Claims: v1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
Claims: idpv1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidConditionEarlier,
@@ -1116,9 +1116,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
ResourceUID: testUID,
},
},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
{Type: "AdditionalAuthorizeParametersValid", Status: "True", LastTransitionTime: earlier, Reason: "Success", Message: "additionalAuthorizeParameters parameter names are allowed", ObservedGeneration: 1234},
@@ -1130,18 +1130,18 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "existing valid upstream with additionalScopes set to override the default",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Claims: v1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
Claims: idpv1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
AuthorizationConfig: idpv1alpha1.OIDCAuthorizationConfig{
AdditionalScopes: testAdditionalScopes,
},
},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidConditionEarlier,
@@ -1175,9 +1175,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
ResourceUID: testUID,
},
},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
{Type: "AdditionalAuthorizeParametersValid", Status: "True", LastTransitionTime: earlier, Reason: "Success", Message: "additionalAuthorizeParameters parameter names are allowed", ObservedGeneration: 1234},
@@ -1189,18 +1189,18 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "existing valid upstream with trailing slash and more optional settings",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/ends-with-slash/",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: idpv1alpha1.OIDCAuthorizationConfig{
AdditionalScopes: testAdditionalScopes,
AdditionalAuthorizeParameters: testAdditionalParams,
AllowPasswordGrant: true,
},
Claims: v1alpha1.OIDCClaims{
Claims: idpv1alpha1.OIDCClaims{
Groups: testGroupsClaim,
Username: testUsernameClaim,
AdditionalClaimMappings: map[string]string{
@@ -1208,7 +1208,7 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
},
},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidConditionEarlier,
@@ -1244,9 +1244,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
ResourceUID: testUID,
},
},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
{Type: "AdditionalAuthorizeParametersValid", Status: "True", LastTransitionTime: earlier, Reason: "Success", Message: "additionalAuthorizeParameters parameter names are allowed", ObservedGeneration: 1234},
@@ -1258,14 +1258,14 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "has disallowed additionalAuthorizeParams keys",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
AdditionalAuthorizeParameters: []v1alpha1.Parameter{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: idpv1alpha1.OIDCAuthorizationConfig{
AdditionalAuthorizeParameters: []idpv1alpha1.Parameter{
{Name: "response_type", Value: "foo"},
{Name: "scope", Value: "foo"},
{Name: "client_id", Value: "foo"},
@@ -1293,9 +1293,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="the following additionalAuthorizeParameters are not allowed: response_type,scope,client_id,state,nonce,code_challenge,code_challenge_method,redirect_uri,hd" "name"="test-name" "namespace"="test-namespace" "reason"="DisallowedParameterName" "type"="AdditionalAuthorizeParametersValid"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{Type: "AdditionalAuthorizeParametersValid", Status: "False", LastTransitionTime: now, Reason: "DisallowedParameterName",
@@ -1309,12 +1309,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer is invalid URL, missing trailing slash when the OIDC discovery endpoint returns the URL with a trailing slash",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/ends-with-slash", // this does not end with slash when it should, thus this is an error case
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -1331,9 +1331,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/ends-with-slash\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/ends-with-slash\" got \"` + testIssuerURL + `/ends-with-slash/\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -1358,12 +1358,12 @@ oidc: issuer did not match the issuer returned by provider, expected "` + testIs
},
{
name: "issuer is invalid URL, extra trailing slash",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -1380,9 +1380,9 @@ oidc: issuer did not match the issuer returned by provider, expected "` + testIs
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/\" got \"` + testIssuerURL + `\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -1409,8 +1409,8 @@ oidc: issuer did not match the issuer returned by provider, expected "` + testIs
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
fakePinnipedClient := pinnipedfake.NewSimpleClientset(tt.inputUpstreams...)
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakePinnipedClient := supervisorfake.NewSimpleClientset(tt.inputUpstreams...)
pinnipedInformers := supervisorinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakeKubeClient := fake.NewSimpleClientset(tt.inputSecrets...)
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
testLog := testlogger.NewLegacy(t) //nolint:staticcheck // old test with lots of log statements
@@ -1504,13 +1504,13 @@ func unwrapTransport(t *testing.T, rt http.RoundTripper) *http.Transport {
}
}
func normalizeOIDCUpstreams(upstreams []v1alpha1.OIDCIdentityProvider, now metav1.Time) []v1alpha1.OIDCIdentityProvider {
result := make([]v1alpha1.OIDCIdentityProvider, 0, len(upstreams))
func normalizeOIDCUpstreams(upstreams []idpv1alpha1.OIDCIdentityProvider, now metav1.Time) []idpv1alpha1.OIDCIdentityProvider {
result := make([]idpv1alpha1.OIDCIdentityProvider, 0, len(upstreams))
for _, u := range upstreams {
normalized := u.DeepCopy()
// We're only interested in comparing the status, so zero out the spec.
normalized.Spec = v1alpha1.OIDCIdentityProviderSpec{}
normalized.Spec = idpv1alpha1.OIDCIdentityProviderSpec{}
// Round down the LastTransitionTime values to `now` if they were just updated. This makes
// it much easier to encode assertions about the expected timestamps.
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package supervisorconfig
@@ -10,7 +10,7 @@ import (
"strings"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
corev1informers "k8s.io/client-go/informers/core/v1"
@@ -112,7 +112,7 @@ func (c *tlsCertObserverController) Sync(ctx controllerlib.Context) error {
if err != nil {
c.issuerTLSCertSetter.SetDefaultTLSCert(nil)
// It's okay if the default TLS cert Secret is not found (it is not required).
if !k8serrors.IsNotFound(err) {
if !apierrors.IsNotFound(err) {
// For any other error, log a message which is visible at the default log level.
plog.Error("error loading TLS certificate from Secret for Supervisor default TLS cert", err,
"defaultCertSecretName", c.defaultTLSCertificateSecretName,
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package supervisorconfig
@@ -18,9 +18,9 @@ import (
k8sinformers "k8s.io/client-go/informers"
kubernetesfake "k8s.io/client-go/kubernetes/fake"
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
supervisorinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/testutil"
)
@@ -38,7 +38,7 @@ func TestTLSCertObserverControllerInformerFilters(t *testing.T) {
r = require.New(t)
observableWithInformerOption = testutil.NewObservableWithInformerOption()
secretsInformer := k8sinformers.NewSharedInformerFactory(nil, 0).Core().V1().Secrets()
federationDomainInformer := pinnipedinformers.NewSharedInformerFactory(nil, 0).Config().V1alpha1().FederationDomains()
federationDomainInformer := supervisorinformers.NewSharedInformerFactory(nil, 0).Config().V1alpha1().FederationDomains()
_ = NewTLSCertObserverController(
nil,
"", // don't care about the secret name for this test
@@ -83,13 +83,13 @@ func TestTLSCertObserverControllerInformerFilters(t *testing.T) {
when("watching FederationDomain objects", func() {
var (
subject controllerlib.Filter
provider, otherProvider *v1alpha1.FederationDomain
provider, otherProvider *supervisorconfigv1alpha1.FederationDomain
)
it.Before(func() {
subject = federationDomainInformerFilter
provider = &v1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-name", Namespace: "any-namespace"}}
otherProvider = &v1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-other-name", Namespace: "any-other-namespace"}}
provider = &supervisorconfigv1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-name", Namespace: "any-namespace"}}
otherProvider = &supervisorconfigv1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-other-name", Namespace: "any-other-namespace"}}
})
when("any FederationDomain changes", func() {
@@ -131,9 +131,9 @@ func TestTLSCertObserverControllerSync(t *testing.T) {
var (
r *require.Assertions
subject controllerlib.Controller
pinnipedInformerClient *pinnipedfake.Clientset
pinnipedInformerClient *supervisorfake.Clientset
kubeInformerClient *kubernetesfake.Clientset
pinnipedInformers pinnipedinformers.SharedInformerFactory
pinnipedInformers supervisorinformers.SharedInformerFactory
kubeInformers k8sinformers.SharedInformerFactory
cancelContext context.Context
cancelContextCancelFunc context.CancelFunc
@@ -182,8 +182,8 @@ func TestTLSCertObserverControllerSync(t *testing.T) {
kubeInformerClient = kubernetesfake.NewSimpleClientset()
kubeInformers = k8sinformers.NewSharedInformerFactory(kubeInformerClient, 0)
pinnipedInformerClient = pinnipedfake.NewSimpleClientset()
pinnipedInformers = pinnipedinformers.NewSharedInformerFactory(pinnipedInformerClient, 0)
pinnipedInformerClient = supervisorfake.NewSimpleClientset()
pinnipedInformers = supervisorinformers.NewSharedInformerFactory(pinnipedInformerClient, 0)
issuerTLSCertSetter = &fakeIssuerTLSCertSetter{}
unrelatedSecret := &corev1.Secret{
@@ -219,75 +219,75 @@ func TestTLSCertObserverControllerSync(t *testing.T) {
it.Before(func() {
var err error
federationDomainWithoutSecret1 := &v1alpha1.FederationDomain{
federationDomainWithoutSecret1 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "no-secret-federationdomain1",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer1.com"}, // no SNICertificateSecretName field
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer1.com"}, // no SNICertificateSecretName field
}
federationDomainWithoutSecret2 := &v1alpha1.FederationDomain{
federationDomainWithoutSecret2 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "no-secret-federationdomain2",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://no-secret-issuer2.com",
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: ""},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: ""},
},
}
federationDomainWithBadSecret := &v1alpha1.FederationDomain{
federationDomainWithBadSecret := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "bad-secret-federationdomain",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://bad-secret-issuer.com",
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: "bad-tls-secret-name"},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: "bad-tls-secret-name"},
},
}
// Also add one with a URL that cannot be parsed to make sure that the controller is not confused by invalid URLs.
invalidIssuerURL := ":/host//path"
_, err = url.Parse(invalidIssuerURL) //nolint:staticcheck // Yes, this URL is intentionally invalid.
r.Error(err)
federationDomainWithBadIssuer := &v1alpha1.FederationDomain{
federationDomainWithBadIssuer := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "bad-issuer-federationdomain",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: invalidIssuerURL},
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: invalidIssuerURL},
}
federationDomainWithGoodSecret1 := &v1alpha1.FederationDomain{
federationDomainWithGoodSecret1 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "good-secret-federationdomain1",
Namespace: installedInNamespace,
},
// Issuer hostname should be treated in a case-insensitive way and SNI ignores port numbers. Test without a port number.
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://www.iSSuer-wiTh-goOd-secRet1.cOm/path",
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name1"},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name1"},
},
}
federationDomainWithGoodSecret2 := &v1alpha1.FederationDomain{
federationDomainWithGoodSecret2 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "good-secret-federationdomain2",
Namespace: installedInNamespace,
},
// Issuer hostname should be treated in a case-insensitive way and SNI ignores port numbers. Test with a port number.
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://www.issUEr-WIth-gOOd-seCret2.com:1234/path",
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name2"},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name2"},
},
}
federationDomainWithIPv6Issuer := &v1alpha1.FederationDomain{
federationDomainWithIPv6Issuer := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "ipv6-issuer-federationdomain",
Namespace: installedInNamespace,
},
// Issuer hostname should be treated correctly when it is an IPv6 address. Test with a port number.
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://[2001:db8::1]:1234/path",
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name1"},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name1"},
},
}
testCrt1 := readTestFile("testdata/test.crt")
@@ -1,4 +1,4 @@
// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package upstreamwatchers
@@ -14,7 +14,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1informers "k8s.io/client-go/informers/core/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
"go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/plog"
@@ -110,7 +110,7 @@ type UpstreamGenericLDAPIDP interface {
type UpstreamGenericLDAPSpec interface {
Host() string
TLSSpec() *v1alpha1.TLSSpec
TLSSpec() *idpv1alpha1.TLSSpec
BindSecretName() string
UserSearch() UpstreamGenericLDAPUserSearch
GroupSearch() UpstreamGenericLDAPGroupSearch
@@ -135,7 +135,7 @@ type UpstreamGenericLDAPStatus interface {
Conditions() []metav1.Condition
}
func ValidateTLSConfig(tlsSpec *v1alpha1.TLSSpec, config *upstreamldap.ProviderConfig) *metav1.Condition {
func ValidateTLSConfig(tlsSpec *idpv1alpha1.TLSSpec, config *upstreamldap.ProviderConfig) *metav1.Condition {
if tlsSpec == nil {
return validTLSCondition(noTLSConfigurationMessage)
}
@@ -278,8 +278,8 @@ func (c *garbageCollectorController) tryRevokeUpstreamOIDCToken(ctx context.Cont
return nil
}
func logKV(secret *corev1.Secret) []interface{} {
return []interface{}{
func logKV(secret *corev1.Secret) []any {
return []any{
"secretName", secret.Name,
"secretNamespace", secret.Namespace,
"secretType", string(secret.Type),
+2 -2
View File
@@ -13,7 +13,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/util/cert"
authv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
"go.pinniped.dev/internal/controllerlib"
)
@@ -103,7 +103,7 @@ type WithInitialEventOptionFunc func(key controllerlib.Key) controllerlib.Option
// BuildCertPoolAuth returns a PEM-encoded CA bundle from the provided spec. If the provided spec is nil, a
// nil CA bundle will be returned. If the provided spec contains a CA bundle that is not properly
// encoded, an error will be returned.
func BuildCertPoolAuth(spec *authv1alpha1.TLSSpec) (*x509.CertPool, []byte, error) {
func BuildCertPoolAuth(spec *authenticationv1alpha1.TLSSpec) (*x509.CertPool, []byte, error) {
if spec == nil {
return nil, nil, nil
}
+2 -2
View File
@@ -72,8 +72,8 @@ func unsyncedInformers(status map[reflect.Type]bool) []string {
return names
}
func anyToFullname(any interface{}) string {
typ := reflect.TypeOf(any)
func anyToFullname(a any) string {
typ := reflect.TypeOf(a)
return typeToFullname(typ)
}
+2 -2
View File
@@ -1,11 +1,11 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package controllerlib
type die string
func crash(i interface{}) {
func crash(i any) {
mustDie, ok := i.(die)
if ok {
panic(string(mustDie))
+5 -5
View File
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package controllerlib
@@ -60,7 +60,7 @@ func WithInformer(getter InformerGetter, filter Filter, opt InformerOption) Opti
}
_, err := informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
AddFunc: func(obj any) {
object := metaOrDie(obj)
if filter.Add(object) {
plog.Debug("handling add",
@@ -73,7 +73,7 @@ func WithInformer(getter InformerGetter, filter Filter, opt InformerOption) Opti
c.add(filter, object)
}
},
UpdateFunc: func(oldObj, newObj interface{}) {
UpdateFunc: func(oldObj, newObj any) {
oldObject := metaOrDie(oldObj)
newObject := metaOrDie(newObj)
if filter.Update(oldObject, newObject) {
@@ -87,7 +87,7 @@ func WithInformer(getter InformerGetter, filter Filter, opt InformerOption) Opti
c.add(filter, newObject)
}
},
DeleteFunc: func(obj interface{}) {
DeleteFunc: func(obj any) {
accessor, err := meta.Accessor(obj)
if err != nil {
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
@@ -146,7 +146,7 @@ func toOnceOpt(opt Option) Option {
}
}
func metaOrDie(obj interface{}) metav1.Object {
func metaOrDie(obj any) metav1.Object {
accessor, err := meta.Accessor(obj)
if err != nil {
panic(err) // this should never happen
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package controllerlib
@@ -16,7 +16,7 @@ var _ events.EventRecorder = klogRecorder{}
type klogRecorder struct{}
func (n klogRecorder) Eventf(regarding runtime.Object, related runtime.Object, eventtype, reason, action, note string, args ...interface{}) {
func (n klogRecorder) Eventf(regarding runtime.Object, related runtime.Object, eventtype, reason, action, note string, args ...any) {
plog.Debug("recording event",
"regarding", regarding,
"related", related,
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package controllerlib
@@ -34,7 +34,7 @@ type Key struct {
Name string
// TODO determine if it makes sense to add a field like:
// Extra interface{}
// Extra any
// This would allow a custom ParentFunc to pass extra data through to the Syncer
// The boxed type would have to be comparable (i.e. usable as a map key)
}
+1 -1
View File
@@ -48,7 +48,7 @@ type Storage interface {
GetName(signature string) string
}
type JSON interface{} // document that we need valid JSON types
type JSON any // document that we need valid JSON types
func New(resource string, secrets corev1client.SecretInterface, clock func() time.Time) Storage {
return &secretsStorage{
+1 -1
View File
@@ -244,4 +244,4 @@ func TestNewServingCert(t *testing.T) {
type fakeT struct{}
func (fakeT) Errorf(string, ...interface{}) {}
func (fakeT) Errorf(string, ...any) {}
+4 -4
View File
@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package execcredcache implements a cache for Kubernetes ExecCredential data.
@@ -50,7 +50,7 @@ func New(path string) *Cache {
}
}
func (c *Cache) Get(key interface{}) *clientauthenticationv1beta1.ExecCredential {
func (c *Cache) Get(key any) *clientauthenticationv1beta1.ExecCredential {
// If the cache file does not exist, exit immediately with no error log
if _, err := os.Stat(c.path); errors.Is(err, os.ErrNotExist) {
return nil
@@ -80,7 +80,7 @@ func (c *Cache) Get(key interface{}) *clientauthenticationv1beta1.ExecCredential
return result
}
func (c *Cache) Put(key interface{}, cred *clientauthenticationv1beta1.ExecCredential) {
func (c *Cache) Put(key any, cred *clientauthenticationv1beta1.ExecCredential) {
// Create the cache directory if it does not exist.
if err := os.MkdirAll(filepath.Dir(c.path), 0700); err != nil && !errors.Is(err, os.ErrExist) {
c.errReporter(fmt.Errorf("could not create credential cache directory: %w", err))
@@ -111,7 +111,7 @@ func (c *Cache) Put(key interface{}, cred *clientauthenticationv1beta1.ExecCrede
})
}
func jsonSHA256Hex(key interface{}) string {
func jsonSHA256Hex(key any) string {
hash := sha256.New()
if err := json.NewEncoder(hash).Encode(key); err != nil {
panic(err)
@@ -12,10 +12,10 @@ import (
coreosoidc "github.com/coreos/go-oidc/v3/oidc"
"github.com/ory/fosite"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
supervisorclient "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1"
"go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
@@ -95,7 +95,7 @@ func (m *ClientManager) GetClient(ctx context.Context, id string) (fosite.Client
// Try to look up an OIDCClient with the given client ID (which will be the Name of the OIDCClient).
oidcClient, err := m.oidcClientsClient.Get(ctx, id, metav1.GetOptions{})
if errors.IsNotFound(err) {
if apierrors.IsNotFound(err) {
return nil, fosite.ErrNotFound.WithDescription("no such client")
}
if err != nil {
@@ -179,7 +179,7 @@ func PinnipedCLI() *Client {
}
}
func oidcClientCRToFositeClient(oidcClient *configv1alpha1.OIDCClient, clientSecrets []string) *Client {
func oidcClientCRToFositeClient(oidcClient *supervisorconfigv1alpha1.OIDCClient, clientSecrets []string) *Client {
// Allow the user to optionally override the default timeouts for these clients.
idTokenLifetimeOverrideInSeconds := oidcClient.Spec.TokenLifetimes.IDTokenSeconds
var idTokenLifetime time.Duration
@@ -215,7 +215,7 @@ func oidcClientCRToFositeClient(oidcClient *configv1alpha1.OIDCClient, clientSec
}
}
func scopesToArguments(scopes []configv1alpha1.Scope) fosite.Arguments {
func scopesToArguments(scopes []supervisorconfigv1alpha1.Scope) fosite.Arguments {
a := make(fosite.Arguments, len(scopes))
for i, scope := range scopes {
a[i] = string(scope)
@@ -223,7 +223,7 @@ func scopesToArguments(scopes []configv1alpha1.Scope) fosite.Arguments {
return a
}
func grantTypesToArguments(grantTypes []configv1alpha1.GrantType) fosite.Arguments {
func grantTypesToArguments(grantTypes []supervisorconfigv1alpha1.GrantType) fosite.Arguments {
a := make(fosite.Arguments, len(grantTypes))
for i, grantType := range grantTypes {
a[i] = string(grantType)
@@ -231,7 +231,7 @@ func grantTypesToArguments(grantTypes []configv1alpha1.GrantType) fosite.Argumen
return a
}
func redirectURIsToStrings(uris []configv1alpha1.RedirectURI) []string {
func redirectURIsToStrings(uris []supervisorconfigv1alpha1.RedirectURI) []string {
s := make([]string, len(uris))
for i, uri := range uris {
s[i] = string(uri)
@@ -10,7 +10,7 @@ import (
"testing"
"time"
"github.com/coreos/go-oidc/v3/oidc"
coreosoidc "github.com/coreos/go-oidc/v3/oidc"
"github.com/ory/fosite"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
@@ -20,7 +20,7 @@ import (
coretesting "k8s.io/client-go/testing"
"k8s.io/utils/ptr"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
"go.pinniped.dev/internal/oidcclientsecretstorage"
@@ -39,7 +39,7 @@ func TestClientManager(t *testing.T) {
tests := []struct {
name string
secrets []*corev1.Secret
oidcClients []*configv1alpha1.OIDCClient
oidcClients []*supervisorconfigv1alpha1.OIDCClient
addKubeReactions func(client *fake.Clientset)
addSupervisorReactions func(client *supervisorfake.Clientset)
run func(t *testing.T, subject *ClientManager)
@@ -62,7 +62,7 @@ func TestClientManager(t *testing.T) {
},
{
name: "find pinniped-cli client when some dynamic clients also exist",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID}},
},
run: func(t *testing.T, subject *ClientManager) {
@@ -74,7 +74,7 @@ func TestClientManager(t *testing.T) {
},
{
name: "client not found",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID}},
},
run: func(t *testing.T, subject *ClientManager) {
@@ -89,13 +89,13 @@ func TestClientManager(t *testing.T) {
},
{
name: "find a dynamic client when its storage secret does not exist (client is invalid because is has no client secret)",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []configv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
},
},
},
@@ -107,13 +107,13 @@ func TestClientManager(t *testing.T) {
},
{
name: "find a dynamic client which is invalid due to its spec",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{}, // at least "openid" is required here, so this makes the client invalid
AllowedRedirectURIs: []configv1alpha1.RedirectURI{"http://localhost:80"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{}, // at least "openid" is required here, so this makes the client invalid
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{"http://localhost:80"},
},
},
},
@@ -128,13 +128,13 @@ func TestClientManager(t *testing.T) {
},
{
name: "find a dynamic client which somehow does not have the required prefix in its name, just in case, although should not be possible since prefix is a validation on the CRD",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "does-not-have-prefix", Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []configv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
},
},
},
@@ -166,7 +166,7 @@ func TestClientManager(t *testing.T) {
},
{
name: "when there is an unexpected error getting the storage secret for the OIDCClient",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID}},
},
addKubeReactions: func(client *fake.Clientset) {
@@ -182,14 +182,14 @@ func TestClientManager(t *testing.T) {
},
{
name: "find a valid dynamic client without an ID token lifetime configuration",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []configv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
TokenLifetimes: configv1alpha1.OIDCClientTokenLifetimes{IDTokenSeconds: nil},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
TokenLifetimes: supervisorconfigv1alpha1.OIDCClientTokenLifetimes{IDTokenSeconds: nil},
},
},
{
@@ -217,14 +217,14 @@ func TestClientManager(t *testing.T) {
},
{
name: "find a valid dynamic client with an ID token lifetime configuration",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "username", "groups"},
AllowedRedirectURIs: []configv1alpha1.RedirectURI{"http://localhost:8080"},
TokenLifetimes: configv1alpha1.OIDCClientTokenLifetimes{IDTokenSeconds: ptr.To[int32](4242)},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username", "groups"},
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{"http://localhost:8080"},
TokenLifetimes: supervisorconfigv1alpha1.OIDCClientTokenLifetimes{IDTokenSeconds: ptr.To[int32](4242)},
},
},
{
@@ -294,7 +294,7 @@ func requireEqualsPinnipedCLI(t *testing.T, c *Client) {
require.Equal(t, []string{"http://127.0.0.1/callback"}, c.GetRedirectURIs())
require.Equal(t, fosite.Arguments{"authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:token-exchange"}, c.GetGrantTypes())
require.Equal(t, fosite.Arguments{"code"}, c.GetResponseTypes())
require.Equal(t, fosite.Arguments{oidc.ScopeOpenID, oidc.ScopeOfflineAccess, "profile", "email", "pinniped:request-audience", "username", "groups"}, c.GetScopes())
require.Equal(t, fosite.Arguments{coreosoidc.ScopeOpenID, coreosoidc.ScopeOfflineAccess, "profile", "email", "pinniped:request-audience", "username", "groups"}, c.GetScopes())
require.True(t, c.IsPublic())
require.Nil(t, c.GetAudience())
require.Nil(t, c.GetRequestURIs())
@@ -7,12 +7,12 @@ package downstreamsession
import (
"context"
"fmt"
"slices"
"time"
"github.com/ory/fosite"
"github.com/ory/fosite/handler/openid"
"github.com/ory/fosite/token/jwt"
"k8s.io/utils/strings/slices"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/constable"
@@ -73,7 +73,7 @@ func NewPinnipedSession(
Custom: customSessionData,
}
extras := map[string]interface{}{}
extras := map[string]any{}
extras[oidcapi.IDTokenClaimAuthorizedParty] = c.ClientID
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package dynamiccodec provides a type that can encode information using a just-in-time signing and
@@ -41,12 +41,12 @@ func New(lifespan time.Duration, signingKeyFunc, encryptionKeyFunc KeyFunc) *Cod
}
// Encode implements oidc.Encode().
func (c *Codec) Encode(name string, value interface{}) (string, error) {
func (c *Codec) Encode(name string, value any) (string, error) {
return c.delegate().Encode(name, value)
}
// Decode implements oidc.Decode().
func (c *Codec) Decode(name string, value string, into interface{}) error {
func (c *Codec) Decode(name string, value string, into any) error {
return c.delegate().Decode(name, value, into)
}
@@ -700,7 +700,7 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
wantUnnecessaryStoredRecords int
wantPasswordGrantCall *expectedPasswordGrant
wantDownstreamCustomSessionData *psession.CustomSessionData
wantDownstreamAdditionalClaims map[string]interface{}
wantDownstreamAdditionalClaims map[string]any
}
tests := []testCase{
{
@@ -991,7 +991,7 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
"downstreamMissingClaim": "upstreamMissingClaim",
}).
WithIDTokenClaim("upstreamCustomClaim", "i am a claim value").
WithIDTokenClaim("upstreamOtherClaim", []interface{}{"hello", true}).
WithIDTokenClaim("upstreamOtherClaim", []any{"hello", true}).
Build()),
method: http.MethodGet,
path: happyGetRequestPathForOIDCPasswordGrantUpstream,
@@ -1011,9 +1011,9 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSession,
wantDownstreamAdditionalClaims: map[string]interface{}{
wantDownstreamAdditionalClaims: map[string]any{
"downstreamCustomClaim": "i am a claim value",
"downstreamOtherClaim": []interface{}{"hello", true},
"downstreamOtherClaim": []any{"hello", true},
},
},
{
@@ -3023,7 +3023,7 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
name: "OIDC upstream password grant: upstream IDP's configured groups claim in the ID token is a slice of interfaces",
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
passwordGrantUpstreamOIDCIdentityProviderBuilder().
WithIDTokenClaim(oidcUpstreamGroupsClaim, []interface{}{"group1", "group2"}).Build(),
WithIDTokenClaim(oidcUpstreamGroupsClaim, []any{"group1", "group2"}).Build(),
),
method: http.MethodGet,
path: happyGetRequestPathForOIDCPasswordGrantUpstream,
@@ -3231,7 +3231,7 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
{
name: "OIDC upstream password grant: upstream ID token contains groups claim where one element is invalid",
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
passwordGrantUpstreamOIDCIdentityProviderBuilder().WithIDTokenClaim(oidcUpstreamGroupsClaim, []interface{}{"foo", 7}).Build(),
passwordGrantUpstreamOIDCIdentityProviderBuilder().WithIDTokenClaim(oidcUpstreamGroupsClaim, []any{"foo", 7}).Build(),
),
method: http.MethodGet,
path: happyGetRequestPathForOIDCPasswordGrantUpstream,
@@ -3700,7 +3700,7 @@ type errorReturningEncoder struct {
oidc.Codec
}
func (*errorReturningEncoder) Encode(_ string, _ interface{}) (string, error) {
func (*errorReturningEncoder) Encode(_ string, _ any) (string, error) {
return "", fmt.Errorf("some encoding error")
}
@@ -20,7 +20,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/federationdomain/oidc"
@@ -242,7 +242,7 @@ func TestCallbackEndpoint(t *testing.T) {
wantDownstreamPKCEChallenge string
wantDownstreamPKCEChallengeMethod string
wantDownstreamCustomSessionData *psession.CustomSessionData
wantDownstreamAdditionalClaims map[string]interface{}
wantDownstreamAdditionalClaims map[string]any
wantOIDCAuthcodeExchangeCall *expectedOIDCAuthcodeExchange
wantGitHubAuthcodeExchangeCall *expectedGitHubAuthcodeExchange
}{
@@ -346,7 +346,7 @@ func TestCallbackEndpoint(t *testing.T) {
performedByUpstreamName: happyOIDCUpstreamIDPName,
args: happyOIDCUpstreamExchangeAuthcodeAndValidateTokenArgs,
},
wantDownstreamAdditionalClaims: map[string]interface{}{
wantDownstreamAdditionalClaims: map[string]any{
"downstreamCustomClaim": "i am a claim value",
"downstreamOtherClaim": "other claim value",
},
@@ -795,7 +795,7 @@ func TestCallbackEndpoint(t *testing.T) {
{
name: "upstream IDP's configured groups claim in the ID token is a slice of interfaces",
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
happyOIDCUpstream().WithIDTokenClaim(oidcUpstreamGroupsClaim, []interface{}{"group1", "group2"}).Build(),
happyOIDCUpstream().WithIDTokenClaim(oidcUpstreamGroupsClaim, []any{"group1", "group2"}).Build(),
),
method: http.MethodGet,
path: newRequestPath().WithState(happyOIDCState).String(),
@@ -889,8 +889,8 @@ func TestCallbackEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]configv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -932,8 +932,8 @@ func TestCallbackEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]configv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1199,8 +1199,8 @@ func TestCallbackEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]configv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1228,8 +1228,8 @@ func TestCallbackEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]configv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1675,7 +1675,7 @@ func TestCallbackEndpoint(t *testing.T) {
{
name: "upstream ID token contains groups claim where one element is invalid",
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
happyOIDCUpstream().WithIDTokenClaim(oidcUpstreamGroupsClaim, []interface{}{"foo", 7}).Build(),
happyOIDCUpstream().WithIDTokenClaim(oidcUpstreamGroupsClaim, []any{"foo", 7}).Build(),
),
method: http.MethodGet,
path: newRequestPath().WithState(happyOIDCState).String(),
@@ -17,7 +17,7 @@ import (
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/client-go/kubernetes/fake"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/authenticators"
"go.pinniped.dev/internal/celtransformer"
@@ -613,8 +613,8 @@ func TestPostLoginEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]configv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -647,8 +647,8 @@ func TestPostLoginEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]configv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -691,8 +691,8 @@ func TestPostLoginEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]configv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1051,8 +1051,8 @@ func TestPostLoginEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]configv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1071,8 +1071,8 @@ func TestPostLoginEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]configv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1185,7 +1185,7 @@ func TestPostLoginEndpoint(t *testing.T) {
tt.wantDownstreamClient,
tt.wantDownstreamRedirectURI,
tt.wantDownstreamCustomSessionData,
map[string]interface{}{},
map[string]any{},
)
case tt.wantRedirectToLoginPageError != "":
// Expecting an error redirect to the login UI page.
@@ -1221,7 +1221,7 @@ func TestPostLoginEndpoint(t *testing.T) {
tt.wantDownstreamClient,
tt.wantDownstreamRedirectURI,
tt.wantDownstreamCustomSessionData,
map[string]interface{}{},
map[string]any{},
)
default:
require.Failf(t, "test should have expected a redirect or form body",
@@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"net/http"
"slices"
"time"
"github.com/ory/fosite"
@@ -16,7 +17,6 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/warning"
"k8s.io/utils/strings/slices"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
@@ -298,7 +298,7 @@ func validateAndGetDownstreamGroupsFromSession(session *psession.PinnipedSession
if downstreamGroupsInterface == nil {
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError())
}
downstreamGroupsInterfaceList, ok := downstreamGroupsInterface.([]interface{})
downstreamGroupsInterfaceList, ok := downstreamGroupsInterface.([]any)
if !ok {
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError())
}
@@ -17,6 +17,7 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"slices"
"strings"
"testing"
"time"
@@ -39,9 +40,8 @@ import (
"k8s.io/client-go/kubernetes/fake"
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/utils/ptr"
"k8s.io/utils/strings/slices"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/celtransformer"
"go.pinniped.dev/internal/crud"
@@ -305,7 +305,7 @@ type tokenEndpointResponseExpectedValues struct {
wantUpstreamOIDCValidateTokenCall *expectedOIDCUpstreamValidateTokens
wantCustomSessionDataStored *psession.CustomSessionData
wantWarnings []RecordedWarning
wantAdditionalClaims map[string]interface{}
wantAdditionalClaims map[string]any
// The expected lifetime of the ID tokens issued by authcode exchange and refresh, but not token exchange.
// When zero, will assume that the test wants the default value for ID token lifetime.
wantIDTokenLifetimeSeconds int
@@ -391,10 +391,10 @@ func TestTokenEndpointAuthcodeExchange(t *testing.T) {
authcodeExchange: authcodeExchangeInputs{
modifyAuthRequest: func(r *http.Request) { r.Form.Set("scope", "openid profile email username groups") },
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -410,13 +410,13 @@ func TestTokenEndpointAuthcodeExchange(t *testing.T) {
wantGrantedScopes: []string{"openid", "username", "groups"},
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -474,10 +474,10 @@ func TestTokenEndpointAuthcodeExchange(t *testing.T) {
},
modifyTokenRequest: modifyAuthcodeTokenRequestWithDynamicClientAuth,
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -493,13 +493,13 @@ func TestTokenEndpointAuthcodeExchange(t *testing.T) {
wantGrantedScopes: []string{"openid", "pinniped:request-audience", "username", "groups"},
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -981,7 +981,7 @@ func TestTokenEndpointWhenAuthcodeIsUsedTwice(t *testing.T) {
// Authcode exchange doesn't use the upstream provider cache, so just pass an empty cache.
subject, rsp, authCode, _, secrets, oauthStore := exchangeAuthcodeForTokens(t,
test.authcodeExchange, testidplister.NewUpstreamIDPListerBuilder().BuildFederationDomainIdentityProvidersListerFinder(), test.kubeResources)
var parsedResponseBody map[string]interface{}
var parsedResponseBody map[string]any
require.NoError(t, json.Unmarshal(rsp.Body.Bytes(), &parsedResponseBody))
// Second call - should be unsuccessful since auth code was already used.
@@ -1088,10 +1088,10 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
authRequest.Form.Set("scope", "openid pinniped:request-audience username groups")
},
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -1107,13 +1107,13 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
wantGrantedScopes: []string{"openid", "pinniped:request-audience", "username", "groups"},
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -1183,10 +1183,10 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
authRequest.Form.Set("scope", "openid pinniped:request-audience username groups")
},
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -1203,13 +1203,13 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
wantGrantedScopes: []string{"openid", "pinniped:request-audience", "username", "groups"},
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -1256,12 +1256,12 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
name: "dynamic client lacks the required urn:ietf:params:oauth:grant-type:token-exchange grant type",
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
namespace, clientID, clientUID, redirectURI := "some-namespace", dynamicClientID, dynamicClientUID, goodRedirectURI
oidcClient := &configv1alpha1.OIDCClient{
oidcClient := &supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: clientID, Generation: 1, UID: types.UID(clientUID)},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // does not have the grant type
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "username", "groups"}, // would be invalid if it also asked for pinniped:request-audience since it lacks the grant type
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(redirectURI)},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // does not have the grant type
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username", "groups"}, // would be invalid if it also asked for pinniped:request-audience since it lacks the grant type
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(redirectURI)},
},
}
secret := testutil.OIDCClientSecretStorageSecretForUID(t, namespace, clientUID, []string{testutil.HashedPassword1AtGoMinCost, testutil.HashedPassword2AtGoMinCost})
@@ -1659,7 +1659,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
// Authcode exchange doesn't use the upstream provider cache, so just pass an empty cache.
subject, rsp, _, _, secrets, storage := exchangeAuthcodeForTokens(t,
test.authcodeExchange, testidplister.NewUpstreamIDPListerBuilder().BuildFederationDomainIdentityProvidersListerFinder(), test.kubeResources)
var parsedAuthcodeExchangeResponseBody map[string]interface{}
var parsedAuthcodeExchangeResponseBody map[string]any
require.NoError(t, json.Unmarshal(rsp.Body.Bytes(), &parsedAuthcodeExchangeResponseBody))
request := happyTokenExchangeRequest(test.requestedAudience, parsedAuthcodeExchangeResponseBody["access_token"].(string))
@@ -1695,7 +1695,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
require.Equal(t, test.wantStatus, rsp.Code)
testutil.RequireEqualContentType(t, rsp.Header().Get("Content-Type"), "application/json")
var parsedResponseBody map[string]interface{}
var parsedResponseBody map[string]any
require.NoError(t, json.Unmarshal(rsp.Body.Bytes(), &parsedResponseBody))
if rsp.Code != http.StatusOK {
@@ -1714,7 +1714,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
return
}
claimsOfFirstIDToken := map[string]interface{}{}
claimsOfFirstIDToken := map[string]any{}
originalIDToken := parsedAuthcodeExchangeResponseBody["id_token"].(string)
firstIDTokenDecoded, _ := josejwt.ParseSigned(originalIDToken)
err = firstIDTokenDecoded.UnsafeClaimsWithoutVerification(&claimsOfFirstIDToken)
@@ -1727,7 +1727,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
// Parse the returned token.
parsedJWT, err := jose.ParseSigned(parsedResponseBody["access_token"].(string))
require.NoError(t, err)
var tokenClaims map[string]interface{}
var tokenClaims map[string]any
require.NoError(t, json.Unmarshal(parsedJWT.UnsafePayloadWithoutVerification(), &tokenClaims))
// Make sure that these are the only fields in the token.
@@ -1765,7 +1765,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
if len(test.authcodeExchange.want.wantAdditionalClaims) > 0 {
require.Equal(t, test.authcodeExchange.want.wantAdditionalClaims, tokenClaims["additionalClaims"])
}
additionalClaims, ok := tokenClaims["additionalClaims"].(map[string]interface{})
additionalClaims, ok := tokenClaims["additionalClaims"].(map[string]any)
if ok && tokenClaims["additionalClaims"] != nil {
require.True(t, len(additionalClaims) > 0, "additionalClaims may never be present and empty in the id token")
}
@@ -2070,7 +2070,7 @@ func TestRefreshGrant(t *testing.T) {
return want
}
happyRefreshTokenResponseForOpenIDAndOfflineAccessWithAdditionalClaims := func(wantCustomSessionDataStored *psession.CustomSessionData, expectToValidateToken *oauth2.Token, wantAdditionalClaims map[string]interface{}) tokenEndpointResponseExpectedValues {
happyRefreshTokenResponseForOpenIDAndOfflineAccessWithAdditionalClaims := func(wantCustomSessionDataStored *psession.CustomSessionData, expectToValidateToken *oauth2.Token, wantAdditionalClaims map[string]any) tokenEndpointResponseExpectedValues {
want := happyRefreshTokenResponseForOpenIDAndOfflineAccess(wantCustomSessionDataStored, expectToValidateToken)
want.wantAdditionalClaims = wantAdditionalClaims
return want
@@ -2105,7 +2105,7 @@ func TestRefreshGrant(t *testing.T) {
refreshedUpstreamTokensWithIDAndRefreshTokens := func() *oauth2.Token {
return refreshedUpstreamTokensWithRefreshTokenWithoutIDToken().
WithExtra(map[string]interface{}{"id_token": oidcUpstreamRefreshedIDToken})
WithExtra(map[string]any{"id_token": oidcUpstreamRefreshedIDToken})
}
refreshedUpstreamTokensWithIDTokenWithoutRefreshToken := func() *oauth2.Token {
@@ -2186,7 +2186,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2204,7 +2204,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2252,7 +2252,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{},
Claims: map[string]any{},
},
}).WithRefreshedTokens(refreshedUpstreamTokensWithRefreshTokenWithoutIDToken()).
WithTransformsForFederationDomain(prefixUsernameAndGroupsPipeline).Build()),
@@ -2291,7 +2291,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2331,7 +2331,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2371,7 +2371,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2380,10 +2380,10 @@ func TestRefreshGrant(t *testing.T) {
customSessionData: initialUpstreamOIDCRefreshTokenCustomSessionData(),
modifyAuthRequest: func(r *http.Request) { r.Form.Set("scope", "openid offline_access username groups") },
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -2400,13 +2400,13 @@ func TestRefreshGrant(t *testing.T) {
wantCustomSessionDataStored: initialUpstreamOIDCRefreshTokenCustomSessionData(),
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -2416,13 +2416,13 @@ func TestRefreshGrant(t *testing.T) {
want: happyRefreshTokenResponseForOpenIDAndOfflineAccessWithAdditionalClaims(
upstreamOIDCCustomSessionDataWithNewRefreshToken(oidcUpstreamRefreshedRefreshToken),
refreshedUpstreamTokensWithIDAndRefreshTokens(),
map[string]interface{}{
map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -2434,7 +2434,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2462,7 +2462,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2498,7 +2498,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2511,10 +2511,10 @@ func TestRefreshGrant(t *testing.T) {
r.Form.Set("scope", "openid offline_access username groups")
},
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -2532,13 +2532,13 @@ func TestRefreshGrant(t *testing.T) {
wantCustomSessionDataStored: initialUpstreamOIDCRefreshTokenCustomSessionData(),
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -2549,13 +2549,13 @@ func TestRefreshGrant(t *testing.T) {
want: withWantDynamicClientID(happyRefreshTokenResponseForOpenIDAndOfflineAccessWithAdditionalClaims(
upstreamOIDCCustomSessionDataWithNewRefreshToken(oidcUpstreamRefreshedRefreshToken),
refreshedUpstreamTokensWithIDAndRefreshTokens(),
map[string]interface{}{
map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -2567,7 +2567,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithUsernameClaim("username-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
"sub": goodUpstreamSubject,
"username-claim": goodUsername,
@@ -2614,7 +2614,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithUsernameClaim("username-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
"sub": goodUpstreamSubject,
"username-claim": goodUsername,
@@ -2635,7 +2635,7 @@ func TestRefreshGrant(t *testing.T) {
upstreamOIDCIdentityProviderBuilder().WithUsernameClaim("username-claim").
WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
"sub": goodUpstreamSubject,
"username-claim": goodUsername,
@@ -2678,7 +2678,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{},
Claims: map[string]any{},
},
}).WithRefreshedTokens(refreshedUpstreamTokensWithRefreshTokenWithoutIDToken()).Build()),
authcodeExchange: authcodeExchangeInputs{
@@ -2715,7 +2715,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{},
Claims: map[string]any{},
},
}).WithRefreshedTokens(refreshedUpstreamTokensWithRefreshTokenWithoutIDToken()).Build()),
authcodeExchange: happyAuthcodeExchangeInputsForOIDCUpstream,
@@ -2739,7 +2739,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
@@ -2770,7 +2770,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
@@ -2804,13 +2804,13 @@ func TestRefreshGrant(t *testing.T) {
},
},
{
name: "happy path refresh grant when the upstream refresh returns new group memberships (as interface{} types) from the merged ID token and userinfo results, it updates groups",
name: "happy path refresh grant when the upstream refresh returns new group memberships (as any types) from the merged ID token and userinfo results, it updates groups",
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []interface{}{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
"my-groups-claim": []any{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
},
}).WithRefreshedTokens(refreshedUpstreamTokensWithIDAndRefreshTokens()).Build()),
@@ -2839,7 +2839,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{}, // refreshed groups claims is updated to be an empty list
},
@@ -2869,7 +2869,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
// "my-groups-claim" is omitted from the refreshed claims
},
@@ -3097,7 +3097,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
@@ -3144,7 +3144,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
@@ -3194,7 +3194,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
@@ -3297,7 +3297,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": nil,
},
@@ -3318,7 +3318,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3336,7 +3336,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3357,7 +3357,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3401,7 +3401,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3552,7 +3552,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3573,7 +3573,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3604,7 +3604,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3946,7 +3946,7 @@ func TestRefreshGrant(t *testing.T) {
// This is the current format of the errors returned by the production code version of ValidateTokenAndMergeWithUserInfo, see ValidateTokenAndMergeWithUserInfo in upstreamoidc.go
WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": "something-different",
},
},
@@ -3972,7 +3972,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
},
},
@@ -3997,7 +3997,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithUsernameClaim("username-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
"sub": goodUpstreamSubject,
"username-claim": "some-changed-username",
@@ -4024,7 +4024,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithUsernameClaim("username-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
"sub": goodUpstreamSubject,
"iss": "some-changed-issuer",
@@ -4710,7 +4710,7 @@ func TestRefreshGrant(t *testing.T) {
// just populating a secret in storage.
subject, rsp, authCode, jwtSigningKey, secrets, oauthStore := exchangeAuthcodeForTokens(t,
test.authcodeExchange, test.idps.BuildFederationDomainIdentityProvidersListerFinder(), test.kubeResources)
var parsedAuthcodeExchangeResponseBody map[string]interface{}
var parsedAuthcodeExchangeResponseBody map[string]any
require.NoError(t, json.Unmarshal(rsp.Body.Bytes(), &parsedAuthcodeExchangeResponseBody))
// Performing an authcode exchange should not have caused any upstream refresh, which should only
@@ -4814,7 +4814,7 @@ func TestRefreshGrant(t *testing.T) {
if test.refreshRequest.want.wantStatus == http.StatusOK {
wantIDToken := slices.Contains(test.refreshRequest.want.wantSuccessBodyFields, "id_token")
var parsedRefreshResponseBody map[string]interface{}
var parsedRefreshResponseBody map[string]any
require.NoError(t, json.Unmarshal(refreshResponse.Body.Bytes(), &parsedRefreshResponseBody))
// Check that we got back new tokens.
@@ -4830,12 +4830,12 @@ func TestRefreshGrant(t *testing.T) {
require.Equal(t, parsedAuthcodeExchangeResponseBody["scope"].(string), parsedRefreshResponseBody["scope"].(string))
if wantIDToken {
var claimsOfFirstIDToken map[string]interface{}
var claimsOfFirstIDToken map[string]any
firstIDTokenDecoded, _ := josejwt.ParseSigned(parsedAuthcodeExchangeResponseBody["id_token"].(string))
err := firstIDTokenDecoded.UnsafeClaimsWithoutVerification(&claimsOfFirstIDToken)
require.NoError(t, err)
var claimsOfSecondIDToken map[string]interface{}
var claimsOfSecondIDToken map[string]any
secondIDTokenDecoded, _ := josejwt.ParseSigned(parsedRefreshResponseBody["id_token"].(string))
err = secondIDTokenDecoded.UnsafeClaimsWithoutVerification(&claimsOfSecondIDToken)
require.NoError(t, err)
@@ -4858,13 +4858,13 @@ func TestRefreshGrant(t *testing.T) {
}
}
func requireClaimsAreNotEqual(t *testing.T, claimName string, claimsOfTokenA map[string]interface{}, claimsOfTokenB map[string]interface{}) {
func requireClaimsAreNotEqual(t *testing.T, claimName string, claimsOfTokenA map[string]any, claimsOfTokenB map[string]any) {
require.NotEmpty(t, claimsOfTokenA[claimName])
require.NotEmpty(t, claimsOfTokenB[claimName])
require.NotEqual(t, claimsOfTokenA[claimName], claimsOfTokenB[claimName])
}
func requireClaimsAreEqual(t *testing.T, claimName string, claimsOfTokenA map[string]interface{}, claimsOfTokenB map[string]interface{}) {
func requireClaimsAreEqual(t *testing.T, claimName string, claimsOfTokenA map[string]any, claimsOfTokenB map[string]any) {
require.NotEmpty(t, claimsOfTokenA[claimName])
require.NotEmpty(t, claimsOfTokenB[claimName])
require.Equal(t, claimsOfTokenA[claimName], claimsOfTokenB[claimName])
@@ -4976,7 +4976,7 @@ func requireTokenEndpointBehavior(
if test.wantStatus == http.StatusOK {
require.NotNil(t, test.wantSuccessBodyFields, "problem with test table setup: wanted success but did not specify expected response body")
var parsedResponseBody map[string]interface{}
var parsedResponseBody map[string]any
require.NoError(t, json.Unmarshal(tokenEndpointResponse.Body.Bytes(), &parsedResponseBody))
require.ElementsMatch(t, test.wantSuccessBodyFields, getMapKeys(parsedResponseBody))
@@ -5149,7 +5149,7 @@ func simulateAuthEndpointHavingAlreadyRun(
Subject: goodSubject,
RequestedAt: goodRequestedAtTime,
AuthTime: goodAuthTime,
Extra: map[string]interface{}{},
Extra: map[string]any{},
},
Subject: "", // not used, note that the authorization and callback endpoints do not set this
Username: "", // not used, note that the authorization and callback endpoints do not set this
@@ -5233,7 +5233,7 @@ func requireInvalidAuthCodeStorage(
func requireValidRefreshTokenStorage(
t *testing.T,
body map[string]interface{},
body map[string]any,
storage fositeoauth2.CoreStorage,
wantClientID string,
wantRequestedScopes []string,
@@ -5241,7 +5241,7 @@ func requireValidRefreshTokenStorage(
wantUsername string,
wantGroups []string,
wantCustomSessionData *psession.CustomSessionData,
wantAdditionalClaims map[string]interface{},
wantAdditionalClaims map[string]any,
secrets v1.SecretInterface,
requestTime time.Time,
) {
@@ -5280,7 +5280,7 @@ func requireValidRefreshTokenStorage(
func requireValidAccessTokenStorage(
t *testing.T,
body map[string]interface{},
body map[string]any,
storage fositeoauth2.CoreStorage,
wantClientID string,
wantRequestedScopes []string,
@@ -5288,7 +5288,7 @@ func requireValidAccessTokenStorage(
wantUsername string,
wantGroups []string,
wantCustomSessionData *psession.CustomSessionData,
wantAdditionalClaims map[string]interface{},
wantAdditionalClaims map[string]any,
secrets v1.SecretInterface,
requestTime time.Time,
) {
@@ -5346,7 +5346,7 @@ func requireValidAccessTokenStorage(
func requireInvalidAccessTokenStorage(
t *testing.T,
body map[string]interface{},
body map[string]any,
storage fositeoauth2.CoreStorage,
) {
t.Helper()
@@ -5391,7 +5391,7 @@ func requireValidStoredRequest(
wantUsername string,
wantGroups []string,
wantCustomSessionData *psession.CustomSessionData,
wantAdditionalClaims map[string]interface{},
wantAdditionalClaims map[string]any,
requestTime time.Time,
) {
t.Helper()
@@ -5416,7 +5416,7 @@ func requireValidStoredRequest(
require.Equal(t, goodSubject, claims.Subject)
// Our custom claims from the authorize endpoint should still be set.
expectedExtra := map[string]interface{}{}
expectedExtra := map[string]any{}
if wantUsername != "" {
expectedExtra["username"] = wantUsername
}
@@ -5510,13 +5510,13 @@ func requireGarbageCollectTimeInDelta(t *testing.T, tokenString string, typeLabe
func requireValidIDToken(
t *testing.T,
body map[string]interface{},
body map[string]any,
jwtSigningKey *ecdsa.PrivateKey,
wantClientID string,
wantNonceValueInIDToken bool,
wantUsernameInIDToken string,
wantGroupsInIDToken []string,
wantAdditionalClaims map[string]interface{},
wantAdditionalClaims map[string]any,
wantIDTokenLifetimeSeconds int,
actualAccessToken string,
requestTime time.Time,
@@ -5532,19 +5532,19 @@ func requireValidIDToken(
token := oidctestutil.VerifyECDSAIDToken(t, goodIssuer, wantClientID, jwtSigningKey, idTokenString)
var claims struct {
Subject string `json:"sub"`
Audience []string `json:"aud"`
Issuer string `json:"iss"`
JTI string `json:"jti"`
Nonce string `json:"nonce"`
AccessTokenHash string `json:"at_hash"`
ExpiresAt int64 `json:"exp"`
IssuedAt int64 `json:"iat"`
RequestedAt int64 `json:"rat"`
AuthTime int64 `json:"auth_time"`
Groups []string `json:"groups"`
Username string `json:"username"`
AdditionalClaims map[string]interface{} `json:"additionalClaims"`
Subject string `json:"sub"`
Audience []string `json:"aud"`
Issuer string `json:"iss"`
JTI string `json:"jti"`
Nonce string `json:"nonce"`
AccessTokenHash string `json:"at_hash"`
ExpiresAt int64 `json:"exp"`
IssuedAt int64 `json:"iat"`
RequestedAt int64 `json:"rat"`
AuthTime int64 `json:"auth_time"`
Groups []string `json:"groups"`
Username string `json:"username"`
AdditionalClaims map[string]any `json:"additionalClaims"`
}
idTokenFields := []string{"sub", "aud", "iss", "jti", "auth_time", "exp", "iat", "rat", "azp", "at_hash"}
@@ -5562,7 +5562,7 @@ func requireValidIDToken(
}
// make sure that these are the only fields in the token
var m map[string]interface{}
var m map[string]any
require.NoError(t, token.Claims(&m))
require.ElementsMatch(t, idTokenFields, getMapKeys(m))
@@ -5578,7 +5578,7 @@ func requireValidIDToken(
require.Equal(t, goodIssuer, claims.Issuer)
require.NotEmpty(t, claims.JTI)
require.Equal(t, wantAdditionalClaims, claims.AdditionalClaims)
require.NotEqual(t, map[string]interface{}{}, claims.AdditionalClaims, "additionalClaims may never be present and empty in the id token")
require.NotEqual(t, map[string]any{}, claims.AdditionalClaims, "additionalClaims may never be present and empty in the id token")
if wantNonceValueInIDToken {
require.Equal(t, goodNonce, claims.Nonce)
@@ -5615,7 +5615,7 @@ func deepCopyRequestForm(r *http.Request) *http.Request {
return &http.Request{Form: copied}
}
func getMapKeys(m map[string]interface{}) []string {
func getMapKeys(m map[string]any) []string {
keys := make([]string, 0)
for key := range m {
keys = append(keys, key)
@@ -5623,8 +5623,8 @@ func getMapKeys(m map[string]interface{}) []string {
return keys
}
func toSliceOfInterface(s []string) []interface{} {
r := make([]interface{}, len(s))
func toSliceOfInterface(s []string) []any {
r := make([]any, len(s))
for i := range s {
r[i] = s[i]
}
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package tokenexchange
@@ -9,7 +9,7 @@ import (
"strings"
"github.com/ory/fosite"
"github.com/ory/fosite/handler/oauth2"
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
"github.com/ory/fosite/handler/openid"
"github.com/pkg/errors"
@@ -27,19 +27,19 @@ type stsParams struct {
requestedAudience string
}
func HandlerFactory(config fosite.Configurator, storage interface{}, strategy interface{}) interface{} {
func HandlerFactory(config fosite.Configurator, storage any, strategy any) any {
return &tokenExchangeHandler{
idTokenStrategy: strategy.(openid.OpenIDConnectTokenStrategy),
accessTokenStrategy: strategy.(oauth2.AccessTokenStrategy),
accessTokenStorage: storage.(oauth2.AccessTokenStorage),
accessTokenStrategy: strategy.(fositeoauth2.AccessTokenStrategy),
accessTokenStorage: storage.(fositeoauth2.AccessTokenStorage),
fositeConfig: config,
}
}
type tokenExchangeHandler struct {
idTokenStrategy openid.OpenIDConnectTokenStrategy
accessTokenStrategy oauth2.AccessTokenStrategy
accessTokenStorage oauth2.AccessTokenStorage
accessTokenStrategy fositeoauth2.AccessTokenStrategy
accessTokenStorage fositeoauth2.AccessTokenStorage
fositeConfig fosite.Configurator
}
@@ -248,7 +248,7 @@ func TestManager(t *testing.T) {
// Minimal check to ensure that the right endpoint was called
r.Equal(http.StatusOK, recorder.Code, "unexpected response:", recorder)
var body map[string]interface{}
var body map[string]any
r.NoError(json.Unmarshal(recorder.Body.Bytes(), &body))
r.Contains(body, "id_token")
r.Contains(body, "access_token")
@@ -19,7 +19,7 @@ const idTokenLifetimeOverrideKey contextKey = iota
// OpenIDConnectExplicitFactory is similar to the function of the same name in the fosite compose package,
// except it allows wrapping the IDTokenLifespanProvider.
func OpenIDConnectExplicitFactory(config fosite.Configurator, storage interface{}, strategy interface{}) interface{} {
func OpenIDConnectExplicitFactory(config fosite.Configurator, storage any, strategy any) any {
openIDConnectExplicitHandler := compose.OpenIDConnectExplicitFactory(config, storage, strategy).(*openid.OpenIDConnectExplicitHandler)
// Overwrite the config with a wrapper around the fosite.IDTokenLifespanProvider.
openIDConnectExplicitHandler.Config = &contextAwareIDTokenLifespanProvider{DelegateConfig: config}
@@ -28,7 +28,7 @@ func OpenIDConnectExplicitFactory(config fosite.Configurator, storage interface{
// OpenIDConnectRefreshFactory is similar to the function of the same name in the fosite compose package,
// except it allows wrapping the IDTokenLifespanProvider.
func OpenIDConnectRefreshFactory(config fosite.Configurator, _ interface{}, strategy interface{}) interface{} {
func OpenIDConnectRefreshFactory(config fosite.Configurator, _ any, strategy any) any {
openIDConnectRefreshHandler := compose.OpenIDConnectRefreshFactory(config, nil, strategy).(*openid.OpenIDConnectRefreshHandler)
// Overwrite the config with a wrapper around the fosite.IDTokenLifespanProvider.
openIDConnectRefreshHandler.Config = &contextAwareIDTokenLifespanProvider{DelegateConfig: config}
+5 -5
View File
@@ -76,12 +76,12 @@ const (
// Encoder is the encoding side of the securecookie.Codec interface.
type Encoder interface {
Encode(name string, value interface{}) (string, error)
Encode(name string, value any) (string, error)
}
// Decoder is the decoding side of the securecookie.Codec interface.
type Decoder interface {
Decode(name, value string, into interface{}) error
Decode(name, value string, into any) error
}
// Codec is both the encoding and decoding sides of the securecookie.Codec interface. It is
@@ -225,7 +225,7 @@ func DefaultOIDCTimeoutsConfiguration() timeouts.Configuration {
}
func FositeOauth2Helper(
oauthStore interface{},
oauthStore any,
issuer string,
hmacSecretOfLengthAtLeast32Func func() []byte,
jwksProvider jwks.DynamicJWKSProvider,
@@ -293,9 +293,9 @@ func FositeOauth2Helper(
// plog.Info("some error", FositeErrorForLog(err)...)
// ...
// }
func FositeErrorForLog(err error) []interface{} {
func FositeErrorForLog(err error) []any {
rfc6749Error := fosite.ErrorToRFC6749Error(err)
keysAndValues := make([]interface{}, 0)
keysAndValues := make([]any, 0)
keysAndValues = append(keysAndValues, "name")
keysAndValues = append(keysAndValues, rfc6749Error.Error()) // Error() returns the ErrorField
keysAndValues = append(keysAndValues, "status")
@@ -1,4 +1,4 @@
// Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2022-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package oidcclientvalidator
@@ -11,7 +11,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/oidcclientsecretstorage"
)
@@ -37,7 +37,7 @@ const (
// get the validation error for that case. It returns a bool to indicate if the client is valid,
// along with a slice of conditions containing more details, and the list of client secrets in the
// case that the client was valid.
func Validate(oidcClient *v1alpha1.OIDCClient, secret *corev1.Secret, minBcryptCost int) (bool, []*metav1.Condition, []string) {
func Validate(oidcClient *supervisorconfigv1alpha1.OIDCClient, secret *corev1.Secret, minBcryptCost int) (bool, []*metav1.Condition, []string) {
conds := make([]*metav1.Condition, 0, 3)
conds, clientSecrets := validateSecret(secret, conds, minBcryptCost)
@@ -55,7 +55,7 @@ func Validate(oidcClient *v1alpha1.OIDCClient, secret *corev1.Secret, minBcryptC
}
// validateAllowedScopes checks if allowedScopes is valid on the OIDCClient.
func validateAllowedScopes(oidcClient *v1alpha1.OIDCClient, conditions []*metav1.Condition) []*metav1.Condition {
func validateAllowedScopes(oidcClient *supervisorconfigv1alpha1.OIDCClient, conditions []*metav1.Condition) []*metav1.Condition {
m := make([]string, 0, 4)
if !allowedScopesContains(oidcClient, oidcapi.ScopeOpenID) {
@@ -95,7 +95,7 @@ func validateAllowedScopes(oidcClient *v1alpha1.OIDCClient, conditions []*metav1
}
// validateAllowedGrantTypes checks if allowedGrantTypes is valid on the OIDCClient.
func validateAllowedGrantTypes(oidcClient *v1alpha1.OIDCClient, conditions []*metav1.Condition) []*metav1.Condition {
func validateAllowedGrantTypes(oidcClient *supervisorconfigv1alpha1.OIDCClient, conditions []*metav1.Condition) []*metav1.Condition {
m := make([]string, 0, 3)
if !allowedGrantTypesContains(oidcClient, oidcapi.GrantTypeAuthorizationCode) {
@@ -207,18 +207,18 @@ func validateSecret(secret *corev1.Secret, conditions []*metav1.Condition, minBc
return conditions, storedClientSecrets
}
func allowedGrantTypesContains(haystack *v1alpha1.OIDCClient, needle string) bool {
func allowedGrantTypesContains(haystack *supervisorconfigv1alpha1.OIDCClient, needle string) bool {
for _, hay := range haystack.Spec.AllowedGrantTypes {
if hay == v1alpha1.GrantType(needle) {
if hay == supervisorconfigv1alpha1.GrantType(needle) {
return true
}
}
return false
}
func allowedScopesContains(haystack *v1alpha1.OIDCClient, needle string) bool {
func allowedScopesContains(haystack *supervisorconfigv1alpha1.OIDCClient, needle string) bool {
for _, hay := range haystack.Spec.AllowedScopes {
if hay == v1alpha1.Scope(needle) {
if hay == supervisorconfigv1alpha1.Scope(needle) {
return true
}
}
@@ -40,7 +40,7 @@ type Identity struct {
// The portion of the user's session data which is specific to the upstream identity provider type.
// Refer to the fields of psession.CustomSessionData whose types are specific to an identity provider type.
// Must not be nil.
IDPSpecificSessionData interface{}
IDPSpecificSessionData any
}
// IdentityLoginExtras are additional information that an identity provider may choose to determine
@@ -49,7 +49,7 @@ type Identity struct {
// refreshes. Its fields are optional and may be nil.
type IdentityLoginExtras struct {
// The downstream additional claims determined for this user in an identity provider-specific way, if any.
DownstreamAdditionalClaims map[string]interface{}
DownstreamAdditionalClaims map[string]any
// Login warnings to show the user after they exchange their downstream authcode, if any.
Warnings []string
@@ -76,7 +76,7 @@ type RefreshedIdentity struct {
// Refer to the fields of psession.CustomSessionData whose types are specific to an identity provider type.
// Set this to be the potentially updated IDP-specific session data. If no updates were required, then
// set this to nil.
IDPSpecificSessionData interface{}
IDPSpecificSessionData any
}
// UpstreamAuthorizeRequestState is the state capturing the downstream authorization request, used as a parameter to
@@ -117,7 +117,7 @@ type FederationDomainResolvedIdentityProvider interface {
// of the field which is specific to the upstream identity provider type. If the session's field is
// nil, then return nil.
// Refer to the fields of psession.CustomSessionData whose types are specific to an identity provider type.
CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) interface{}
CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) any
// ApplyIDPSpecificSessionDataToSession assigns the IDP-specific portion of the session data into a session.
// The IDP-specific session data provided to this function will be from an Identity that was returned by
@@ -125,7 +125,7 @@ type FederationDomainResolvedIdentityProvider interface {
// assumptions about the type of idpSpecificSessionData for casting, based upon how it chooses to return
// IDPSpecificSessionData in Identity structs. If the given session already has any IDP-specific session
// data, it should be overwritten by this function.
ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData interface{})
ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData any)
// UpstreamAuthorizeRedirectURL returns the URL to which the user's browser can be redirected to continue
// the downstream browser-based authorization flow. Returned errors should be of type fosite.RFC6749Error.
@@ -58,14 +58,14 @@ func (p *FederationDomainResolvedGitHubIdentityProvider) GetTransforms() *idtran
return p.Transforms
}
func (p *FederationDomainResolvedGitHubIdentityProvider) CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) interface{} {
func (p *FederationDomainResolvedGitHubIdentityProvider) CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) any {
if session.GitHub == nil {
return nil
}
return session.GitHub.Clone()
}
func (p *FederationDomainResolvedGitHubIdentityProvider) ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData interface{}) {
func (p *FederationDomainResolvedGitHubIdentityProvider) ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData any) {
session.GitHub = idpSpecificSessionData.(*psession.GitHubSessionData)
}
@@ -64,7 +64,7 @@ func (p *FederationDomainResolvedLDAPIdentityProvider) GetTransforms() *idtransf
return p.Transforms
}
func (p *FederationDomainResolvedLDAPIdentityProvider) CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) interface{} {
func (p *FederationDomainResolvedLDAPIdentityProvider) CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) any {
switch p.GetSessionProviderType() {
case psession.ProviderTypeLDAP:
if session.LDAP == nil {
@@ -83,7 +83,7 @@ func (p *FederationDomainResolvedLDAPIdentityProvider) CloneIDPSpecificSessionDa
}
}
func (p *FederationDomainResolvedLDAPIdentityProvider) ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData interface{}) {
func (p *FederationDomainResolvedLDAPIdentityProvider) ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData any) {
if p.GetSessionProviderType() == psession.ProviderTypeActiveDirectory {
session.ActiveDirectory = idpSpecificSessionData.(*psession.ActiveDirectorySessionData)
return
@@ -139,7 +139,7 @@ func (p *FederationDomainResolvedLDAPIdentityProvider) Login(
upstreamUsername := authenticateResponse.User.GetName()
upstreamGroups := authenticateResponse.User.GetGroups()
var sessionData interface{}
var sessionData any
switch p.GetSessionProviderType() {
case psession.ProviderTypeLDAP:
sessionData = &psession.LDAPSessionData{
@@ -86,14 +86,14 @@ func (p *FederationDomainResolvedOIDCIdentityProvider) GetTransforms() *idtransf
return p.Transforms
}
func (p *FederationDomainResolvedOIDCIdentityProvider) CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) interface{} {
func (p *FederationDomainResolvedOIDCIdentityProvider) CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) any {
if session.OIDC == nil {
return nil
}
return session.OIDC.Clone()
}
func (p *FederationDomainResolvedOIDCIdentityProvider) ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData interface{}) {
func (p *FederationDomainResolvedOIDCIdentityProvider) ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData any) {
session.OIDC = idpSpecificSessionData.(*psession.OIDCSessionData)
}
@@ -328,7 +328,7 @@ func (p *FederationDomainResolvedOIDCIdentityProvider) UpstreamRefresh(
}
func validateUpstreamSubjectAndIssuerUnchangedSinceInitialLogin(
mergedClaims map[string]interface{},
mergedClaims map[string]any,
s *psession.OIDCSessionData,
providerName string,
providerType psession.ProviderType,
@@ -364,7 +364,7 @@ func validateUpstreamSubjectAndIssuerUnchangedSinceInitialLogin(
return nil
}
func getString(m map[string]interface{}, key string) (string, bool) {
func getString(m map[string]any, key string) (string, bool) {
val, ok := m[key].(string)
return val, ok
}
@@ -389,7 +389,7 @@ func makeDownstreamOIDCSessionData(
const pleaseCheck = "please check configuration of OIDCIdentityProvider and the client in the " +
"upstream provider's API/UI and try to get a refresh token if possible"
logKV := []interface{}{
logKV := []any{
"identityProviderResourceName", oidcUpstream.GetResourceName(),
"scopes", oidcUpstream.GetScopes(),
"additionalParams", oidcUpstream.GetAdditionalAuthcodeParams(),
@@ -428,7 +428,7 @@ func makeDownstreamOIDCSessionData(
// getIdentityFromUpstreamIDToken returns the mapped subject, username, and group names, in that order.
func getIdentityFromUpstreamIDToken(
upstreamIDPConfig upstreamprovider.UpstreamOIDCIdentityProviderI,
idTokenClaims map[string]interface{},
idTokenClaims map[string]any,
idpDisplayName string,
) (string, string, []string, error) {
subject, username, err := getDownstreamSubjectAndUpstreamUsernameFromUpstreamIDToken(upstreamIDPConfig, idTokenClaims, idpDisplayName)
@@ -447,9 +447,9 @@ func getIdentityFromUpstreamIDToken(
// mapAdditionalClaimsFromUpstreamIDToken returns the additionalClaims mapped from the upstream token, if any.
func mapAdditionalClaimsFromUpstreamIDToken(
upstreamIDPConfig upstreamprovider.UpstreamOIDCIdentityProviderI,
idTokenClaims map[string]interface{},
) map[string]interface{} {
mapped := make(map[string]interface{}, len(upstreamIDPConfig.GetAdditionalClaimMappings()))
idTokenClaims map[string]any,
) map[string]any {
mapped := make(map[string]any, len(upstreamIDPConfig.GetAdditionalClaimMappings()))
for downstreamClaimName, upstreamClaimName := range upstreamIDPConfig.GetAdditionalClaimMappings() {
upstreamClaimValue, ok := idTokenClaims[upstreamClaimName]
if !ok {
@@ -467,7 +467,7 @@ func mapAdditionalClaimsFromUpstreamIDToken(
func getDownstreamSubjectAndUpstreamUsernameFromUpstreamIDToken(
upstreamIDPConfig upstreamprovider.UpstreamOIDCIdentityProviderI,
idTokenClaims map[string]interface{},
idTokenClaims map[string]any,
idpDisplayName string,
) (string, string, error) {
// The spec says the "sub" claim is only unique per issuer,
@@ -519,7 +519,7 @@ func getDownstreamSubjectAndUpstreamUsernameFromUpstreamIDToken(
return subject, username, nil
}
func extractStringClaimValue(claimName string, upstreamIDPName string, idTokenClaims map[string]interface{}) (string, error) {
func extractStringClaimValue(claimName string, upstreamIDPName string, idTokenClaims map[string]any) (string, error) {
value, ok := idTokenClaims[claimName]
if !ok {
plog.Warning(
@@ -563,7 +563,7 @@ func mappedUsernameFromUpstreamOIDCSubject(upstreamIssuerAsString string, upstre
// in the provided map of claims. It returns an error when the claim exists but its value cannot be parsed.
func getGroupsFromUpstreamIDToken(
upstreamIDPConfig upstreamprovider.UpstreamOIDCIdentityProviderI,
idTokenClaims map[string]interface{},
idTokenClaims map[string]any,
) ([]string, error) {
groupsClaimName := upstreamIDPConfig.GetGroupsClaim()
if groupsClaimName == "" {
@@ -593,7 +593,7 @@ func getGroupsFromUpstreamIDToken(
return groupsAsArray, nil
}
func extractGroups(groupsAsInterface interface{}) ([]string, bool) {
func extractGroups(groupsAsInterface any) ([]string, bool) {
groupsAsString, okAsString := groupsAsInterface.(string)
if okAsString {
return []string{groupsAsString}, true
@@ -604,7 +604,7 @@ func extractGroups(groupsAsInterface interface{}) ([]string, bool) {
return groupsAsStringArray, true
}
groupsAsInterfaceArray, okAsArray := groupsAsInterface.([]interface{})
groupsAsInterfaceArray, okAsArray := groupsAsInterface.([]any)
if !okAsArray {
return nil, false
}
@@ -15,18 +15,18 @@ func TestMapAdditionalClaimsFromUpstreamIDToken(t *testing.T) {
tests := []struct {
name string
additionalClaimMappings map[string]string
upstreamClaims map[string]interface{}
wantClaims map[string]interface{}
upstreamClaims map[string]any
wantClaims map[string]any
}{
{
name: "happy path",
additionalClaimMappings: map[string]string{
"email": "notification_email",
},
upstreamClaims: map[string]interface{}{
upstreamClaims: map[string]any{
"notification_email": "test@example.com",
},
wantClaims: map[string]interface{}{
wantClaims: map[string]any{
"email": "test@example.com",
},
},
@@ -35,20 +35,20 @@ func TestMapAdditionalClaimsFromUpstreamIDToken(t *testing.T) {
additionalClaimMappings: map[string]string{
"email": "email",
},
upstreamClaims: map[string]interface{}{},
wantClaims: map[string]interface{}{},
upstreamClaims: map[string]any{},
wantClaims: map[string]any{},
},
{
name: "complex",
additionalClaimMappings: map[string]string{
"complex": "complex",
},
upstreamClaims: map[string]interface{}{
upstreamClaims: map[string]any{
"complex": map[string]string{
"subClaim": "subValue",
},
},
wantClaims: map[string]interface{}{
wantClaims: map[string]any{
"complex": map[string]string{
"subClaim": "subValue",
},
@@ -8,7 +8,7 @@ import (
"time"
"github.com/ory/fosite"
"github.com/ory/fosite/handler/oauth2"
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
"github.com/ory/fosite/handler/openid"
fositepkce "github.com/ory/fosite/handler/pkce"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
@@ -27,7 +27,7 @@ import (
type KubeStorage struct {
clientManager fosite.ClientManager
authorizationCodeStorage oauth2.AuthorizeCodeStorage
authorizationCodeStorage fositeoauth2.AuthorizeCodeStorage
pkceStorage fositepkce.PKCERequestStorage
oidcStorage openid.OpenIDConnectRequestStorage
accessTokenStorage accesstoken.RevocationStorage
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package strategy
@@ -9,7 +9,7 @@ import (
"github.com/ory/fosite"
"github.com/ory/fosite/compose"
"github.com/ory/fosite/handler/oauth2"
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
errorsx "github.com/pkg/errors"
"go.pinniped.dev/internal/federationdomain/storage"
@@ -44,7 +44,7 @@ type DynamicOauth2HMACStrategy struct {
keyFunc func() []byte
}
var _ oauth2.CoreStrategy = &DynamicOauth2HMACStrategy{}
var _ fositeoauth2.CoreStrategy = &DynamicOauth2HMACStrategy{}
func NewDynamicOauth2HMACStrategy(
fositeConfig *fosite.Config,
@@ -156,6 +156,6 @@ func (s *DynamicOauth2HMACStrategy) ValidateAuthorizeCode(
return s.delegate().ValidateAuthorizeCode(ctx, requester, replacePrefix(token, pinAuthcodePrefix, oryAuthcodePrefix))
}
func (s *DynamicOauth2HMACStrategy) delegate() *oauth2.HMACSHAStrategy {
func (s *DynamicOauth2HMACStrategy) delegate() *fositeoauth2.HMACSHAStrategy {
return compose.NewOAuth2HMACStrategy(storage.NewDynamicGlobalSecretConfig(s.fositeConfig, s.keyFunc))
}
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package strategy
@@ -69,7 +69,7 @@ func (s *DynamicOpenIDConnectECDSAStrategy) GenerateIDToken(
return "", fosite.ErrServerError.WithWrap(constable.Error("JWK must be of type ecdsa"))
}
keyGetter := func(context.Context) (interface{}, error) {
keyGetter := func(context.Context) (any, error) {
return key, nil
}
strategy := compose.NewOpenIDConnectStrategy(keyGetter, s.fositeConfig)
@@ -10,7 +10,7 @@ import (
"golang.org/x/oauth2"
"k8s.io/apimachinery/pkg/types"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
"go.pinniped.dev/internal/authenticators"
"go.pinniped.dev/internal/setutil"
"go.pinniped.dev/pkg/oidcclient/nonce"
@@ -162,12 +162,12 @@ type UpstreamGithubIdentityProviderI interface {
// GetUsernameAttribute returns the attribute from the GitHub API user response to use for the downstream username.
// See https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user.
// Note that this is a constructed value - do not expect that the result will exactly match one of the JSON fields.
GetUsernameAttribute() v1alpha1.GitHubUsernameAttribute
GetUsernameAttribute() idpv1alpha1.GitHubUsernameAttribute
// GetGroupNameAttribute returns the attribute from the GitHub API team response to use for the downstream group names.
// See https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user.
// Note that this is a constructed value - do not expect that the result will exactly match one of the JSON fields.
GetGroupNameAttribute() v1alpha1.GitHubGroupNameAttribute
GetGroupNameAttribute() idpv1alpha1.GitHubGroupNameAttribute
// GetAllowedOrganizations returns a list of organizations configured to allow authentication.
// If this list has contents, a user must have membership in at least one of these organizations to log in,
@@ -9,9 +9,9 @@ import (
"time"
"github.com/ory/fosite"
"github.com/ory/fosite/handler/oauth2"
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
"go.pinniped.dev/internal/constable"
@@ -40,7 +40,7 @@ const (
)
type RevocationStorage interface {
oauth2.AccessTokenStorage
fositeoauth2.AccessTokenStorage
RevokeAccessToken(ctx context.Context, requestID string) error
}
@@ -115,7 +115,7 @@ func (a *accessTokenStorage) getSession(ctx context.Context, signature string) (
session := newValidEmptyAccessTokenSession()
rv, err := a.storage.Get(ctx, signature, session)
if errors.IsNotFound(err) {
if apierrors.IsNotFound(err) {
return nil, "", fosite.ErrNotFound.WithWrap(err).WithDebug(err.Error())
}
@@ -335,7 +335,7 @@ func TestReadFromSecret(t *testing.T) {
Username: "snorlax",
Subject: "panda",
Claims: &jwt.IDTokenClaims{JTI: "xyz"},
Headers: &jwt.Headers{Extra: map[string]interface{}{"myheader": "foo"}},
Headers: &jwt.Headers{Extra: map[string]any{"myheader": "foo"}},
},
Custom: &psession.CustomSessionData{
Username: "fake-username",
@@ -10,9 +10,9 @@ import (
"time"
"github.com/ory/fosite"
"github.com/ory/fosite/handler/oauth2"
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
"go.pinniped.dev/internal/constable"
@@ -40,7 +40,7 @@ const (
authorizeCodeStorageVersion = "8"
)
var _ oauth2.AuthorizeCodeStorage = &authorizeCodeStorage{}
var _ fositeoauth2.AuthorizeCodeStorage = &authorizeCodeStorage{}
type authorizeCodeStorage struct {
storage crud.Storage
@@ -53,7 +53,7 @@ type Session struct {
Version string `json:"version"`
}
func New(secrets corev1client.SecretInterface, clock func() time.Time, sessionStorageLifetime timeouts.StorageLifetime) oauth2.AuthorizeCodeStorage {
func New(secrets corev1client.SecretInterface, clock func() time.Time, sessionStorageLifetime timeouts.StorageLifetime) fositeoauth2.AuthorizeCodeStorage {
return &authorizeCodeStorage{storage: crud.New(TypeLabelValue, secrets, clock), lifetime: sessionStorageLifetime}
}
@@ -131,7 +131,7 @@ func (a *authorizeCodeStorage) InvalidateAuthorizeCodeSession(ctx context.Contex
session.Active = false
if _, err := a.storage.Update(ctx, signature, rv, session); err != nil {
if errors.IsConflict(err) {
if apierrors.IsConflict(err) {
return &errSerializationFailureWithCause{cause: err}
}
return err
@@ -144,7 +144,7 @@ func (a *authorizeCodeStorage) getSession(ctx context.Context, signature string)
session := NewValidEmptyAuthorizeCodeSession()
rv, err := a.storage.Get(ctx, signature, session)
if errors.IsNotFound(err) {
if apierrors.IsNotFound(err) {
return nil, "", fosite.ErrNotFound.WithWrap(err).WithDebug(err.Error())
}
@@ -18,7 +18,7 @@ import (
"github.com/go-jose/go-jose/v3"
fuzz "github.com/google/gofuzz"
"github.com/ory/fosite"
"github.com/ory/fosite/handler/oauth2"
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
"github.com/ory/fosite/handler/openid"
"github.com/ory/fosite/token/jwt"
"github.com/pkg/errors"
@@ -276,7 +276,7 @@ func TestCreateWithWrongRequesterDataTypes(t *testing.T) {
require.EqualError(t, err, "requester's client must be of type clientregistry.Client")
}
func makeTestSubject(lifetimeFunc timeouts.StorageLifetime) (context.Context, *fake.Clientset, corev1client.SecretInterface, oauth2.AuthorizeCodeStorage) {
func makeTestSubject(lifetimeFunc timeouts.StorageLifetime) (context.Context, *fake.Clientset, corev1client.SecretInterface, fositeoauth2.AuthorizeCodeStorage) {
client := fake.NewSimpleClientset()
secrets := client.CoreV1().Secrets(namespace)
return context.Background(),
@@ -324,24 +324,24 @@ func TestFuzzAndJSONNewValidEmptyAuthorizeCodeSession(t *testing.T) {
*fs = pinnipedSession
},
// these types contain an interface{} that we need to handle
// these types contain an any that we need to handle
// this is safe because we explicitly provide the PinnipedSession concrete type
func(value *map[string]interface{}, c fuzz.Continue) {
func(value *map[string]any, c fuzz.Continue) {
// cover all the JSON data types just in case
*value = map[string]interface{}{
*value = map[string]any{
randString(c): float64(c.Intn(1 << 32)),
randString(c): map[string]interface{}{
randString(c): []interface{}{float64(c.Intn(1 << 32))},
randString(c): map[string]interface{}{
randString(c): map[string]any{
randString(c): []any{float64(c.Intn(1 << 32))},
randString(c): map[string]any{
randString(c): nil,
randString(c): map[string]interface{}{
randString(c): map[string]any{
randString(c): c.RandBool(),
},
},
},
}
},
// JWK contains an interface{} Key that we need to handle
// JWK contains an any Key that we need to handle
// this is safe because JWK explicitly implements JSON marshalling and unmarshalling
func(jwk *jose.JSONWebKey, c fuzz.Continue) {
key, _, err := ed25519.GenerateKey(c)
@@ -471,7 +471,7 @@ func TestReadFromSecret(t *testing.T) {
Username: "snorlax",
Subject: "panda",
Claims: &jwt.IDTokenClaims{JTI: "xyz"},
Headers: &jwt.Headers{Extra: map[string]interface{}{"myheader": "foo"}},
Headers: &jwt.Headers{Extra: map[string]any{"myheader": "foo"}},
},
Custom: &psession.CustomSessionData{
Username: "fake-username",

Some files were not shown because too many files have changed in this diff Show More