Add IDP selector support in client code.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
parent
164f64a370
commit
fbe0551426
@ -9,11 +9,14 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||||
|
|
||||||
|
idpv1alpha1 "go.pinniped.dev/generated/1.19/apis/idp/v1alpha1"
|
||||||
"go.pinniped.dev/internal/client"
|
"go.pinniped.dev/internal/client"
|
||||||
"go.pinniped.dev/internal/constable"
|
"go.pinniped.dev/internal/constable"
|
||||||
"go.pinniped.dev/internal/here"
|
"go.pinniped.dev/internal/here"
|
||||||
@ -75,9 +78,19 @@ func newExchangeCredentialCmd(args []string, stdout, stderr io.Writer) *exchange
|
|||||||
}
|
}
|
||||||
|
|
||||||
type envGetter func(string) (string, bool)
|
type envGetter func(string) (string, bool)
|
||||||
type tokenExchanger func(ctx context.Context, namespace, token, caBundle, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error)
|
type tokenExchanger func(
|
||||||
|
ctx context.Context,
|
||||||
|
namespace string,
|
||||||
|
idp corev1.TypedLocalObjectReference,
|
||||||
|
token string,
|
||||||
|
caBundle string,
|
||||||
|
apiEndpoint string,
|
||||||
|
) (*clientauthenticationv1beta1.ExecCredential, error)
|
||||||
|
|
||||||
const ErrMissingEnvVar = constable.Error("failed to get credential: environment variable not set")
|
const (
|
||||||
|
ErrMissingEnvVar = constable.Error("failed to get credential: environment variable not set")
|
||||||
|
ErrInvalidIDPType = constable.Error("invalid IDP type")
|
||||||
|
)
|
||||||
|
|
||||||
func runExchangeCredential(stdout, _ io.Writer) {
|
func runExchangeCredential(stdout, _ io.Writer) {
|
||||||
err := exchangeCredential(os.LookupEnv, client.ExchangeToken, stdout, 30*time.Second)
|
err := exchangeCredential(os.LookupEnv, client.ExchangeToken, stdout, 30*time.Second)
|
||||||
@ -96,6 +109,16 @@ func exchangeCredential(envGetter envGetter, tokenExchanger tokenExchanger, outp
|
|||||||
return envVarNotSetError("PINNIPED_NAMESPACE")
|
return envVarNotSetError("PINNIPED_NAMESPACE")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idpType, varExists := envGetter("PINNIPED_IDP_TYPE")
|
||||||
|
if !varExists {
|
||||||
|
return envVarNotSetError("PINNIPED_IDP_TYPE")
|
||||||
|
}
|
||||||
|
|
||||||
|
idpName, varExists := envGetter("PINNIPED_IDP_NAME")
|
||||||
|
if !varExists {
|
||||||
|
return envVarNotSetError("PINNIPED_IDP_NAME")
|
||||||
|
}
|
||||||
|
|
||||||
token, varExists := envGetter("PINNIPED_TOKEN")
|
token, varExists := envGetter("PINNIPED_TOKEN")
|
||||||
if !varExists {
|
if !varExists {
|
||||||
return envVarNotSetError("PINNIPED_TOKEN")
|
return envVarNotSetError("PINNIPED_TOKEN")
|
||||||
@ -111,7 +134,16 @@ func exchangeCredential(envGetter envGetter, tokenExchanger tokenExchanger, outp
|
|||||||
return envVarNotSetError("PINNIPED_K8S_API_ENDPOINT")
|
return envVarNotSetError("PINNIPED_K8S_API_ENDPOINT")
|
||||||
}
|
}
|
||||||
|
|
||||||
cred, err := tokenExchanger(ctx, namespace, token, caBundle, apiEndpoint)
|
idp := corev1.TypedLocalObjectReference{Name: idpName}
|
||||||
|
switch strings.ToLower(idpType) {
|
||||||
|
case "webhook":
|
||||||
|
idp.APIGroup = &idpv1alpha1.SchemeGroupVersion.Group
|
||||||
|
idp.Kind = "WebhookIdentityProvider"
|
||||||
|
default:
|
||||||
|
return fmt.Errorf(`%w: %q, supported values are "webhook"`, ErrInvalidIDPType, idpType)
|
||||||
|
}
|
||||||
|
|
||||||
|
cred, err := tokenExchanger(ctx, namespace, idp, token, caBundle, apiEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get credential: %w", err)
|
return fmt.Errorf("failed to get credential: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/sclevine/spec"
|
"github.com/sclevine/spec"
|
||||||
"github.com/sclevine/spec/report"
|
"github.com/sclevine/spec/report"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||||
|
|
||||||
@ -136,6 +137,8 @@ func TestExchangeCredential(t *testing.T) {
|
|||||||
buffer = new(bytes.Buffer)
|
buffer = new(bytes.Buffer)
|
||||||
fakeEnv = map[string]string{
|
fakeEnv = map[string]string{
|
||||||
"PINNIPED_NAMESPACE": "namespace from env",
|
"PINNIPED_NAMESPACE": "namespace from env",
|
||||||
|
"PINNIPED_IDP_TYPE": "Webhook",
|
||||||
|
"PINNIPED_IDP_NAME": "webhook name from env",
|
||||||
"PINNIPED_TOKEN": "token from env",
|
"PINNIPED_TOKEN": "token from env",
|
||||||
"PINNIPED_CA_BUNDLE": "ca bundle from env",
|
"PINNIPED_CA_BUNDLE": "ca bundle from env",
|
||||||
"PINNIPED_K8S_API_ENDPOINT": "k8s api from env",
|
"PINNIPED_K8S_API_ENDPOINT": "k8s api from env",
|
||||||
@ -149,6 +152,18 @@ func TestExchangeCredential(t *testing.T) {
|
|||||||
r.EqualError(err, "failed to get credential: environment variable not set: PINNIPED_NAMESPACE")
|
r.EqualError(err, "failed to get credential: environment variable not set: PINNIPED_NAMESPACE")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("returns an error when PINNIPED_IDP_TYPE is missing", func() {
|
||||||
|
delete(fakeEnv, "PINNIPED_IDP_TYPE")
|
||||||
|
err := exchangeCredential(envGetter, tokenExchanger, buffer, 30*time.Second)
|
||||||
|
r.EqualError(err, "failed to get credential: environment variable not set: PINNIPED_IDP_TYPE")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns an error when PINNIPED_IDP_NAME is missing", func() {
|
||||||
|
delete(fakeEnv, "PINNIPED_IDP_NAME")
|
||||||
|
err := exchangeCredential(envGetter, tokenExchanger, buffer, 30*time.Second)
|
||||||
|
r.EqualError(err, "failed to get credential: environment variable not set: PINNIPED_IDP_NAME")
|
||||||
|
})
|
||||||
|
|
||||||
it("returns an error when PINNIPED_TOKEN is missing", func() {
|
it("returns an error when PINNIPED_TOKEN is missing", func() {
|
||||||
delete(fakeEnv, "PINNIPED_TOKEN")
|
delete(fakeEnv, "PINNIPED_TOKEN")
|
||||||
err := exchangeCredential(envGetter, tokenExchanger, buffer, 30*time.Second)
|
err := exchangeCredential(envGetter, tokenExchanger, buffer, 30*time.Second)
|
||||||
@ -168,9 +183,17 @@ func TestExchangeCredential(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
when("env vars are invalid", func() {
|
||||||
|
it("returns an error when PINNIPED_IDP_TYPE is missing", func() {
|
||||||
|
fakeEnv["PINNIPED_IDP_TYPE"] = "invalid"
|
||||||
|
err := exchangeCredential(envGetter, tokenExchanger, buffer, 30*time.Second)
|
||||||
|
r.EqualError(err, `invalid IDP type: "invalid", supported values are "webhook"`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
when("the token exchange fails", func() {
|
when("the token exchange fails", func() {
|
||||||
it.Before(func() {
|
it.Before(func() {
|
||||||
tokenExchanger = func(ctx context.Context, namespace, token, caBundle, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error) {
|
tokenExchanger = func(ctx context.Context, namespace string, idp corev1.TypedLocalObjectReference, token, caBundle, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error) {
|
||||||
return nil, fmt.Errorf("some error")
|
return nil, fmt.Errorf("some error")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -183,7 +206,7 @@ func TestExchangeCredential(t *testing.T) {
|
|||||||
|
|
||||||
when("the JSON encoder fails", func() {
|
when("the JSON encoder fails", func() {
|
||||||
it.Before(func() {
|
it.Before(func() {
|
||||||
tokenExchanger = func(ctx context.Context, namespace, token, caBundle, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error) {
|
tokenExchanger = func(ctx context.Context, namespace string, idp corev1.TypedLocalObjectReference, token, caBundle, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error) {
|
||||||
return &clientauthenticationv1beta1.ExecCredential{
|
return &clientauthenticationv1beta1.ExecCredential{
|
||||||
Status: &clientauthenticationv1beta1.ExecCredentialStatus{
|
Status: &clientauthenticationv1beta1.ExecCredentialStatus{
|
||||||
Token: "some token",
|
Token: "some token",
|
||||||
@ -200,7 +223,7 @@ func TestExchangeCredential(t *testing.T) {
|
|||||||
|
|
||||||
when("the token exchange times out", func() {
|
when("the token exchange times out", func() {
|
||||||
it.Before(func() {
|
it.Before(func() {
|
||||||
tokenExchanger = func(ctx context.Context, namespace, token, caBundle, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error) {
|
tokenExchanger = func(ctx context.Context, namespace string, idp corev1.TypedLocalObjectReference, token, caBundle, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error) {
|
||||||
select {
|
select {
|
||||||
case <-time.After(100 * time.Millisecond):
|
case <-time.After(100 * time.Millisecond):
|
||||||
return &clientauthenticationv1beta1.ExecCredential{
|
return &clientauthenticationv1beta1.ExecCredential{
|
||||||
@ -224,7 +247,7 @@ func TestExchangeCredential(t *testing.T) {
|
|||||||
var actualNamespace, actualToken, actualCaBundle, actualAPIEndpoint string
|
var actualNamespace, actualToken, actualCaBundle, actualAPIEndpoint string
|
||||||
|
|
||||||
it.Before(func() {
|
it.Before(func() {
|
||||||
tokenExchanger = func(ctx context.Context, namespace, token, caBundle, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error) {
|
tokenExchanger = func(ctx context.Context, namespace string, idp corev1.TypedLocalObjectReference, token, caBundle, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error) {
|
||||||
actualNamespace, actualToken, actualCaBundle, actualAPIEndpoint = namespace, token, caBundle, apiEndpoint
|
actualNamespace, actualToken, actualCaBundle, actualAPIEndpoint = namespace, token, caBundle, apiEndpoint
|
||||||
now := metav1.NewTime(time.Date(2020, 7, 29, 1, 2, 3, 0, time.UTC))
|
now := metav1.NewTime(time.Date(2020, 7, 29, 1, 2, 3, 0, time.UTC))
|
||||||
return &clientauthenticationv1beta1.ExecCredential{
|
return &clientauthenticationv1beta1.ExecCredential{
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
@ -21,15 +22,18 @@ import (
|
|||||||
// ErrLoginFailed is returned by ExchangeToken when the server rejects the login request.
|
// ErrLoginFailed is returned by ExchangeToken when the server rejects the login request.
|
||||||
var ErrLoginFailed = errors.New("login failed")
|
var ErrLoginFailed = errors.New("login failed")
|
||||||
|
|
||||||
// ExchangeToken exchanges an opaque token using the Pinniped CredentialRequest API, returning a client-go ExecCredential valid on the target cluster.
|
// ExchangeToken exchanges an opaque token using the Pinniped TokenCredentialRequest API, returning a client-go ExecCredential valid on the target cluster.
|
||||||
func ExchangeToken(ctx context.Context, namespace string, token string, caBundle string, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error) {
|
func ExchangeToken(ctx context.Context, namespace string, idp corev1.TypedLocalObjectReference, token string, caBundle string, apiEndpoint string) (*clientauthenticationv1beta1.ExecCredential, error) {
|
||||||
client, err := getClient(apiEndpoint, caBundle)
|
client, err := getClient(apiEndpoint, caBundle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not get API client: %w", err)
|
return nil, fmt.Errorf("could not get API client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := client.LoginV1alpha1().TokenCredentialRequests(namespace).Create(ctx, &v1alpha1.TokenCredentialRequest{
|
resp, err := client.LoginV1alpha1().TokenCredentialRequests(namespace).Create(ctx, &v1alpha1.TokenCredentialRequest{
|
||||||
Spec: v1alpha1.TokenCredentialRequestSpec{Token: token},
|
Spec: v1alpha1.TokenCredentialRequestSpec{
|
||||||
|
Token: token,
|
||||||
|
IdentityProvider: idp,
|
||||||
|
},
|
||||||
}, metav1.CreateOptions{})
|
}, metav1.CreateOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not login: %w", err)
|
return nil, fmt.Errorf("could not login: %w", err)
|
||||||
|
@ -12,10 +12,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||||
|
|
||||||
"go.pinniped.dev/generated/1.19/apis/login/v1alpha1"
|
idpv1alpha1 "go.pinniped.dev/generated/1.19/apis/idp/v1alpha1"
|
||||||
|
loginv1alpha1 "go.pinniped.dev/generated/1.19/apis/login/v1alpha1"
|
||||||
"go.pinniped.dev/internal/testutil"
|
"go.pinniped.dev/internal/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,9 +25,15 @@ func TestExchangeToken(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
|
testIDP := corev1.TypedLocalObjectReference{
|
||||||
|
APIGroup: &idpv1alpha1.SchemeGroupVersion.Group,
|
||||||
|
Kind: "WebhookIdentityProvider",
|
||||||
|
Name: "test-webhook",
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("invalid configuration", func(t *testing.T) {
|
t.Run("invalid configuration", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
got, err := ExchangeToken(ctx, "test-namespace", "", "", "")
|
got, err := ExchangeToken(ctx, "test-namespace", testIDP, "", "", "")
|
||||||
require.EqualError(t, err, "could not get API client: invalid configuration: no configuration has been provided, try setting KUBERNETES_MASTER environment variable")
|
require.EqualError(t, err, "could not get API client: invalid configuration: no configuration has been provided, try setting KUBERNETES_MASTER environment variable")
|
||||||
require.Nil(t, got)
|
require.Nil(t, got)
|
||||||
})
|
})
|
||||||
@ -38,7 +46,7 @@ func TestExchangeToken(t *testing.T) {
|
|||||||
_, _ = w.Write([]byte("some server error"))
|
_, _ = w.Write([]byte("some server error"))
|
||||||
})
|
})
|
||||||
|
|
||||||
got, err := ExchangeToken(ctx, "test-namespace", "", caBundle, endpoint)
|
got, err := ExchangeToken(ctx, "test-namespace", testIDP, "", caBundle, endpoint)
|
||||||
require.EqualError(t, err, `could not login: an error on the server ("some server error") has prevented the request from succeeding (post tokencredentialrequests.login.pinniped.dev)`)
|
require.EqualError(t, err, `could not login: an error on the server ("some server error") has prevented the request from succeeding (post tokencredentialrequests.login.pinniped.dev)`)
|
||||||
require.Nil(t, got)
|
require.Nil(t, got)
|
||||||
})
|
})
|
||||||
@ -49,13 +57,13 @@ func TestExchangeToken(t *testing.T) {
|
|||||||
errorMessage := "some login failure"
|
errorMessage := "some login failure"
|
||||||
caBundle, endpoint := testutil.TLSTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
caBundle, endpoint := testutil.TLSTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("content-type", "application/json")
|
w.Header().Set("content-type", "application/json")
|
||||||
_ = json.NewEncoder(w).Encode(&v1alpha1.TokenCredentialRequest{
|
_ = json.NewEncoder(w).Encode(&loginv1alpha1.TokenCredentialRequest{
|
||||||
TypeMeta: metav1.TypeMeta{APIVersion: "login.pinniped.dev/v1alpha1", Kind: "TokenCredentialRequest"},
|
TypeMeta: metav1.TypeMeta{APIVersion: "login.pinniped.dev/v1alpha1", Kind: "TokenCredentialRequest"},
|
||||||
Status: v1alpha1.TokenCredentialRequestStatus{Message: &errorMessage},
|
Status: loginv1alpha1.TokenCredentialRequestStatus{Message: &errorMessage},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
got, err := ExchangeToken(ctx, "test-namespace", "", caBundle, endpoint)
|
got, err := ExchangeToken(ctx, "test-namespace", testIDP, "", caBundle, endpoint)
|
||||||
require.EqualError(t, err, `login failed: some login failure`)
|
require.EqualError(t, err, `login failed: some login failure`)
|
||||||
require.Nil(t, got)
|
require.Nil(t, got)
|
||||||
})
|
})
|
||||||
@ -65,12 +73,12 @@ func TestExchangeToken(t *testing.T) {
|
|||||||
// Start a test server that returns without any error message but also without valid credentials
|
// Start a test server that returns without any error message but also without valid credentials
|
||||||
caBundle, endpoint := testutil.TLSTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
caBundle, endpoint := testutil.TLSTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("content-type", "application/json")
|
w.Header().Set("content-type", "application/json")
|
||||||
_ = json.NewEncoder(w).Encode(&v1alpha1.TokenCredentialRequest{
|
_ = json.NewEncoder(w).Encode(&loginv1alpha1.TokenCredentialRequest{
|
||||||
TypeMeta: metav1.TypeMeta{APIVersion: "login.pinniped.dev/v1alpha1", Kind: "TokenCredentialRequest"},
|
TypeMeta: metav1.TypeMeta{APIVersion: "login.pinniped.dev/v1alpha1", Kind: "TokenCredentialRequest"},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
got, err := ExchangeToken(ctx, "test-namespace", "", caBundle, endpoint)
|
got, err := ExchangeToken(ctx, "test-namespace", testIDP, "", caBundle, endpoint)
|
||||||
require.EqualError(t, err, `login failed: unknown`)
|
require.EqualError(t, err, `login failed: unknown`)
|
||||||
require.Nil(t, got)
|
require.Nil(t, got)
|
||||||
})
|
})
|
||||||
@ -95,7 +103,12 @@ func TestExchangeToken(t *testing.T) {
|
|||||||
"creationTimestamp": null
|
"creationTimestamp": null
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
"token": "test-token"
|
"token": "test-token",
|
||||||
|
"identityProvider": {
|
||||||
|
"apiGroup": "idp.pinniped.dev",
|
||||||
|
"kind": "WebhookIdentityProvider",
|
||||||
|
"name": "test-webhook"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"status": {}
|
"status": {}
|
||||||
}`,
|
}`,
|
||||||
@ -103,10 +116,10 @@ func TestExchangeToken(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
w.Header().Set("content-type", "application/json")
|
w.Header().Set("content-type", "application/json")
|
||||||
_ = json.NewEncoder(w).Encode(&v1alpha1.TokenCredentialRequest{
|
_ = json.NewEncoder(w).Encode(&loginv1alpha1.TokenCredentialRequest{
|
||||||
TypeMeta: metav1.TypeMeta{APIVersion: "login.pinniped.dev/v1alpha1", Kind: "TokenCredentialRequest"},
|
TypeMeta: metav1.TypeMeta{APIVersion: "login.pinniped.dev/v1alpha1", Kind: "TokenCredentialRequest"},
|
||||||
Status: v1alpha1.TokenCredentialRequestStatus{
|
Status: loginv1alpha1.TokenCredentialRequestStatus{
|
||||||
Credential: &v1alpha1.ClusterCredential{
|
Credential: &loginv1alpha1.ClusterCredential{
|
||||||
ExpirationTimestamp: expires,
|
ExpirationTimestamp: expires,
|
||||||
ClientCertificateData: "test-certificate",
|
ClientCertificateData: "test-certificate",
|
||||||
ClientKeyData: "test-key",
|
ClientKeyData: "test-key",
|
||||||
@ -115,7 +128,7 @@ func TestExchangeToken(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
got, err := ExchangeToken(ctx, "test-namespace", "test-token", caBundle, endpoint)
|
got, err := ExchangeToken(ctx, "test-namespace", testIDP, "test-token", caBundle, endpoint)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &clientauthenticationv1beta1.ExecCredential{
|
require.Equal(t, &clientauthenticationv1beta1.ExecCredential{
|
||||||
TypeMeta: metav1.TypeMeta{
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
@ -10,7 +10,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
|
idpv1alpha1 "go.pinniped.dev/generated/1.19/apis/idp/v1alpha1"
|
||||||
"go.pinniped.dev/internal/client"
|
"go.pinniped.dev/internal/client"
|
||||||
"go.pinniped.dev/internal/here"
|
"go.pinniped.dev/internal/here"
|
||||||
"go.pinniped.dev/test/library"
|
"go.pinniped.dev/test/library"
|
||||||
@ -68,7 +70,13 @@ func TestClient(t *testing.T) {
|
|||||||
|
|
||||||
// Using the CA bundle and host from the current (admin) kubeconfig, do the token exchange.
|
// Using the CA bundle and host from the current (admin) kubeconfig, do the token exchange.
|
||||||
clientConfig := library.NewClientConfig(t)
|
clientConfig := library.NewClientConfig(t)
|
||||||
resp, err := client.ExchangeToken(ctx, namespace, token, string(clientConfig.CAData), clientConfig.Host)
|
|
||||||
|
idp := corev1.TypedLocalObjectReference{
|
||||||
|
APIGroup: &idpv1alpha1.SchemeGroupVersion.Group,
|
||||||
|
Kind: "WebhookIdentityProvider",
|
||||||
|
Name: "pinniped-webhook",
|
||||||
|
}
|
||||||
|
resp, err := client.ExchangeToken(ctx, namespace, idp, token, string(clientConfig.CAData), clientConfig.Host)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, resp.Status.ExpirationTimestamp)
|
require.NotNil(t, resp.Status.ExpirationTimestamp)
|
||||||
require.InDelta(t, time.Until(resp.Status.ExpirationTimestamp.Time), 1*time.Hour, float64(3*time.Minute))
|
require.InDelta(t, time.Until(resp.Status.ExpirationTimestamp.Time), 1*time.Hour, float64(3*time.Minute))
|
||||||
|
Loading…
Reference in New Issue
Block a user