From 1c3518e18a7a8a39688364f0e45870cfc1f3fd5a Mon Sep 17 00:00:00 2001 From: Andrew Keesler Date: Tue, 19 Jan 2021 11:29:15 -0500 Subject: [PATCH] cmd/pinniped: wire API group suffix through to client components Signed-off-by: Andrew Keesler --- cmd/pinniped/cmd/deprecated.go | 3 ++- cmd/pinniped/cmd/kubeconfig.go | 3 +++ cmd/pinniped/cmd/kubeconfig_test.go | 6 ++++++ cmd/pinniped/cmd/login_oidc.go | 5 ++++- cmd/pinniped/cmd/login_oidc_test.go | 4 +++- cmd/pinniped/cmd/login_static.go | 5 ++++- cmd/pinniped/cmd/login_static_test.go | 3 ++- pkg/conciergeclient/conciergeclient.go | 23 ++++++++++++++++----- pkg/conciergeclient/conciergeclient_test.go | 10 +++++++++ 9 files changed, 52 insertions(+), 10 deletions(-) diff --git a/cmd/pinniped/cmd/deprecated.go b/cmd/pinniped/cmd/deprecated.go index 8894eef4..aa229d4e 100644 --- a/cmd/pinniped/cmd/deprecated.go +++ b/cmd/pinniped/cmd/deprecated.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 cmd @@ -70,6 +70,7 @@ func legacyGetKubeconfigCommand(deps kubeconfigDeps) *cobra.Command { namespace: namespace, authenticatorName: authenticatorName, authenticatorType: authenticatorType, + apiGroupSuffix: "pinniped.dev", }, }) } diff --git a/cmd/pinniped/cmd/kubeconfig.go b/cmd/pinniped/cmd/kubeconfig.go index 8ca7f64d..5bf0b342 100644 --- a/cmd/pinniped/cmd/kubeconfig.go +++ b/cmd/pinniped/cmd/kubeconfig.go @@ -73,6 +73,7 @@ type getKubeconfigConciergeParams struct { namespace string authenticatorName string authenticatorType string + apiGroupSuffix string } type getKubeconfigParams struct { @@ -103,6 +104,7 @@ func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command { f.StringVar(&flags.concierge.namespace, "concierge-namespace", "pinniped-concierge", "Namespace in which the concierge was installed") f.StringVar(&flags.concierge.authenticatorType, "concierge-authenticator-type", "", "Concierge authenticator type (e.g., 'webhook', 'jwt') (default: autodiscover)") f.StringVar(&flags.concierge.authenticatorName, "concierge-authenticator-name", "", "Concierge authenticator name (default: autodiscover)") + f.StringVar(&flags.concierge.apiGroupSuffix, "concierge-api-group-suffix", "pinniped.dev", "Concierge API group suffix") f.StringVar(&flags.oidc.issuer, "oidc-issuer", "", "OpenID Connect issuer URL (default: autodiscover)") f.StringVar(&flags.oidc.clientID, "oidc-client-id", "pinniped-cli", "OpenID Connect client ID (default: autodiscover)") @@ -258,6 +260,7 @@ func configureConcierge(authenticator metav1.Object, flags *getKubeconfigParams, // Append the flags to configure the Concierge credential exchange at runtime. execConfig.Args = append(execConfig.Args, "--enable-concierge", + "--concierge-api-group-suffix="+flags.concierge.apiGroupSuffix, "--concierge-namespace="+flags.concierge.namespace, "--concierge-authenticator-name="+flags.concierge.authenticatorName, "--concierge-authenticator-type="+flags.concierge.authenticatorType, diff --git a/cmd/pinniped/cmd/kubeconfig_test.go b/cmd/pinniped/cmd/kubeconfig_test.go index c5b2e1c6..90d4635d 100644 --- a/cmd/pinniped/cmd/kubeconfig_test.go +++ b/cmd/pinniped/cmd/kubeconfig_test.go @@ -57,6 +57,7 @@ func TestGetKubeconfig(t *testing.T) { kubeconfig [flags] Flags: + --concierge-api-group-suffix string Concierge API group suffix (default "pinniped.dev") --concierge-authenticator-name string Concierge authenticator name (default: autodiscover) --concierge-authenticator-type string Concierge authenticator type (e.g., 'webhook', 'jwt') (default: autodiscover) --concierge-namespace string Namespace in which the concierge was installed (default "pinniped-concierge") @@ -313,6 +314,7 @@ func TestGetKubeconfig(t *testing.T) { - login - static - --enable-concierge + - --concierge-api-group-suffix=pinniped.dev - --concierge-namespace=test-namespace - --concierge-authenticator-name=test-authenticator - --concierge-authenticator-type=webhook @@ -358,6 +360,7 @@ func TestGetKubeconfig(t *testing.T) { - login - static - --enable-concierge + - --concierge-api-group-suffix=pinniped.dev - --concierge-namespace=test-namespace - --concierge-authenticator-name=test-authenticator - --concierge-authenticator-type=webhook @@ -410,6 +413,7 @@ func TestGetKubeconfig(t *testing.T) { - login - oidc - --enable-concierge + - --concierge-api-group-suffix=pinniped.dev - --concierge-namespace=pinniped-concierge - --concierge-authenticator-name=test-authenticator - --concierge-authenticator-type=jwt @@ -429,6 +433,7 @@ func TestGetKubeconfig(t *testing.T) { name: "autodetect nothing, set a bunch of options", args: []string{ "--kubeconfig", "./testdata/kubeconfig.yaml", + "--concierge-api-group-suffix", "tuna.io", "--concierge-authenticator-type", "webhook", "--concierge-authenticator-name", "test-authenticator", "--oidc-issuer", "https://example.com/issuer", @@ -468,6 +473,7 @@ func TestGetKubeconfig(t *testing.T) { - login - oidc - --enable-concierge + - --concierge-api-group-suffix=tuna.io - --concierge-namespace=pinniped-concierge - --concierge-authenticator-name=test-authenticator - --concierge-authenticator-type=webhook diff --git a/cmd/pinniped/cmd/login_oidc.go b/cmd/pinniped/cmd/login_oidc.go index 39718105..7802eeea 100644 --- a/cmd/pinniped/cmd/login_oidc.go +++ b/cmd/pinniped/cmd/login_oidc.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 cmd @@ -64,6 +64,7 @@ type oidcLoginFlags struct { conciergeAuthenticatorName string conciergeEndpoint string conciergeCABundle string + conciergeAPIGroupSuffix string } func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command { @@ -92,6 +93,7 @@ func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command { cmd.Flags().StringVar(&flags.conciergeAuthenticatorName, "concierge-authenticator-name", "", "Concierge authenticator name") cmd.Flags().StringVar(&flags.conciergeEndpoint, "concierge-endpoint", "", "API base for the Pinniped concierge endpoint") cmd.Flags().StringVar(&flags.conciergeCABundle, "concierge-ca-bundle-data", "", "CA bundle to use when connecting to the concierge") + cmd.Flags().StringVar(&flags.conciergeAPIGroupSuffix, "concierge-api-group-suffix", "pinniped.dev", "Concierge API group suffix") mustMarkHidden(&cmd, "debug-session-cache") mustMarkRequired(&cmd, "issuer") @@ -135,6 +137,7 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin conciergeclient.WithEndpoint(flags.conciergeEndpoint), conciergeclient.WithBase64CABundle(flags.conciergeCABundle), conciergeclient.WithAuthenticator(flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName), + conciergeclient.WithAPIGroupSuffix(flags.conciergeAPIGroupSuffix), ) if err != nil { return fmt.Errorf("invalid concierge parameters: %w", err) diff --git a/cmd/pinniped/cmd/login_oidc_test.go b/cmd/pinniped/cmd/login_oidc_test.go index da7515a0..a12050f0 100644 --- a/cmd/pinniped/cmd/login_oidc_test.go +++ b/cmd/pinniped/cmd/login_oidc_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 cmd @@ -60,6 +60,7 @@ func TestLoginOIDCCommand(t *testing.T) { --ca-bundle strings Path to TLS certificate authority bundle (PEM format, optional, can be repeated) --ca-bundle-data strings Base64 endcoded TLS certificate authority bundle (base64 encoded PEM format, optional, can be repeated) --client-id string OpenID Connect client ID (default "pinniped-cli") + --concierge-api-group-suffix string Concierge API group suffix (default "pinniped.dev") --concierge-authenticator-name string Concierge authenticator name --concierge-authenticator-type string Concierge authenticator type (e.g., 'webhook', 'jwt') --concierge-ca-bundle-data string CA bundle to use when connecting to the concierge @@ -175,6 +176,7 @@ func TestLoginOIDCCommand(t *testing.T) { "--concierge-authenticator-name", "test-authenticator", "--concierge-endpoint", "https://127.0.0.1:1234/", "--concierge-ca-bundle-data", base64.StdEncoding.EncodeToString(testCA.Bundle()), + "--concierge-api-group-suffix", "some.suffix.com", }, wantOptionsCount: 7, wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"token":"exchanged-token"}}` + "\n", diff --git a/cmd/pinniped/cmd/login_static.go b/cmd/pinniped/cmd/login_static.go index a051e4fa..52fcf095 100644 --- a/cmd/pinniped/cmd/login_static.go +++ b/cmd/pinniped/cmd/login_static.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 cmd @@ -46,6 +46,7 @@ type staticLoginParams struct { conciergeAuthenticatorName string conciergeEndpoint string conciergeCABundle string + conciergeAPIGroupSuffix string } func staticLoginCommand(deps staticLoginDeps) *cobra.Command { @@ -66,6 +67,7 @@ func staticLoginCommand(deps staticLoginDeps) *cobra.Command { cmd.Flags().StringVar(&flags.conciergeAuthenticatorName, "concierge-authenticator-name", "", "Concierge authenticator name") cmd.Flags().StringVar(&flags.conciergeEndpoint, "concierge-endpoint", "", "API base for the Pinniped concierge endpoint") cmd.Flags().StringVar(&flags.conciergeCABundle, "concierge-ca-bundle-data", "", "CA bundle to use when connecting to the concierge") + cmd.Flags().StringVar(&flags.conciergeAPIGroupSuffix, "concierge-api-group-suffix", "pinniped.dev", "Concierge API group suffix") cmd.RunE = func(cmd *cobra.Command, args []string) error { return runStaticLogin(cmd.OutOrStdout(), deps, flags) } return &cmd } @@ -83,6 +85,7 @@ func runStaticLogin(out io.Writer, deps staticLoginDeps, flags staticLoginParams conciergeclient.WithEndpoint(flags.conciergeEndpoint), conciergeclient.WithBase64CABundle(flags.conciergeCABundle), conciergeclient.WithAuthenticator(flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName), + conciergeclient.WithAPIGroupSuffix(flags.conciergeAPIGroupSuffix), ) if err != nil { return fmt.Errorf("invalid concierge parameters: %w", err) diff --git a/cmd/pinniped/cmd/login_static_test.go b/cmd/pinniped/cmd/login_static_test.go index ef523020..f1c30da3 100644 --- a/cmd/pinniped/cmd/login_static_test.go +++ b/cmd/pinniped/cmd/login_static_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 cmd @@ -51,6 +51,7 @@ func TestLoginStaticCommand(t *testing.T) { static [--token TOKEN] [--token-env TOKEN_NAME] [flags] Flags: + --concierge-api-group-suffix string Concierge API group suffix (default "pinniped.dev") --concierge-authenticator-name string Concierge authenticator name --concierge-authenticator-type string Concierge authenticator type (e.g., 'webhook', 'jwt') --concierge-ca-bundle-data string CA bundle to use when connecting to the concierge diff --git a/pkg/conciergeclient/conciergeclient.go b/pkg/conciergeclient/conciergeclient.go index 11d40879..b8163437 100644 --- a/pkg/conciergeclient/conciergeclient.go +++ b/pkg/conciergeclient/conciergeclient.go @@ -33,10 +33,11 @@ type Option func(*Client) error // Client is a configuration for talking to the Pinniped concierge. type Client struct { - namespace string - authenticator *corev1.TypedLocalObjectReference - caBundle string - endpoint *url.URL + namespace string + authenticator *corev1.TypedLocalObjectReference + caBundle string + endpoint *url.URL + apiGroupSuffix string } // WithNamespace configures the namespace where the TokenCredentialRequest is to be sent. @@ -112,9 +113,20 @@ func WithEndpoint(endpoint string) Option { } } +// WithAPIGroupSuffix configures the concierge's API group suffix (e.g., "pinniped.dev"). +func WithAPIGroupSuffix(apiGroupSuffix string) Option { + return func(c *Client) error { + if apiGroupSuffix == "" { + return fmt.Errorf("api group suffix must not be empty") + } + c.apiGroupSuffix = apiGroupSuffix + return nil + } +} + // New validates the specified options and returns a newly initialized *Client. func New(opts ...Option) (*Client, error) { - c := Client{namespace: "pinniped-concierge"} + c := Client{namespace: "pinniped-concierge", apiGroupSuffix: "pinniped.dev"} for _, opt := range opts { if err := opt(&c); err != nil { return nil, err @@ -151,6 +163,7 @@ func (c *Client) clientset() (conciergeclientset.Interface, error) { if err != nil { return nil, err } + _ = c.apiGroupSuffix // TODO: wire API group into kubeclient. client, err := kubeclient.New(kubeclient.WithConfig(cfg)) if err != nil { return nil, err diff --git a/pkg/conciergeclient/conciergeclient_test.go b/pkg/conciergeclient/conciergeclient_test.go index ce19c704..79560c71 100644 --- a/pkg/conciergeclient/conciergeclient_test.go +++ b/pkg/conciergeclient/conciergeclient_test.go @@ -104,6 +104,15 @@ func TestNew(t *testing.T) { }, wantErr: "WithEndpoint must be specified", }, + { + name: "empty api group suffix", + opts: []Option{ + WithAuthenticator("jwt", "test-authenticator"), + WithEndpoint("https://example.com"), + WithAPIGroupSuffix(""), + }, + wantErr: "api group suffix must not be empty", + }, { name: "valid", opts: []Option{ @@ -114,6 +123,7 @@ func TestNew(t *testing.T) { WithBase64CABundle(base64.StdEncoding.EncodeToString(testCA.Bundle())), WithAuthenticator("jwt", "test-authenticator"), WithAuthenticator("webhook", "test-authenticator"), + WithAPIGroupSuffix("suffix.com"), }, }, }