...

Source file src/github.com/linkerd/linkerd2/jaeger/injector/mutator/webhook.go

Documentation: github.com/linkerd/linkerd2/jaeger/injector/mutator

     1  package mutator
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"html/template"
     8  	"strings"
     9  
    10  	"github.com/linkerd/linkerd2/controller/k8s"
    11  	"github.com/linkerd/linkerd2/controller/webhook"
    12  	"github.com/linkerd/linkerd2/jaeger/pkg/labels"
    13  	l5dLabels "github.com/linkerd/linkerd2/pkg/k8s"
    14  	log "github.com/sirupsen/logrus"
    15  	admissionv1beta1 "k8s.io/api/admission/v1beta1"
    16  	corev1 "k8s.io/api/core/v1"
    17  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    18  	"k8s.io/client-go/tools/record"
    19  	"sigs.k8s.io/yaml"
    20  )
    21  
    22  const (
    23  	collectorSvcAddrAnnotation    = l5dLabels.ProxyConfigAnnotationsPrefix + "/trace-collector"
    24  	collectorSvcAccountAnnotation = l5dLabels.ProxyConfigAnnotationsPrefixAlpha +
    25  		"/trace-collector-service-account"
    26  )
    27  
    28  // Params holds the values used in the patch template
    29  type Params struct {
    30  	ProxyPath           string
    31  	CollectorSvcAddr    string
    32  	CollectorSvcAccount string
    33  	ClusterDomain       string
    34  	LinkerdNamespace    string
    35  }
    36  
    37  // Mutate returns an AdmissionResponse containing the patch, if any, to apply
    38  // to the proxy
    39  func Mutate(collectorSvcAddr, collectorSvcAccount, clusterDomain, linkerdNamespace string) webhook.Handler {
    40  	return func(
    41  		_ context.Context,
    42  		api *k8s.MetadataAPI,
    43  		request *admissionv1beta1.AdmissionRequest,
    44  		_ record.EventRecorder,
    45  	) (*admissionv1beta1.AdmissionResponse, error) {
    46  		log.Debugf("request object bytes: %s", request.Object.Raw)
    47  
    48  		admissionResponse := &admissionv1beta1.AdmissionResponse{
    49  			UID:     request.UID,
    50  			Allowed: true,
    51  		}
    52  
    53  		if collectorSvcAddr == "" {
    54  			return admissionResponse, nil
    55  		}
    56  
    57  		var pod *corev1.Pod
    58  		if err := yaml.Unmarshal(request.Object.Raw, &pod); err != nil {
    59  			return nil, err
    60  		}
    61  		params := Params{
    62  			ProxyPath:           webhook.GetProxyContainerPath(pod.Spec),
    63  			CollectorSvcAddr:    collectorSvcAddr,
    64  			CollectorSvcAccount: collectorSvcAccount,
    65  			ClusterDomain:       clusterDomain,
    66  			LinkerdNamespace:    linkerdNamespace,
    67  		}
    68  		if params.ProxyPath == "" || labels.IsTracingEnabled(pod) {
    69  			return admissionResponse, nil
    70  		}
    71  
    72  		namespace, err := api.Get(k8s.NS, request.Namespace)
    73  		if err != nil {
    74  			return nil, err
    75  		}
    76  		applyOverrides(namespace, pod, &params)
    77  		amendSvcAccount(pod.Namespace, &params)
    78  
    79  		t, err := template.New("tpl").Parse(tpl)
    80  		if err != nil {
    81  			return nil, err
    82  		}
    83  		var patchJSON bytes.Buffer
    84  		if err = t.Execute(&patchJSON, params); err != nil {
    85  			return nil, err
    86  		}
    87  
    88  		patchType := admissionv1beta1.PatchTypeJSONPatch
    89  		admissionResponse.Patch = patchJSON.Bytes()
    90  		admissionResponse.PatchType = &patchType
    91  
    92  		return admissionResponse, nil
    93  	}
    94  }
    95  
    96  func applyOverrides(ns metav1.Object, pod *corev1.Pod, params *Params) {
    97  	ann := ns.GetAnnotations()
    98  	if ann == nil {
    99  		ann = map[string]string{}
   100  	}
   101  	for k, v := range pod.Annotations {
   102  		ann[k] = v
   103  	}
   104  	if override, ok := ann[collectorSvcAddrAnnotation]; ok {
   105  		params.CollectorSvcAddr = override
   106  	}
   107  	if override, ok := ann[collectorSvcAccountAnnotation]; ok {
   108  		params.CollectorSvcAccount = override
   109  	}
   110  }
   111  
   112  func amendSvcAccount(ns string, params *Params) {
   113  	hostAndPort := strings.Split(params.CollectorSvcAddr, ":")
   114  	hostname := strings.Split(hostAndPort[0], ".")
   115  	if len(hostname) > 1 {
   116  		ns = hostname[1]
   117  	}
   118  	params.CollectorSvcAccount = fmt.Sprintf("%s.%s", params.CollectorSvcAccount, ns)
   119  }
   120  

View as plain text