Grafana Indexing PoC: Adds feature flag and gRPC endpoint (#93356)

* adds Filter gRPC and make protobuf

* adds route for querying the filter gRPC

* wires up Filter gRPC call

* [WIP] index from start

* renames gRPC endpoint to "Search"

* adds /apis/search route into k8s routes. Hacky for now.

* updates readme - wrong casing

* adds feature toggle for unified storage search

* hides US search behind feature flag. Clean up print statements.

* removes indexer - will be added in another PR

* Search: Add API Builder

* adds required method

* implementing UpdateAPIGroupInfo (WIP)

* adds groupversion

* commenting out for now

* remove unneeded code from experimenting and update register.go to match interface required

* namespaces search route

---------

Co-authored-by: leonorfmartins <leonorfmartins@gmail.com>
Co-authored-by: Todd Treece <todd.treece@grafana.com>
This commit is contained in:
owensmallwood
2024-09-30 13:46:14 -06:00
committed by GitHub
co-authored by leonorfmartins Todd Treece
parent cebcb38df2
commit 6a3eb276ef
18 changed files with 599 additions and 214 deletions
+2
View File
@@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/registry/apis/playlist"
"github.com/grafana/grafana/pkg/registry/apis/query"
"github.com/grafana/grafana/pkg/registry/apis/scope"
"github.com/grafana/grafana/pkg/registry/apis/search"
)
var (
@@ -37,6 +38,7 @@ func ProvideRegistryServiceSink(
_ *scope.ScopeAPIBuilder,
_ *query.QueryAPIBuilder,
_ *notifications.NotificationsAPIBuilder,
_ *search.SearchAPIBuilder,
) *Service {
return &Service{}
}
@@ -246,6 +246,10 @@ func (a *dashboardSqlAccess) Read(ctx context.Context, req *resource.ReadRequest
return a.ReadResource(ctx, req), nil
}
func (a *dashboardSqlAccess) Search(ctx context.Context, req *resource.SearchRequest) (*resource.SearchResponse, error) {
return nil, fmt.Errorf("not yet (filter)")
}
func (a *dashboardSqlAccess) History(ctx context.Context, req *resource.HistoryRequest) (*resource.HistoryResponse, error) {
info, err := claims.ParseNamespace(req.Key.Namespace)
if err == nil {
+103
View File
@@ -0,0 +1,103 @@
package search
import (
"encoding/json"
"net/http"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
genericapiserver "k8s.io/apiserver/pkg/server"
common "k8s.io/kube-openapi/pkg/common"
"k8s.io/kube-openapi/pkg/spec3"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/grafana/grafana/pkg/services/apiserver/builder"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/storage/unified/resource"
)
var _ builder.APIGroupBuilder = (*SearchAPIBuilder)(nil)
type SearchAPIBuilder struct {
unified resource.ResourceClient
}
func NewSearchAPIBuilder(
unified resource.ResourceClient,
) (*SearchAPIBuilder, error) {
return &SearchAPIBuilder{
unified: unified,
}, nil
}
func RegisterAPIService(
features featuremgmt.FeatureToggles,
apiregistration builder.APIRegistrar,
unified resource.ResourceClient,
) (*SearchAPIBuilder, error) {
if !(features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageSearch) || features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs)) {
return nil, nil
}
builder, err := NewSearchAPIBuilder(unified)
apiregistration.RegisterAPI(builder)
return builder, err
}
func (b *SearchAPIBuilder) GetGroupVersion() schema.GroupVersion {
return schema.GroupVersion{Group: "search.grafana.app", Version: "v0alpha1"}
}
func (b *SearchAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
return nil
}
func (b *SearchAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
return func(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{}
}
}
func (b *SearchAPIBuilder) GetAPIRoutes() *builder.APIRoutes {
return &builder.APIRoutes{
Namespace: []builder.APIRouteHandler{
{
Path: "search",
Spec: &spec3.PathProps{
Get: &spec3.Operation{
OperationProps: spec3.OperationProps{
Tags: []string{"Search"},
Summary: "Search",
Description: "Search for resources",
},
},
},
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
urlQuery := r.URL.Query().Get("query")
searchRequest := &resource.SearchRequest{Query: urlQuery}
res, err := b.unified.Search(r.Context(), searchRequest)
if err != nil {
panic(err)
}
if err := json.NewEncoder(w).Encode(res); err != nil {
panic(err)
}
}),
},
},
}
}
func (b *SearchAPIBuilder) GetAuthorizer() authorizer.Authorizer {
return nil
}
func (b *SearchAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.OpenAPI, error) {
return oas, nil
}
func (b *SearchAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter, dualWriteBuilder grafanarest.DualWriteBuilder) error {
apiGroupInfo.PrioritizedVersions = []schema.GroupVersion{b.GetGroupVersion()}
return nil
}
+2
View File
@@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/registry/apis/playlist"
"github.com/grafana/grafana/pkg/registry/apis/query"
"github.com/grafana/grafana/pkg/registry/apis/scope"
"github.com/grafana/grafana/pkg/registry/apis/search"
"github.com/grafana/grafana/pkg/registry/apis/service"
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
)
@@ -40,4 +41,5 @@ var WireSet = wire.NewSet(
scope.RegisterAPIService,
notifications.RegisterAPIService,
//sso.RegisterAPIService,
search.RegisterAPIService,
)