pass Dialer instead of egressselector to webhooks

This commit is contained in:
Jefftree 2019-12-05 17:28:59 -08:00
parent d318e52ffe
commit 1b38199ea8
15 changed files with 85 additions and 50 deletions

View File

@ -498,13 +498,13 @@ func buildGenericConfig(
}
versionedInformers = clientgoinformers.NewSharedInformerFactory(clientgoExternalClient, 10*time.Minute)
genericConfig.Authentication.Authenticator, genericConfig.OpenAPIConfig.SecurityDefinitions, err = BuildAuthenticator(s, genericConfig, clientgoExternalClient, versionedInformers)
genericConfig.Authentication.Authenticator, genericConfig.OpenAPIConfig.SecurityDefinitions, err = BuildAuthenticator(s, genericConfig.EgressSelector, clientgoExternalClient, versionedInformers)
if err != nil {
lastErr = fmt.Errorf("invalid authentication config: %v", err)
return
}
genericConfig.Authorization.Authorizer, genericConfig.RuleResolver, err = BuildAuthorizer(s, versionedInformers)
genericConfig.Authorization.Authorizer, genericConfig.RuleResolver, err = BuildAuthorizer(s, genericConfig.EgressSelector, versionedInformers)
if err != nil {
lastErr = fmt.Errorf("invalid authorization config: %v", err)
return
@ -560,7 +560,7 @@ func buildGenericConfig(
}
// BuildAuthenticator constructs the authenticator
func BuildAuthenticator(s *options.ServerRunOptions, c *genericapiserver.Config, extclient clientgoclientset.Interface, versionedInformer clientgoinformers.SharedInformerFactory) (authenticator.Request, *spec.SecurityDefinitions, error) {
func BuildAuthenticator(s *options.ServerRunOptions, EgressSelector *egressselector.EgressSelector, extclient clientgoclientset.Interface, versionedInformer clientgoinformers.SharedInformerFactory) (authenticator.Request, *spec.SecurityDefinitions, error) {
authenticatorConfig, err := s.Authentication.ToAuthenticationConfig()
if err != nil {
return nil, nil, err
@ -577,16 +577,29 @@ func BuildAuthenticator(s *options.ServerRunOptions, c *genericapiserver.Config,
versionedInformer.Core().V1().Secrets().Lister().Secrets(v1.NamespaceSystem),
)
if c.EgressSelector != nil {
authenticatorConfig.EgressLookup = c.EgressSelector.Lookup
if EgressSelector != nil {
egressDialer, err := EgressSelector.Lookup(egressselector.Master.AsNetworkContext())
if err != nil {
return nil, nil, err
}
authenticatorConfig.CustomDial = egressDialer
}
return authenticatorConfig.New()
}
// BuildAuthorizer constructs the authorizer
func BuildAuthorizer(s *options.ServerRunOptions, versionedInformers clientgoinformers.SharedInformerFactory) (authorizer.Authorizer, authorizer.RuleResolver, error) {
func BuildAuthorizer(s *options.ServerRunOptions, EgressSelector *egressselector.EgressSelector, versionedInformers clientgoinformers.SharedInformerFactory) (authorizer.Authorizer, authorizer.RuleResolver, error) {
authorizationConfig := s.Authorization.ToAuthorizationConfig(versionedInformers)
if EgressSelector != nil {
egressDialer, err := EgressSelector.Lookup(egressselector.Master.AsNetworkContext())
if err != nil {
return nil, nil, err
}
authorizationConfig.CustomDial = egressDialer
}
return authorizationConfig.New()
}

View File

@ -12,6 +12,7 @@ go_library(
deps = [
"//pkg/features:go_default_library",
"//pkg/serviceaccount:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/group:go_default_library",
@ -25,7 +26,6 @@ go_library(
"//staging/src/k8s.io/apiserver/pkg/authentication/token/tokenfile:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/token/union:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/dynamiccertificates:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/egressselector:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile:go_default_library",
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth:go_default_library",

View File

@ -21,6 +21,7 @@ import (
"github.com/go-openapi/spec"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/authenticatorfactory"
"k8s.io/apiserver/pkg/authentication/group"
@ -34,7 +35,6 @@ import (
"k8s.io/apiserver/pkg/authentication/token/tokenfile"
tokenunion "k8s.io/apiserver/pkg/authentication/token/union"
"k8s.io/apiserver/pkg/server/dynamiccertificates"
"k8s.io/apiserver/pkg/server/egressselector"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile"
"k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth"
@ -85,8 +85,8 @@ type Config struct {
// If this value is nil, then mutual TLS is disabled.
ClientCAContentProvider dynamiccertificates.CAContentProvider
// Lookup will give us a dialer if the egress selector is configured for it
EgressLookup egressselector.Lookup
// Optional field, custom dial function used to connect to webhook
CustomDial utilnet.DialFunc
}
// New returns an authenticator.Request or an error that supports the standard
@ -311,15 +311,10 @@ func newServiceAccountAuthenticator(iss string, keyfiles []string, apiAudiences
}
func newWebhookTokenAuthenticator(config Config) (authenticator.Token, error) {
webhookConfigFile := config.WebhookTokenAuthnConfigFile
version := config.WebhookTokenAuthnVersion
ttl := config.WebhookTokenAuthnCacheTTL
implicitAuds := config.APIAudiences
webhookTokenAuthenticator, err := webhook.New(webhookConfigFile, version, implicitAuds, config.EgressLookup)
webhookTokenAuthenticator, err := webhook.New(config.WebhookTokenAuthnConfigFile, config.WebhookTokenAuthnVersion, config.APIAudiences, config.CustomDial)
if err != nil {
return nil, err
}
return tokencache.New(webhookTokenAuthenticator, false, ttl, ttl), nil
return tokencache.New(webhookTokenAuthenticator, false, config.WebhookTokenAuthnCacheTTL, config.WebhookTokenAuthnCacheTTL), nil
}

View File

@ -16,6 +16,7 @@ go_library(
"//plugin/pkg/auth/authorizer/node:go_default_library",
"//plugin/pkg/auth/authorizer/rbac:go_default_library",
"//plugin/pkg/auth/authorizer/rbac/bootstrappolicy:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authorization/union:go_default_library",

View File

@ -20,6 +20,7 @@ import (
"fmt"
"time"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
"k8s.io/apiserver/pkg/authorization/union"
@ -54,6 +55,9 @@ type Config struct {
WebhookCacheUnauthorizedTTL time.Duration
VersionedInformerFactory versionedinformers.SharedInformerFactory
// Optional field, custom dial function used to connect to webhook
CustomDial utilnet.DialFunc
}
// New returns the right sort of union of multiple authorizer.Authorizer objects
@ -102,7 +106,8 @@ func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, erro
webhookAuthorizer, err := webhook.New(config.WebhookConfigFile,
config.WebhookVersion,
config.WebhookCacheAuthorizedTTL,
config.WebhookCacheUnauthorizedTTL)
config.WebhookCacheUnauthorizedTTL,
config.CustomDial)
if err != nil {
return nil, nil, err
}

View File

@ -29,7 +29,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/egressselector:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library",
"//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library",
"//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library",

View File

@ -29,7 +29,6 @@ import (
"k8s.io/apimachinery/pkg/util/net"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/server/egressselector"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
@ -63,11 +62,11 @@ func DefaultShouldRetry(err error) bool {
}
// NewGenericWebhook creates a new GenericWebhook from the provided kubeconfig file.
func NewGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff time.Duration, egressLookup egressselector.Lookup) (*GenericWebhook, error) {
return newGenericWebhook(scheme, codecFactory, kubeConfigFile, groupVersions, initialBackoff, defaultRequestTimeout, egressLookup)
func NewGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff time.Duration, customDial utilnet.DialFunc) (*GenericWebhook, error) {
return newGenericWebhook(scheme, codecFactory, kubeConfigFile, groupVersions, initialBackoff, defaultRequestTimeout, customDial)
}
func newGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff, requestTimeout time.Duration, egressLookup egressselector.Lookup) (*GenericWebhook, error) {
func newGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff, requestTimeout time.Duration, customDial utilnet.DialFunc) (*GenericWebhook, error) {
for _, groupVersion := range groupVersions {
if !scheme.IsVersionRegistered(groupVersion) {
return nil, fmt.Errorf("webhook plugin requires enabling extension resource: %s", groupVersion)
@ -96,14 +95,9 @@ func newGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFact
codec := codecFactory.LegacyCodec(groupVersions...)
clientConfig.ContentConfig.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec})
if egressLookup != nil {
networkContext := egressselector.Master.AsNetworkContext()
var egressDialer utilnet.DialFunc
egressDialer, err = egressLookup(networkContext)
if err != nil {
return nil, err
}
clientConfig.Dial = egressDialer
if customDial != nil {
clientConfig.Dial = customDial
}
restClient, err := rest.UnversionedRESTClientFor(clientConfig)

View File

@ -39,9 +39,9 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/egressselector:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/typed/authentication/v1:go_default_library",

View File

@ -28,9 +28,9 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/server/egressselector"
"k8s.io/apiserver/pkg/util/webhook"
"k8s.io/client-go/kubernetes/scheme"
authenticationv1client "k8s.io/client-go/kubernetes/typed/authentication/v1"
@ -64,8 +64,8 @@ func NewFromInterface(tokenReview authenticationv1client.TokenReviewInterface, i
// file. It is recommend to wrap this authenticator with the token cache
// authenticator implemented in
// k8s.io/apiserver/pkg/authentication/token/cache.
func New(kubeConfigFile string, version string, implicitAuds authenticator.Audiences, egressLookup egressselector.Lookup) (*WebhookTokenAuthenticator, error) {
tokenReview, err := tokenReviewInterfaceFromKubeconfig(kubeConfigFile, version, egressLookup)
func New(kubeConfigFile string, version string, implicitAuds authenticator.Audiences, customDial utilnet.DialFunc) (*WebhookTokenAuthenticator, error) {
tokenReview, err := tokenReviewInterfaceFromKubeconfig(kubeConfigFile, version, customDial)
if err != nil {
return nil, err
}
@ -154,7 +154,7 @@ func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token
// tokenReviewInterfaceFromKubeconfig builds a client from the specified kubeconfig file,
// and returns a TokenReviewInterface that uses that client. Note that the client submits TokenReview
// requests to the exact path specified in the kubeconfig file, so arbitrary non-API servers can be targeted.
func tokenReviewInterfaceFromKubeconfig(kubeConfigFile string, version string, egressLookup egressselector.Lookup) (tokenReviewer, error) {
func tokenReviewInterfaceFromKubeconfig(kubeConfigFile string, version string, customDial utilnet.DialFunc) (tokenReviewer, error) {
localScheme := runtime.NewScheme()
if err := scheme.AddToScheme(localScheme); err != nil {
return nil, err
@ -166,7 +166,7 @@ func tokenReviewInterfaceFromKubeconfig(kubeConfigFile string, version string, e
if err := localScheme.SetVersionPriority(groupVersions...); err != nil {
return nil, err
}
gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, egressLookup)
gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, customDial)
if err != nil {
return nil, err
}
@ -177,7 +177,7 @@ func tokenReviewInterfaceFromKubeconfig(kubeConfigFile string, version string, e
if err := localScheme.SetVersionPriority(groupVersions...); err != nil {
return nil, err
}
gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, egressLookup)
gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, customDial)
if err != nil {
return nil, err
}

View File

@ -39,6 +39,7 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/cache:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",

View File

@ -31,6 +31,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/cache"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/util/webhook"
@ -84,8 +85,8 @@ func NewFromInterface(subjectAccessReview authorizationv1client.SubjectAccessRev
//
// For additional HTTP configuration, refer to the kubeconfig documentation
// https://kubernetes.io/docs/user-guide/kubeconfig-file/.
func New(kubeConfigFile string, version string, authorizedTTL, unauthorizedTTL time.Duration) (*WebhookAuthorizer, error) {
subjectAccessReview, err := subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile, version)
func New(kubeConfigFile string, version string, authorizedTTL, unauthorizedTTL time.Duration, customDial utilnet.DialFunc) (*WebhookAuthorizer, error) {
subjectAccessReview, err := subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile, version, customDial)
if err != nil {
return nil, err
}
@ -245,7 +246,7 @@ func convertToSARExtra(extra map[string][]string) map[string]authorizationv1.Ext
// subjectAccessReviewInterfaceFromKubeconfig builds a client from the specified kubeconfig file,
// and returns a SubjectAccessReviewInterface that uses that client. Note that the client submits SubjectAccessReview
// requests to the exact path specified in the kubeconfig file, so arbitrary non-API servers can be targeted.
func subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile string, version string) (subjectAccessReviewer, error) {
func subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile string, version string, customDial utilnet.DialFunc) (subjectAccessReviewer, error) {
localScheme := runtime.NewScheme()
if err := scheme.AddToScheme(localScheme); err != nil {
return nil, err
@ -257,7 +258,7 @@ func subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile string, version s
if err := localScheme.SetVersionPriority(groupVersions...); err != nil {
return nil, err
}
gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, nil)
gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, customDial)
if err != nil {
return nil, err
}
@ -268,7 +269,7 @@ func subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile string, version s
if err := localScheme.SetVersionPriority(groupVersions...); err != nil {
return nil, err
}
gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, nil)
gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, customDial)
if err != nil {
return nil, err
}

View File

@ -186,7 +186,7 @@ current-context: default
return fmt.Errorf("failed to execute test template: %v", err)
}
// Create a new authorizer
sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1")
sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1", nil)
if err != nil {
return fmt.Errorf("error building sar client: %v", err)
}
@ -325,7 +325,7 @@ func newV1Authorizer(callbackURL string, clientCert, clientKey, ca []byte, cache
if err := json.NewEncoder(tempfile).Encode(config); err != nil {
return nil, err
}
sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1")
sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1", nil)
if err != nil {
return nil, fmt.Errorf("error building sar client: %v", err)
}

View File

@ -186,7 +186,7 @@ current-context: default
return fmt.Errorf("failed to execute test template: %v", err)
}
// Create a new authorizer
sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1beta1")
sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1beta1", nil)
if err != nil {
return fmt.Errorf("error building sar client: %v", err)
}
@ -325,7 +325,7 @@ func newV1beta1Authorizer(callbackURL string, clientCert, clientKey, ca []byte,
if err := json.NewEncoder(tempfile).Encode(config); err != nil {
return nil, err
}
sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1beta1")
sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1beta1", nil)
if err != nil {
return nil, fmt.Errorf("error building sar client: %v", err)
}

View File

@ -59,6 +59,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",

View File

@ -37,6 +37,7 @@ import (
authenticationv1beta1 "k8s.io/api/authentication/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/group"
"k8s.io/apiserver/pkg/authentication/request/bearertoken"
@ -69,7 +70,7 @@ func getTestTokenAuth() authenticator.Request {
return group.NewGroupAdder(bearertoken.New(tokenAuthenticator), []string{user.AllAuthenticated})
}
func getTestWebhookTokenAuth(serverURL string) (authenticator.Request, error) {
func getTestWebhookTokenAuth(serverURL string, customDial utilnet.DialFunc) (authenticator.Request, error) {
kubecfgFile, err := ioutil.TempFile("", "webhook-kubecfg")
if err != nil {
return nil, err
@ -85,13 +86,19 @@ func getTestWebhookTokenAuth(serverURL string) (authenticator.Request, error) {
if err := json.NewEncoder(kubecfgFile).Encode(config); err != nil {
return nil, err
}
webhookTokenAuth, err := webhook.New(kubecfgFile.Name(), "v1beta1", nil, nil)
webhookTokenAuth, err := webhook.New(kubecfgFile.Name(), "v1beta1", nil, customDial)
if err != nil {
return nil, err
}
return bearertoken.New(cache.New(webhookTokenAuth, false, 2*time.Minute, 2*time.Minute)), nil
}
func getTestWebhookTokenAuthCustomDialer(serverURL string) (authenticator.Request, error) {
customDial := http.DefaultTransport.(*http.Transport).DialContext
return getTestWebhookTokenAuth(serverURL, customDial)
}
func path(resource, namespace, name string) string {
return pathWithPrefix("", resource, namespace, name)
}
@ -1192,9 +1199,27 @@ func TestReadOnlyAuthorization(t *testing.T) {
// authenticator to call out to a remote web server for authentication
// decisions.
func TestWebhookTokenAuthenticator(t *testing.T) {
testWebhookTokenAuthenticator(false, t)
}
// TestWebhookTokenAuthenticatorCustomDial is the same as TestWebhookTokenAuthenticator, but uses a
// custom dialer
func TestWebhookTokenAuthenticatorCustomDial(t *testing.T) {
testWebhookTokenAuthenticator(true, t)
}
func testWebhookTokenAuthenticator(customDialer bool, t *testing.T) {
authServer := newTestWebhookTokenAuthServer()
defer authServer.Close()
authenticator, err := getTestWebhookTokenAuth(authServer.URL)
var authenticator authenticator.Request
var err error
if customDialer == false {
authenticator, err = getTestWebhookTokenAuth(authServer.URL, nil)
} else {
authenticator, err = getTestWebhookTokenAuthCustomDialer(authServer.URL)
}
if err != nil {
t.Fatalf("error starting webhook token authenticator server: %v", err)
}