Files
grafana/pkg/registry/apis/provisioning/webhook.go
T
Roberto Jiménez Sánchez d8b1834139 [Prototyping] Update resources on github webhook events (#97113)
* Add replicator interface
* Use factory to create replicators
* Use replicator in import
2024-11-28 11:48:42 +01:00

97 lines
2.7 KiB
Go

package provisioning
import (
"context"
"fmt"
"log/slog"
"net/http"
"k8s.io/apimachinery/pkg/api/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"
"k8s.io/apiserver/pkg/endpoints/request"
"github.com/grafana/grafana/pkg/apimachinery/identity"
provisioning "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/auth"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/resources"
)
// This only works for github right now
type webhookConnector struct {
client auth.BackgroundIdentityService
getter RepoGetter
logger *slog.Logger
resourceClient *resources.ClientFactory
}
func (*webhookConnector) New() runtime.Object {
// This is added as the "ResponseType" regardless what ProducesObject() returns
return &provisioning.WebhookResponse{}
}
func (*webhookConnector) Destroy() {}
func (*webhookConnector) NamespaceScoped() bool {
return true
}
func (*webhookConnector) GetSingularName() string {
return "WebhookResponse"
}
func (*webhookConnector) ProducesMIMETypes(verb string) []string {
return []string{"application/json"}
}
func (*webhookConnector) ProducesObject(verb string) any {
return &provisioning.WebhookResponse{}
}
func (*webhookConnector) ConnectMethods() []string {
return []string{
http.MethodPost,
http.MethodGet, // only useful for browser testing, should be removed
}
}
func (*webhookConnector) NewConnectOptions() (runtime.Object, bool, string) {
return nil, false, ""
}
func (s *webhookConnector) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) {
namespace := request.NamespaceValue(ctx)
id, err := s.client.WorkerIdentity(ctx, namespace)
if err != nil {
return nil, err
}
// Get the repository with the worker identity (since the request user is likely anonymous)
repo, err := s.getter.GetRepository(identity.WithRequester(ctx, id), name)
if err != nil {
return nil, err
}
factory := resources.NewReplicatorFactory(s.resourceClient, namespace, repo)
webhook := repo.Webhook(ctx, s.logger, responder, factory)
if webhook == nil {
return nil, &errors.StatusError{
ErrStatus: v1.Status{
Message: fmt.Sprintf("webhook is not implemented for: %s", repo.Config().Spec.Type),
Code: http.StatusNotImplemented,
},
}
}
return webhook, nil
}
var (
_ rest.Storage = (*webhookConnector)(nil)
_ rest.Connecter = (*webhookConnector)(nil)
_ rest.Scoper = (*webhookConnector)(nil)
_ rest.SingularNameProvider = (*webhookConnector)(nil)
_ rest.StorageMetadata = (*webhookConnector)(nil)
)