grafana/pkg/aggregator/apiserver/plugin/admission.go

128 lines
3.5 KiB
Go

package plugin
import (
"encoding/json"
"fmt"
"net/http"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/aggregator/apiserver/plugin/admission"
"github.com/grafana/grafana/pkg/aggregator/apiserver/util"
grafanasemconv "github.com/grafana/grafana/pkg/semconv"
"k8s.io/component-base/tracing"
"k8s.io/klog/v2"
)
func (h *PluginHandler) AdmissionMutationHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
span := tracing.SpanFromContext(ctx)
span.AddEvent("AdmissionMutationHandler")
responder := &util.Responder{ResponseWriter: w}
ar, err := admission.ParseRequest(h.admissionCodecs, r)
if err != nil {
responder.Error(w, r, err)
return
}
span.AddEvent("GetPluginContext",
grafanasemconv.GrafanaPluginId(h.dataplaneService.Spec.PluginID),
)
pluginContext, err := h.pluginContextProvider.GetPluginContext(ctx, h.dataplaneService.Spec.PluginID, "")
if err != nil {
responder.Error(w, r, fmt.Errorf("unable to get plugin context: %w", err))
return
}
req, err := admission.ToAdmissionRequest(pluginContext, ar)
if err != nil {
responder.Error(w, r, fmt.Errorf("unable to convert admission request: %w", err))
return
}
ctx = backend.WithGrafanaConfig(ctx, pluginContext.GrafanaConfig)
span.AddEvent("MutateAdmission start")
rsp, err := h.client.MutateAdmission(ctx, req)
if err != nil {
responder.Error(w, r, err)
return
}
span.AddEvent("MutateAdmission end")
span.AddEvent("FromMutationResponse start")
res, err := admission.FromMutationResponse(ar.Request.Object.Raw, rsp)
if err != nil {
responder.Error(w, r, err)
return
}
res.SetGroupVersionKind(ar.GroupVersionKind())
res.Response.UID = ar.Request.UID
respBytes, err := json.Marshal(res)
if err != nil {
klog.Error(err)
responder.Error(w, r, err)
return
}
w.Header().Set("Content-Type", "application/json")
if _, err := w.Write(respBytes); err != nil {
klog.Error(err)
}
})
}
func (h *PluginHandler) AdmissionValidationHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
span := tracing.SpanFromContext(ctx)
span.AddEvent("AdmissionValidationHandler")
responder := &util.Responder{ResponseWriter: w}
ar, err := admission.ParseRequest(h.admissionCodecs, r)
if err != nil {
responder.Error(w, r, err)
return
}
span.AddEvent("GetPluginContext",
grafanasemconv.GrafanaPluginId(h.dataplaneService.Spec.PluginID),
)
pluginContext, err := h.pluginContextProvider.GetPluginContext(ctx, h.dataplaneService.Spec.PluginID, "")
if err != nil {
responder.Error(w, r, fmt.Errorf("unable to get plugin context: %w", err))
return
}
req, err := admission.ToAdmissionRequest(pluginContext, ar)
if err != nil {
responder.Error(w, r, fmt.Errorf("unable to convert admission request: %w", err))
return
}
ctx = backend.WithGrafanaConfig(ctx, pluginContext.GrafanaConfig)
span.AddEvent("ValidateAdmission start")
rsp, err := h.client.ValidateAdmission(ctx, req)
if err != nil {
responder.Error(w, r, err)
return
}
span.AddEvent("ValidateAdmission end")
res := admission.FromValidationResponse(rsp)
res.SetGroupVersionKind(ar.GroupVersionKind())
res.Response.UID = ar.Request.UID
respBytes, err := json.Marshal(res)
if err != nil {
klog.Error(err)
responder.Error(w, r, err)
return
}
w.Header().Set("Content-Type", "application/json")
if _, err := w.Write(respBytes); err != nil {
klog.Error(err)
}
})
}