diff --git a/test/integration/cli_test.go b/test/integration/cli_test.go index a859dcac..cc8a4ac0 100644 --- a/test/integration/cli_test.go +++ b/test/integration/cli_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package integration @@ -65,6 +65,7 @@ func TestCLIGetKubeconfigStaticToken(t *testing.T) { args: []string{ "get", "kubeconfig", "--static-token", env.TestUser.Token, + "--concierge-api-group-suffix", env.APIGroupSuffix, "--concierge-namespace", env.ConciergeNamespace, "--concierge-authenticator-type", "webhook", "--concierge-authenticator-name", authenticator.Name, diff --git a/test/integration/client_test.go b/test/integration/client_test.go index 64dd1aba..67f23083 100644 --- a/test/integration/client_test.go +++ b/test/integration/client_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package integration @@ -13,8 +13,8 @@ import ( "github.com/stretchr/testify/require" clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1" - "go.pinniped.dev/internal/client" "go.pinniped.dev/internal/here" + "go.pinniped.dev/pkg/conciergeclient" "go.pinniped.dev/test/library" ) @@ -69,10 +69,18 @@ func TestClient(t *testing.T) { // Using the CA bundle and host from the current (admin) kubeconfig, do the token exchange. clientConfig := library.NewClientConfig(t) + client, err := conciergeclient.New( + conciergeclient.WithNamespace(env.ConciergeNamespace), + conciergeclient.WithCABundle(string(clientConfig.CAData)), + conciergeclient.WithEndpoint(clientConfig.Host), + conciergeclient.WithAuthenticator("webhook", webhook.Name), + conciergeclient.WithAPIGroupSuffix(env.APIGroupSuffix), + ) + require.NoError(t, err) var resp *clientauthenticationv1beta1.ExecCredential assert.Eventually(t, func() bool { - resp, err = client.ExchangeToken(ctx, env.ConciergeNamespace, webhook, env.TestUser.Token, string(clientConfig.CAData), clientConfig.Host) + resp, err = client.ExchangeToken(ctx, env.TestUser.Token) return err == nil }, 10*time.Second, 500*time.Millisecond) require.NoError(t, err) diff --git a/test/integration/concierge_api_serving_certs_test.go b/test/integration/concierge_api_serving_certs_test.go index 2225bd96..e2138457 100644 --- a/test/integration/concierge_api_serving_certs_test.go +++ b/test/integration/concierge_api_serving_certs_test.go @@ -79,7 +79,7 @@ func TestAPIServingCertificateAutoCreationAndRotation(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() - const apiServiceName = "v1alpha1.login.concierge.pinniped.dev" + apiServiceName := "v1alpha1.login.concierge." + env.APIGroupSuffix // Get the initial auto-generated version of the Secret. secret, err := kubeClient.CoreV1().Secrets(env.ConciergeNamespace).Get(ctx, defaultServingCertResourceName, metav1.GetOptions{}) diff --git a/test/integration/e2e_test.go b/test/integration/e2e_test.go index 5afa4c9d..2c9ce325 100644 --- a/test/integration/e2e_test.go +++ b/test/integration/e2e_test.go @@ -138,6 +138,7 @@ func TestE2EFullIntegration(t *testing.T) { // Run "pinniped get kubeconfig" to get a kubeconfig YAML. kubeconfigYAML, stderr := runPinnipedCLI(t, pinnipedExe, "get", "kubeconfig", + "--concierge-api-group-suffix", env.APIGroupSuffix, "--concierge-namespace", env.ConciergeNamespace, "--concierge-authenticator-type", "jwt", "--concierge-authenticator-name", authenticator.Name, diff --git a/test/integration/kube_api_discovery_test.go b/test/integration/kube_api_discovery_test.go index fd58b065..ed82226d 100644 --- a/test/integration/kube_api_discovery_test.go +++ b/test/integration/kube_api_discovery_test.go @@ -1,46 +1,60 @@ -// Copyright 2020 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package integration import ( + "fmt" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "go.pinniped.dev/test/library" ) func TestGetAPIResourceList(t *testing.T) { - library.SkipUnlessIntegration(t) + env := library.IntegrationEnv(t) client := library.NewClientset(t) groups, resources, err := client.Discovery().ServerGroupsAndResources() require.NoError(t, err) + makeGV := func(firstSegment, secondSegment string) schema.GroupVersion { + return schema.GroupVersion{ + Group: fmt.Sprintf("%s.%s.%s", firstSegment, secondSegment, env.APIGroupSuffix), + Version: "v1alpha1", + } + } + loginConciergeGV := makeGV("login", "concierge") + authenticationConciergeGV := makeGV("authentication", "concierge") + configConciergeGV := makeGV("config", "concierge") + idpSupervisorGV := makeGV("idp", "supervisor") + configSupervisorGV := makeGV("config", "supervisor") + tests := []struct { group metav1.APIGroup resourceByVersion map[string][]metav1.APIResource }{ { group: metav1.APIGroup{ - Name: "login.concierge.pinniped.dev", + Name: loginConciergeGV.Group, Versions: []metav1.GroupVersionForDiscovery{ { - GroupVersion: "login.concierge.pinniped.dev/v1alpha1", - Version: "v1alpha1", + GroupVersion: loginConciergeGV.String(), + Version: loginConciergeGV.Version, }, }, PreferredVersion: metav1.GroupVersionForDiscovery{ - GroupVersion: "login.concierge.pinniped.dev/v1alpha1", - Version: "v1alpha1", + GroupVersion: loginConciergeGV.String(), + Version: loginConciergeGV.Version, }, }, resourceByVersion: map[string][]metav1.APIResource{ - "login.concierge.pinniped.dev/v1alpha1": { + loginConciergeGV.String(): { { Name: "tokencredentialrequests", Kind: "TokenCredentialRequest", @@ -53,20 +67,20 @@ func TestGetAPIResourceList(t *testing.T) { }, { group: metav1.APIGroup{ - Name: "config.supervisor.pinniped.dev", + Name: configSupervisorGV.Group, Versions: []metav1.GroupVersionForDiscovery{ { - GroupVersion: "config.supervisor.pinniped.dev/v1alpha1", - Version: "v1alpha1", + GroupVersion: configSupervisorGV.String(), + Version: configSupervisorGV.Version, }, }, PreferredVersion: metav1.GroupVersionForDiscovery{ - GroupVersion: "config.supervisor.pinniped.dev/v1alpha1", - Version: "v1alpha1", + GroupVersion: configSupervisorGV.String(), + Version: configSupervisorGV.Version, }, }, resourceByVersion: map[string][]metav1.APIResource{ - "config.supervisor.pinniped.dev/v1alpha1": { + configSupervisorGV.String(): { { Name: "federationdomains", SingularName: "federationdomain", @@ -80,20 +94,20 @@ func TestGetAPIResourceList(t *testing.T) { }, { group: metav1.APIGroup{ - Name: "idp.supervisor.pinniped.dev", + Name: idpSupervisorGV.Group, Versions: []metav1.GroupVersionForDiscovery{ { - GroupVersion: "idp.supervisor.pinniped.dev/v1alpha1", - Version: "v1alpha1", + GroupVersion: idpSupervisorGV.String(), + Version: idpSupervisorGV.Version, }, }, PreferredVersion: metav1.GroupVersionForDiscovery{ - GroupVersion: "idp.supervisor.pinniped.dev/v1alpha1", - Version: "v1alpha1", + GroupVersion: idpSupervisorGV.String(), + Version: idpSupervisorGV.Version, }, }, resourceByVersion: map[string][]metav1.APIResource{ - "idp.supervisor.pinniped.dev/v1alpha1": { + idpSupervisorGV.String(): { { Name: "oidcidentityproviders", SingularName: "oidcidentityprovider", @@ -113,20 +127,20 @@ func TestGetAPIResourceList(t *testing.T) { }, { group: metav1.APIGroup{ - Name: "config.concierge.pinniped.dev", + Name: configConciergeGV.Group, Versions: []metav1.GroupVersionForDiscovery{ { - GroupVersion: "config.concierge.pinniped.dev/v1alpha1", - Version: "v1alpha1", + GroupVersion: configConciergeGV.String(), + Version: configConciergeGV.Version, }, }, PreferredVersion: metav1.GroupVersionForDiscovery{ - GroupVersion: "config.concierge.pinniped.dev/v1alpha1", - Version: "v1alpha1", + GroupVersion: configConciergeGV.String(), + Version: configConciergeGV.Version, }, }, resourceByVersion: map[string][]metav1.APIResource{ - "config.concierge.pinniped.dev/v1alpha1": { + configConciergeGV.String(): { { Name: "credentialissuers", SingularName: "credentialissuer", @@ -140,20 +154,20 @@ func TestGetAPIResourceList(t *testing.T) { }, { group: metav1.APIGroup{ - Name: "authentication.concierge.pinniped.dev", + Name: authenticationConciergeGV.Group, Versions: []metav1.GroupVersionForDiscovery{ { - GroupVersion: "authentication.concierge.pinniped.dev/v1alpha1", - Version: "v1alpha1", + GroupVersion: authenticationConciergeGV.String(), + Version: authenticationConciergeGV.Version, }, }, PreferredVersion: metav1.GroupVersionForDiscovery{ - GroupVersion: "authentication.concierge.pinniped.dev/v1alpha1", - Version: "v1alpha1", + GroupVersion: authenticationConciergeGV.String(), + Version: authenticationConciergeGV.Version, }, }, resourceByVersion: map[string][]metav1.APIResource{ - "authentication.concierge.pinniped.dev/v1alpha1": { + authenticationConciergeGV.String(): { { Name: "webhookauthenticators", SingularName: "webhookauthenticator", @@ -182,7 +196,7 @@ func TestGetAPIResourceList(t *testing.T) { testedGroups[tt.group.Name] = true } for _, g := range groups { - if !strings.Contains(g.Name, "pinniped.dev") { + if !strings.Contains(g.Name, env.APIGroupSuffix) { continue } assert.Truef(t, testedGroups[g.Name], "expected group %q to have assertions defined", g.Name) @@ -192,7 +206,7 @@ func TestGetAPIResourceList(t *testing.T) { t.Run("every API categorized appropriately", func(t *testing.T) { t.Parallel() for _, r := range resources { - if !strings.Contains(r.GroupVersion, "pinniped.dev") { + if !strings.Contains(r.GroupVersion, env.APIGroupSuffix) { continue } for _, a := range r.APIResources { @@ -208,7 +222,7 @@ func TestGetAPIResourceList(t *testing.T) { t.Run("Pinniped resources do not have short names", func(t *testing.T) { t.Parallel() for _, r := range resources { - if !strings.Contains(r.GroupVersion, "pinniped.dev") { + if !strings.Contains(r.GroupVersion, env.APIGroupSuffix) { continue } for _, a := range r.APIResources { diff --git a/test/integration/kubeclient_test.go b/test/integration/kubeclient_test.go index f65026ba..f225df36 100644 --- a/test/integration/kubeclient_test.go +++ b/test/integration/kubeclient_test.go @@ -69,6 +69,7 @@ func TestKubeClientOwnerRef(t *testing.T) { Name: parentSecret.Name, UID: parentSecret.UID, } + _ = env.APIGroupSuffix // TODO: wire API group into kubeclient. ownerRefClient, err := kubeclient.New( kubeclient.WithMiddleware(ownerref.New(ref)), kubeclient.WithConfig(library.NewClientConfig(t)), diff --git a/test/library/client.go b/test/library/client.go index 430d48e1..d432f919 100644 --- a/test/library/client.go +++ b/test/library/client.go @@ -31,6 +31,7 @@ import ( idpv1alpha1 "go.pinniped.dev/generated/1.20/apis/supervisor/idp/v1alpha1" conciergeclientset "go.pinniped.dev/generated/1.20/client/concierge/clientset/versioned" supervisorclientset "go.pinniped.dev/generated/1.20/client/supervisor/clientset/versioned" + "go.pinniped.dev/internal/kubeclient" // Import to initialize client auth plugins - the kubeconfig that we use for // testing may use gcloud, az, oidc, etc. @@ -76,19 +77,19 @@ func NewClientsetWithCertAndKey(t *testing.T, clientCertificateData, clientKeyDa func NewSupervisorClientset(t *testing.T) supervisorclientset.Interface { t.Helper() - return supervisorclientset.NewForConfigOrDie(NewClientConfig(t)) + return newKubeclient(t, NewClientConfig(t)).PinnipedSupervisor } func NewConciergeClientset(t *testing.T) conciergeclientset.Interface { t.Helper() - return conciergeclientset.NewForConfigOrDie(NewClientConfig(t)) + return newKubeclient(t, NewClientConfig(t)).PinnipedConcierge } func NewAnonymousConciergeClientset(t *testing.T) conciergeclientset.Interface { t.Helper() - return conciergeclientset.NewForConfigOrDie(newAnonymousClientRestConfig(t)) + return newKubeclient(t, newAnonymousClientRestConfig(t)).PinnipedConcierge } func NewAggregatedClientset(t *testing.T) aggregatorclient.Interface { @@ -132,6 +133,14 @@ func newAnonymousClientRestConfigWithCertAndKeyAdded(t *testing.T, clientCertifi return config } +func newKubeclient(t *testing.T, config *rest.Config) *kubeclient.Client { + t.Helper() + _ = IntegrationEnv(t).APIGroupSuffix // TODO: wire API group into kubeclient. + client, err := kubeclient.New(kubeclient.WithConfig(config)) + require.NoError(t, err) + return client +} + // CreateTestWebhookAuthenticator creates and returns a test WebhookAuthenticator in $PINNIPED_TEST_CONCIERGE_NAMESPACE, which will be // automatically deleted at the end of the current test's lifetime. It returns a corev1.TypedLocalObjectReference which // describes the test webhook authenticator within the test namespace. diff --git a/test/library/env.go b/test/library/env.go index 0fd61789..8fa53a93 100644 --- a/test/library/env.go +++ b/test/library/env.go @@ -38,6 +38,7 @@ type TestEnv struct { SupervisorHTTPSIngressAddress string `json:"supervisorHttpsIngressAddress"` SupervisorHTTPSIngressCABundle string `json:"supervisorHttpsIngressCABundle"` Proxy string `json:"proxy"` + APIGroupSuffix string `json:"apiGroupSuffix"` TestUser struct { Token string `json:"token"` @@ -106,6 +107,14 @@ func needEnv(t *testing.T, key string) string { return value } +func wantEnv(key, dephault string) string { + value, ok := os.LookupEnv(key) + if !ok { + return dephault + } + return value +} + func filterEmpty(ss []string) []string { filtered := []string{} for _, s := range ss { @@ -154,6 +163,7 @@ func loadEnvVars(t *testing.T, result *TestEnv) { result.SupervisorCustomLabels = supervisorCustomLabels require.NotEmpty(t, result.SupervisorCustomLabels, "PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS cannot be empty") result.Proxy = os.Getenv("PINNIPED_TEST_PROXY") + result.APIGroupSuffix = wantEnv("PINNIPED_TEST_API_GROUP_SUFFIX", "pinniped.dev") result.CLITestUpstream = TestOIDCUpstream{ Issuer: needEnv(t, "PINNIPED_TEST_CLI_OIDC_ISSUER"),