From 0efc19a1b766616a22c3b0586df94f57a0f787a8 Mon Sep 17 00:00:00 2001 From: Andrew Keesler Date: Mon, 7 Dec 2020 20:40:20 -0500 Subject: [PATCH] Support JWTAuthenticator in pinniped CLI Signed-off-by: Andrew Keesler --- cmd/pinniped/cmd/exchange_credential.go | 7 ++- cmd/pinniped/cmd/exchange_credential_test.go | 50 +++++++++++++++++++- cmd/pinniped/cmd/get_kubeconfig.go | 2 +- cmd/pinniped/cmd/get_kubeconfig_test.go | 4 +- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/cmd/pinniped/cmd/exchange_credential.go b/cmd/pinniped/cmd/exchange_credential.go index 2440864c..74d1176b 100644 --- a/cmd/pinniped/cmd/exchange_credential.go +++ b/cmd/pinniped/cmd/exchange_credential.go @@ -64,7 +64,7 @@ func newExchangeCredentialCmd(args []string, stdout, stderr io.Writer) *exchange - PINNIPED_NAMESPACE: the namespace of the authenticator to authenticate against - PINNIPED_AUTHENTICATOR_TYPE: the type of authenticator to authenticate - against (e.g., "webhook") + against (e.g., "webhook", "jwt") - PINNIPED_AUTHENTICATOR_NAME: the name of the authenticator to authenticate against - PINNIPED_CA_BUNDLE: the CA bundle to trust when calling @@ -148,8 +148,11 @@ func exchangeCredential(envGetter envGetter, tokenExchanger tokenExchanger, outp case "webhook": authenticator.APIGroup = &auth1alpha1.SchemeGroupVersion.Group authenticator.Kind = "WebhookAuthenticator" + case "jwt": + authenticator.APIGroup = &auth1alpha1.SchemeGroupVersion.Group + authenticator.Kind = "JWTAuthenticator" default: - return fmt.Errorf(`%w: %q, supported values are "webhook"`, ErrInvalidAuthenticatorType, authenticatorType) + return fmt.Errorf(`%w: %q, supported values are "webhook" and "jwt"`, ErrInvalidAuthenticatorType, authenticatorType) } cred, err := tokenExchanger(ctx, namespace, authenticator, token, caBundle, apiEndpoint) diff --git a/cmd/pinniped/cmd/exchange_credential_test.go b/cmd/pinniped/cmd/exchange_credential_test.go index 2b1367c2..babd4f3b 100644 --- a/cmd/pinniped/cmd/exchange_credential_test.go +++ b/cmd/pinniped/cmd/exchange_credential_test.go @@ -18,6 +18,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1" + auth1alpha1 "go.pinniped.dev/generated/1.19/apis/concierge/authentication/v1alpha1" "go.pinniped.dev/internal/here" "go.pinniped.dev/internal/testutil" ) @@ -46,7 +47,7 @@ var ( - PINNIPED_NAMESPACE: the namespace of the authenticator to authenticate against - PINNIPED_AUTHENTICATOR_TYPE: the type of authenticator to authenticate - against (e.g., "webhook") + against (e.g., "webhook", "jwt") - PINNIPED_AUTHENTICATOR_NAME: the name of the authenticator to authenticate against - PINNIPED_CA_BUNDLE: the CA bundle to trust when calling @@ -193,7 +194,7 @@ func TestExchangeCredential(t *testing.T) { it("returns an error when PINNIPED_AUTHENTICATOR_TYPE is missing", func() { fakeEnv["PINNIPED_AUTHENTICATOR_TYPE"] = "invalid" err := exchangeCredential(envGetter, tokenExchanger, buffer, 30*time.Second) - r.EqualError(err, `invalid authenticator type: "invalid", supported values are "webhook"`) + r.EqualError(err, `invalid authenticator type: "invalid", supported values are "webhook" and "jwt"`) }) }) @@ -292,5 +293,50 @@ func TestExchangeCredential(t *testing.T) { r.JSONEq(expected, buffer.String()) }) }) + + when("the authenticator info is passed", func() { + var actualAuthenticator corev1.TypedLocalObjectReference + + it.Before(func() { + tokenExchanger = func(ctx context.Context, namespace string, authenticator corev1.TypedLocalObjectReference, token, caBundle, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error) { + actualAuthenticator = authenticator + return nil, nil + } + }) + + when("the authenticator is of type webhook", func() { + it.Before(func() { + fakeEnv["PINNIPED_AUTHENTICATOR_TYPE"] = "webhook" + fakeEnv["PINNIPED_AUTHENTICATOR_NAME"] = "some-webhook-name" + }) + + it("passes the correct authenticator type to the token exchanger", func() { + err := exchangeCredential(envGetter, tokenExchanger, buffer, 30*time.Second) + r.NoError(err) + require.Equal(t, corev1.TypedLocalObjectReference{ + APIGroup: &auth1alpha1.SchemeGroupVersion.Group, + Kind: "WebhookAuthenticator", + Name: "some-webhook-name", + }, actualAuthenticator) + }) + }) + + when("the authenticator is of type jwt", func() { + it.Before(func() { + fakeEnv["PINNIPED_AUTHENTICATOR_TYPE"] = "jwt" + fakeEnv["PINNIPED_AUTHENTICATOR_NAME"] = "some-jwt-authenticator-name" + }) + + it("passes the correct authenticator type to the token exchanger", func() { + err := exchangeCredential(envGetter, tokenExchanger, buffer, 30*time.Second) + r.NoError(err) + require.Equal(t, corev1.TypedLocalObjectReference{ + APIGroup: &auth1alpha1.SchemeGroupVersion.Group, + Kind: "JWTAuthenticator", + Name: "some-jwt-authenticator-name", + }, actualAuthenticator) + }) + }) + }) }, spec.Parallel(), spec.Report(report.Terminal{})) } diff --git a/cmd/pinniped/cmd/get_kubeconfig.go b/cmd/pinniped/cmd/get_kubeconfig.go index 3f4b22b8..9ed9bacf 100644 --- a/cmd/pinniped/cmd/get_kubeconfig.go +++ b/cmd/pinniped/cmd/get_kubeconfig.go @@ -89,7 +89,7 @@ func (c *getKubeConfigCommand) Command() *cobra.Command { cmd.Flags().StringVar(&c.flags.kubeconfig, "kubeconfig", c.flags.kubeconfig, "Path to the kubeconfig file") cmd.Flags().StringVar(&c.flags.contextOverride, "kubeconfig-context", c.flags.contextOverride, "Kubeconfig context override") cmd.Flags().StringVar(&c.flags.namespace, "pinniped-namespace", c.flags.namespace, "Namespace in which Pinniped was installed") - cmd.Flags().StringVar(&c.flags.authenticatorType, "authenticator-type", c.flags.authenticatorType, "Authenticator type (e.g., 'webhook')") + cmd.Flags().StringVar(&c.flags.authenticatorType, "authenticator-type", c.flags.authenticatorType, "Authenticator type (e.g., 'webhook', 'jwt')") cmd.Flags().StringVar(&c.flags.authenticatorName, "authenticator-name", c.flags.authenticatorType, "Authenticator name") mustMarkRequired(cmd, "token") plog.RemoveKlogGlobalFlags() diff --git a/cmd/pinniped/cmd/get_kubeconfig_test.go b/cmd/pinniped/cmd/get_kubeconfig_test.go index 70488b3c..40a88b90 100644 --- a/cmd/pinniped/cmd/get_kubeconfig_test.go +++ b/cmd/pinniped/cmd/get_kubeconfig_test.go @@ -31,7 +31,7 @@ var ( Flags: --authenticator-name string Authenticator name - --authenticator-type string Authenticator type (e.g., 'webhook') + --authenticator-type string Authenticator type (e.g., 'webhook', 'jwt') -h, --help help for get-kubeconfig --kubeconfig string Path to the kubeconfig file --kubeconfig-context string Kubeconfig context override @@ -62,7 +62,7 @@ var ( Flags: --authenticator-name string Authenticator name - --authenticator-type string Authenticator type (e.g., 'webhook') + --authenticator-type string Authenticator type (e.g., 'webhook', 'jwt') -h, --help help for get-kubeconfig --kubeconfig string Path to the kubeconfig file --kubeconfig-context string Kubeconfig context override