78 lines
2.4 KiB
Go
78 lines
2.4 KiB
Go
|
/*
|
||
|
Copyright 2020 VMware, Inc.
|
||
|
SPDX-License-Identifier: Apache-2.0
|
||
|
*/
|
||
|
|
||
|
package config
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"io/ioutil"
|
||
|
"os"
|
||
|
|
||
|
authenticationv1beta1 "k8s.io/api/authentication/v1beta1"
|
||
|
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||
|
"k8s.io/apiserver/plugin/pkg/authenticator/token/webhook"
|
||
|
"k8s.io/client-go/tools/clientcmd"
|
||
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||
|
|
||
|
"github.com/suzerain-io/placeholder-name/pkg/config/api"
|
||
|
)
|
||
|
|
||
|
// NewWebhook creates a webhook from the provided API server url and caBundle
|
||
|
// used to validate TLS connections.
|
||
|
func NewWebhook(spec api.WebhookConfigSpec) (*webhook.WebhookTokenAuthenticator, error) {
|
||
|
kubeconfig, err := ioutil.TempFile("", "placeholder-name-webhook-kubeconfig-*")
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("create temp file: %w", err)
|
||
|
}
|
||
|
defer os.Remove(kubeconfig.Name())
|
||
|
|
||
|
if err := anonymousKubeconfig(spec.URL, spec.CABundle, kubeconfig); err != nil {
|
||
|
return nil, fmt.Errorf("anonymous kubeconfig: %w", err)
|
||
|
}
|
||
|
|
||
|
// We use v1beta1 instead of v1 since v1beta1 is more prevalent in our desired
|
||
|
// integration points.
|
||
|
version := authenticationv1beta1.SchemeGroupVersion.Version
|
||
|
|
||
|
// At the current time, we don't provide any audiences because we simply don't
|
||
|
// have any requirements to do so. This can be changed in the future as
|
||
|
// requirements change.
|
||
|
var implicitAuds authenticator.Audiences
|
||
|
|
||
|
// We set this to nil because we would only need this to support some of the
|
||
|
// custom proxy stuff used by the API server.
|
||
|
var customDial utilnet.DialFunc
|
||
|
|
||
|
return webhook.New(kubeconfig.Name(), version, implicitAuds, customDial)
|
||
|
}
|
||
|
|
||
|
// anonymousKubeconfig writes a kubeconfig file to the provided io.Writer that
|
||
|
// will "use" anonymous auth to talk to a Kube API server at the provided url
|
||
|
// with the provided caBundle.
|
||
|
func anonymousKubeconfig(url string, caBundle []byte, out io.Writer) error {
|
||
|
config := clientcmdapi.NewConfig()
|
||
|
config.Clusters["anonymous-cluster"] = &clientcmdapi.Cluster{
|
||
|
Server: url,
|
||
|
CertificateAuthorityData: caBundle,
|
||
|
}
|
||
|
config.Contexts["anonymous"] = &clientcmdapi.Context{
|
||
|
Cluster: "anonymous-cluster",
|
||
|
}
|
||
|
config.CurrentContext = "anonymous"
|
||
|
|
||
|
data, err := clientcmd.Write(*config)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("marshal config: %w", err)
|
||
|
}
|
||
|
|
||
|
if _, err := out.Write(data); err != nil {
|
||
|
return fmt.Errorf("write config: %w", err)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|