package injector import ( "bytes" "context" "html/template" "github.com/linkerd/linkerd2/controller/k8s" "github.com/linkerd/linkerd2/controller/webhook" vizLabels "github.com/linkerd/linkerd2/viz/pkg/labels" log "github.com/sirupsen/logrus" admissionv1beta1 "k8s.io/api/admission/v1beta1" corev1 "k8s.io/api/core/v1" "k8s.io/client-go/tools/record" "sigs.k8s.io/yaml" ) // Params holds the values used in the patch template. type Params struct { ProxyPath string ProxyTapSvcName string } // Mutate mutates an AdmissionRequest and adds the LINKERD2_PROXY_TAP_SVC_NAME // env var to a pod's proxy container if tap is not disabled via annotation on the // pod or the namespace. func Mutate(tapSvcName string) webhook.Handler { return func( _ context.Context, k8sAPI *k8s.MetadataAPI, request *admissionv1beta1.AdmissionRequest, _ record.EventRecorder, ) (*admissionv1beta1.AdmissionResponse, error) { log.Debugf("request object bytes: %s", request.Object.Raw) admissionResponse := &admissionv1beta1.AdmissionResponse{ UID: request.UID, Allowed: true, } var pod *corev1.Pod if err := yaml.Unmarshal(request.Object.Raw, &pod); err != nil { return nil, err } params := Params{ ProxyPath: webhook.GetProxyContainerPath(pod.Spec), ProxyTapSvcName: tapSvcName, } if params.ProxyPath == "" || vizLabels.IsTapEnabled(pod) { return admissionResponse, nil } namespace, err := k8sAPI.Get(k8s.NS, request.Namespace) if err != nil { return nil, err } var t *template.Template if vizLabels.IsTapDisabled(namespace) || vizLabels.IsTapDisabled(pod) { return admissionResponse, nil } t, err = template.New("tpl").Parse(tpl) if err != nil { return nil, err } var patchJSON bytes.Buffer if err = t.Execute(&patchJSON, params); err != nil { return nil, err } patchType := admissionv1beta1.PatchTypeJSONPatch admissionResponse.Patch = patchJSON.Bytes() admissionResponse.PatchType = &patchType return admissionResponse, nil } }