Add integration tests for UpstreamOIDCProvider status.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
parent
cbd71df574
commit
d68a4b85f4
@ -78,6 +78,39 @@ func TestGetAPIResourceList(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
group: metav1.APIGroup{
|
||||||
|
Name: "idp.supervisor.pinniped.dev",
|
||||||
|
Versions: []metav1.GroupVersionForDiscovery{
|
||||||
|
{
|
||||||
|
GroupVersion: "idp.supervisor.pinniped.dev/v1alpha1",
|
||||||
|
Version: "v1alpha1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||||
|
GroupVersion: "idp.supervisor.pinniped.dev/v1alpha1",
|
||||||
|
Version: "v1alpha1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
resourceByVersion: map[string][]metav1.APIResource{
|
||||||
|
"idp.supervisor.pinniped.dev/v1alpha1": {
|
||||||
|
{
|
||||||
|
Name: "upstreamoidcproviders",
|
||||||
|
SingularName: "upstreamoidcprovider",
|
||||||
|
Namespaced: true,
|
||||||
|
Kind: "UpstreamOIDCProvider",
|
||||||
|
Verbs: []string{"delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"},
|
||||||
|
Categories: []string{"pinniped", "pinniped-idp", "pinniped-idps"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "upstreamoidcproviders/status",
|
||||||
|
Namespaced: true,
|
||||||
|
Kind: "UpstreamOIDCProvider",
|
||||||
|
Verbs: []string{"get", "patch", "update"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
group: metav1.APIGroup{
|
group: metav1.APIGroup{
|
||||||
Name: "config.concierge.pinniped.dev",
|
Name: "config.concierge.pinniped.dev",
|
||||||
@ -155,10 +188,14 @@ func TestGetAPIResourceList(t *testing.T) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, a := range r.APIResources {
|
for _, a := range r.APIResources {
|
||||||
if a.Kind != "TokenCredentialRequest" {
|
|
||||||
assert.Containsf(t, a.Categories, "pinniped", "expected resource %q to be in the 'pinniped' category", a.Name)
|
|
||||||
}
|
|
||||||
assert.NotContainsf(t, a.Categories, "all", "expected resource %q not to be in the 'all' category", a.Name)
|
assert.NotContainsf(t, a.Categories, "all", "expected resource %q not to be in the 'all' category", a.Name)
|
||||||
|
if strings.HasSuffix(a.Name, "/status") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if a.Kind == "TokenCredentialRequest" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
assert.Containsf(t, a.Categories, "pinniped", "expected resource %q to be in the 'pinniped' category", a.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
159
test/integration/supervisor_upstream_test.go
Normal file
159
test/integration/supervisor_upstream_test.go
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
|
||||||
|
"go.pinniped.dev/generated/1.19/apis/supervisor/idp/v1alpha1"
|
||||||
|
"go.pinniped.dev/test/library"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSupervisorUpstreamOIDCDiscovery(t *testing.T) {
|
||||||
|
library.SkipUnlessIntegration(t)
|
||||||
|
|
||||||
|
t.Run("invalid missing secret and bad issuer", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
spec := v1alpha1.UpstreamOIDCProviderSpec{
|
||||||
|
Issuer: "https://127.0.0.1:444444/issuer",
|
||||||
|
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
|
||||||
|
AdditionalScopes: []string{"email", "profile"},
|
||||||
|
},
|
||||||
|
Client: v1alpha1.OIDCClient{
|
||||||
|
SecretName: "does-not-exist",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
upstream := makeTestUpstream(t, spec, v1alpha1.PhaseError)
|
||||||
|
expectUpstreamConditions(t, upstream, []v1alpha1.Condition{
|
||||||
|
{
|
||||||
|
Type: "ClientCredentialsValid",
|
||||||
|
Status: v1alpha1.ConditionFalse,
|
||||||
|
Reason: "SecretNotFound",
|
||||||
|
Message: `secret "does-not-exist" not found`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "OIDCDiscoverySucceeded",
|
||||||
|
Status: v1alpha1.ConditionFalse,
|
||||||
|
Reason: "Unreachable",
|
||||||
|
Message: `failed to perform OIDC discovery against "https://127.0.0.1:444444/issuer": Get "https://127.0.0.1:444444/issuer/.well-known/openid-configuration": dial tcp: address 444444: invalid port`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("valid", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
spec := v1alpha1.UpstreamOIDCProviderSpec{
|
||||||
|
Issuer: "https://accounts.google.com", // Use Google as an example of a valid OIDC issuer for now.
|
||||||
|
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
|
||||||
|
AdditionalScopes: []string{"email", "profile"},
|
||||||
|
},
|
||||||
|
Client: v1alpha1.OIDCClient{
|
||||||
|
SecretName: makeTestClientCredsSecret(t, "test-client-id", "test-client-secret").Name,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
upstream := makeTestUpstream(t, spec, v1alpha1.PhaseReady)
|
||||||
|
expectUpstreamConditions(t, upstream, []v1alpha1.Condition{
|
||||||
|
{
|
||||||
|
Type: "ClientCredentialsValid",
|
||||||
|
Status: v1alpha1.ConditionTrue,
|
||||||
|
Reason: "Success",
|
||||||
|
Message: "loaded client credentials",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "OIDCDiscoverySucceeded",
|
||||||
|
Status: v1alpha1.ConditionTrue,
|
||||||
|
Reason: "Success",
|
||||||
|
Message: "discovered issuer configuration",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func expectUpstreamConditions(t *testing.T, upstream *v1alpha1.UpstreamOIDCProvider, expected []v1alpha1.Condition) {
|
||||||
|
t.Helper()
|
||||||
|
normalized := make([]v1alpha1.Condition, 0, len(upstream.Status.Conditions))
|
||||||
|
for _, c := range upstream.Status.Conditions {
|
||||||
|
c.ObservedGeneration = 0
|
||||||
|
c.LastTransitionTime = metav1.Time{}
|
||||||
|
normalized = append(normalized, c)
|
||||||
|
}
|
||||||
|
require.ElementsMatch(t, expected, normalized)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeTestClientCredsSecret(t *testing.T, clientID string, clientSecret string) *corev1.Secret {
|
||||||
|
t.Helper()
|
||||||
|
env := library.IntegrationEnv(t)
|
||||||
|
client := library.NewClientset(t)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
created, err := client.CoreV1().Secrets(env.SupervisorNamespace).Create(ctx, &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Namespace: env.SupervisorNamespace,
|
||||||
|
GenerateName: "test-client-creds-",
|
||||||
|
Labels: map[string]string{"pinniped.dev/test": ""},
|
||||||
|
Annotations: map[string]string{"pinniped.dev/testName": t.Name()},
|
||||||
|
},
|
||||||
|
Type: "secrets.pinniped.dev/oidc-client",
|
||||||
|
StringData: map[string]string{
|
||||||
|
"clientID": clientID,
|
||||||
|
"clientSecret": clientSecret,
|
||||||
|
},
|
||||||
|
}, metav1.CreateOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
t.Cleanup(func() {
|
||||||
|
err := client.CoreV1().Secrets(env.SupervisorNamespace).Delete(context.Background(), created.Name, metav1.DeleteOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
t.Logf("created test client credentials Secret %s", created.Name)
|
||||||
|
return created
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeTestUpstream(t *testing.T, spec v1alpha1.UpstreamOIDCProviderSpec, expectedPhase v1alpha1.UpstreamOIDCProviderPhase) *v1alpha1.UpstreamOIDCProvider {
|
||||||
|
t.Helper()
|
||||||
|
env := library.IntegrationEnv(t)
|
||||||
|
client := library.NewSupervisorClientset(t)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// Create the UpstreamOIDCProvider using GenerateName to get a random name.
|
||||||
|
created, err := client.IDPV1alpha1().
|
||||||
|
UpstreamOIDCProviders(env.SupervisorNamespace).
|
||||||
|
Create(ctx, &v1alpha1.UpstreamOIDCProvider{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Namespace: env.SupervisorNamespace,
|
||||||
|
GenerateName: "test-upstream-",
|
||||||
|
Labels: map[string]string{"pinniped.dev/test": ""},
|
||||||
|
Annotations: map[string]string{"pinniped.dev/testName": t.Name()},
|
||||||
|
},
|
||||||
|
Spec: spec,
|
||||||
|
}, metav1.CreateOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Always clean this up after this point.
|
||||||
|
t.Cleanup(func() {
|
||||||
|
err := client.IDPV1alpha1().
|
||||||
|
UpstreamOIDCProviders(env.SupervisorNamespace).
|
||||||
|
Delete(context.Background(), created.Name, metav1.DeleteOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
t.Logf("created test UpstreamOIDCProvider %s", created.Name)
|
||||||
|
|
||||||
|
// Wait for the UpstreamOIDCProvider to enter the expected phase (or time out).
|
||||||
|
var result *v1alpha1.UpstreamOIDCProvider
|
||||||
|
require.Eventuallyf(t, func() bool {
|
||||||
|
var err error
|
||||||
|
result, err = client.IDPV1alpha1().
|
||||||
|
UpstreamOIDCProviders(created.Namespace).Get(ctx, created.Name, metav1.GetOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
return result.Status.Phase == expectedPhase
|
||||||
|
}, 60*time.Second, 1*time.Second, "expected the UpstreamOIDCProvider to go into phase %s", expectedPhase)
|
||||||
|
return result
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user