mirror of https://github.com/linkerd/linkerd2.git
112 lines
3.2 KiB
Go
112 lines
3.2 KiB
Go
package injector
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"text/template"
|
|
|
|
"github.com/linkerd/linkerd2/controller/proxy-injector/tmpl"
|
|
k8sPkg "github.com/linkerd/linkerd2/pkg/k8s"
|
|
"github.com/linkerd/linkerd2/pkg/tls"
|
|
log "github.com/sirupsen/logrus"
|
|
arv1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/client-go/kubernetes"
|
|
"sigs.k8s.io/yaml"
|
|
)
|
|
|
|
// WebhookConfig creates the MutatingWebhookConfiguration of the webhook.
|
|
type WebhookConfig struct {
|
|
controllerNamespace string
|
|
webhookServiceName string
|
|
trustAnchor []byte
|
|
configTemplate *template.Template
|
|
k8sAPI kubernetes.Interface
|
|
}
|
|
|
|
// NewWebhookConfig returns a new instance of initiator.
|
|
func NewWebhookConfig(client kubernetes.Interface, controllerNamespace, webhookServiceName string, rootCA *tls.CA) (*WebhookConfig, error) {
|
|
trustAnchor := rootCA.Cred.EncodeCertificatePEM()
|
|
|
|
t := template.New(k8sPkg.ProxyInjectorWebhookConfig)
|
|
|
|
return &WebhookConfig{
|
|
controllerNamespace: controllerNamespace,
|
|
webhookServiceName: webhookServiceName,
|
|
trustAnchor: []byte(trustAnchor),
|
|
configTemplate: template.Must(t.Parse(tmpl.MutatingWebhookConfigurationSpec)),
|
|
k8sAPI: client,
|
|
}, nil
|
|
}
|
|
|
|
// Create sends the request to create the MutatingWebhookConfiguration resource.
|
|
func (w *WebhookConfig) Create() (*arv1beta1.MutatingWebhookConfiguration, error) {
|
|
exists, err := w.exists()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if exists {
|
|
log.Info("deleting existing mutating webhook configuration")
|
|
if err := w.delete(); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return w.create()
|
|
}
|
|
|
|
// exists returns true if the mutating webhook configuration exists. Otherwise,
|
|
// it returns false.
|
|
func (w *WebhookConfig) exists() (bool, error) {
|
|
_, err := w.get()
|
|
if err != nil {
|
|
if apierrors.IsNotFound(err) {
|
|
return false, nil
|
|
}
|
|
|
|
return false, err
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
func (w *WebhookConfig) create() (*arv1beta1.MutatingWebhookConfiguration, error) {
|
|
var (
|
|
buf = &bytes.Buffer{}
|
|
spec = struct {
|
|
WebhookConfigName string
|
|
WebhookServiceName string
|
|
ControllerNamespace string
|
|
CABundle string
|
|
}{
|
|
WebhookConfigName: k8sPkg.ProxyInjectorWebhookConfig,
|
|
WebhookServiceName: w.webhookServiceName,
|
|
ControllerNamespace: w.controllerNamespace,
|
|
CABundle: base64.StdEncoding.EncodeToString(w.trustAnchor),
|
|
}
|
|
)
|
|
if err := w.configTemplate.Execute(buf, spec); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var config arv1beta1.MutatingWebhookConfiguration
|
|
if err := yaml.Unmarshal(buf.Bytes(), &config); err != nil {
|
|
log.Infof("failed to unmarshal mutating webhook configuration: %s\n%s\n", err, buf.String())
|
|
return nil, err
|
|
}
|
|
|
|
return w.k8sAPI.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().Create(&config)
|
|
}
|
|
|
|
func (w *WebhookConfig) get() (*arv1beta1.MutatingWebhookConfiguration, error) {
|
|
return w.k8sAPI.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().
|
|
Get(k8sPkg.ProxyInjectorWebhookConfig, metav1.GetOptions{})
|
|
}
|
|
|
|
func (w *WebhookConfig) delete() error {
|
|
return w.k8sAPI.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().Delete(
|
|
k8sPkg.ProxyInjectorWebhookConfig, &metav1.DeleteOptions{})
|
|
}
|