2025-04-01 10:38:02 +09:00

105 lines
2.3 KiB
Go

package runner
import (
"context"
"errors"
"fmt"
"reflect"
"github.com/grafana/grafana-app-sdk/app"
"github.com/grafana/grafana-app-sdk/resource"
"k8s.io/apiserver/pkg/admission"
)
func (b *appBuilder) Mutate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) (err error) {
if b.app == nil {
return errors.New("app is nil")
}
req, err := b.translateAdmissionAttributes(a)
if err != nil {
return err
}
resp, err := b.app.Mutate(ctx, req)
if err != nil {
if errors.Is(err, app.ErrNotImplemented) {
return nil
}
return err
}
obj := a.GetObject()
if obj != nil && resp.UpdatedObject != nil {
reflect.ValueOf(obj).Elem().Set(reflect.ValueOf(resp.UpdatedObject).Elem())
}
return nil
}
func (b *appBuilder) Validate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) (err error) {
req, err := b.translateAdmissionAttributes(a)
if err != nil {
return err
}
err = b.app.Validate(ctx, req)
if err != nil {
if errors.Is(err, app.ErrNotImplemented) {
return nil
}
return err
}
return nil
}
func (b *appBuilder) translateAdmissionAttributes(a admission.Attributes) (*app.AdmissionRequest, error) {
extra := make(map[string]any)
for k, v := range a.GetUserInfo().GetExtra() {
extra[k] = any(v)
}
var action resource.AdmissionAction
switch a.GetOperation() {
case admission.Create:
action = resource.AdmissionActionCreate
case admission.Update:
action = resource.AdmissionActionUpdate
case admission.Delete:
action = resource.AdmissionActionDelete
case admission.Connect:
action = resource.AdmissionActionConnect
default:
return nil, fmt.Errorf("unknown admission operation: %v", a.GetOperation())
}
var (
obj resource.Object
oldObj resource.Object
)
if a.GetObject() != nil {
obj = a.GetObject().(resource.Object)
}
if a.GetOldObject() != nil {
oldObj = a.GetOldObject().(resource.Object)
}
req := app.AdmissionRequest{
Action: action,
Kind: a.GetKind().Kind,
Group: a.GetKind().Group,
Version: a.GetKind().Version,
UserInfo: resource.AdmissionUserInfo{
UID: a.GetUserInfo().GetUID(),
Username: a.GetUserInfo().GetName(),
Groups: a.GetUserInfo().GetGroups(),
Extra: extra,
},
Object: obj,
OldObject: oldObj,
}
return &req, nil
}