Add remaining k8s endpoints for Folders (#93146)

* Add remaining Folders k8s endpoints

Signed-off-by: Maicon Costa <maiconscosta@gmail.com>

* Remove duplicated import

Signed-off-by: Maicon Costa <maiconscosta@gmail.com>

---------

Signed-off-by: Maicon Costa <maiconscosta@gmail.com>
This commit is contained in:
maicon 2024-09-12 14:38:27 -03:00 committed by GitHub
parent f8fa5286a1
commit d1d578785c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 78 additions and 4 deletions

View File

@ -448,9 +448,12 @@ func (hs *HTTPServer) registerRoutes() {
if hs.Features.IsEnabledGlobally(featuremgmt.FlagKubernetesFolders) {
// Use k8s client to implement legacy API
handler := newFolderK8sHandler(hs)
folderRoute.Get("/", handler.searchFolders)
folderRoute.Post("/", handler.createFolder)
folderRoute.Group("/:uid", func(folderUidRoute routing.RouteRegister) {
folderUidRoute.Get("/", handler.getFolder)
folderUidRoute.Delete("/", handler.deleteFolder)
folderUidRoute.Put("/:uid", handler.updateFolder)
})
} else {
idScope := dashboards.ScopeFoldersProvider.GetResourceScope(ac.Parameter(":id"))

View File

@ -5,6 +5,7 @@ import (
"errors"
"net/http"
"strconv"
"strings"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -648,17 +649,43 @@ func newFolderK8sHandler(hs *HTTPServer) *folderK8sHandler {
}
}
func (fk8s *folderK8sHandler) searchFolders(c *contextmodel.ReqContext) {
client, ok := fk8s.getClient(c)
if !ok {
return // error is already sent
}
out, err := client.List(c.Req.Context(), v1.ListOptions{})
if err != nil {
fk8s.writeError(c, err)
return
}
query := strings.ToUpper(c.Query("query"))
folders := []folder.Folder{}
for _, item := range out.Items {
p := internalfolders.UnstructuredToLegacyFolder(item)
if p == nil {
continue
}
if query != "" && !strings.Contains(strings.ToUpper(p.Title), query) {
continue // query filter
}
folders = append(folders, *p)
}
c.JSON(http.StatusOK, folders)
}
func (fk8s *folderK8sHandler) createFolder(c *contextmodel.ReqContext) {
client, ok := fk8s.getClient(c)
if !ok {
return // error is already sent
}
cmd := folder.CreateFolderCommand{}
cmd := folder.UpdateFolderCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
c.JsonApiErr(http.StatusBadRequest, "bad request data", err)
return
}
obj := internalfolders.LegacyCreateCommandToUnstructured(cmd)
obj := internalfolders.LegacyUpdateCommandToUnstructured(cmd)
out, err := client.Create(c.Req.Context(), &obj, v1.CreateOptions{})
if err != nil {
fk8s.writeError(c, err)
@ -681,6 +708,41 @@ func (fk8s *folderK8sHandler) getFolder(c *contextmodel.ReqContext) {
c.JSON(http.StatusOK, internalfolders.UnstructuredToLegacyFolderDTO(*out))
}
func (fk8s *folderK8sHandler) deleteFolder(c *contextmodel.ReqContext) {
client, ok := fk8s.getClient(c)
if !ok {
return // error is already sent
}
uid := web.Params(c.Req)[":uid"]
err := client.Delete(c.Req.Context(), uid, v1.DeleteOptions{})
if err != nil {
fk8s.writeError(c, err)
return
}
c.JSON(http.StatusOK, "")
}
func (fk8s *folderK8sHandler) updateFolder(c *contextmodel.ReqContext) {
client, ok := fk8s.getClient(c)
if !ok {
return // error is already sent
}
uid := web.Params(c.Req)[":uid"]
cmd := folder.UpdateFolderCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
c.JsonApiErr(http.StatusBadRequest, "bad request data", err)
return
}
obj := internalfolders.LegacyUpdateCommandToUnstructured(cmd)
obj.SetName(uid)
out, err := client.Update(c.Req.Context(), &obj, v1.UpdateOptions{})
if err != nil {
fk8s.writeError(c, err)
return
}
c.JSON(http.StatusOK, internalfolders.UnstructuredToLegacyFolderDTO(*out))
}
//-----------------------------------------------------------------------------------------
// Utility functions
//-----------------------------------------------------------------------------------------

View File

@ -14,12 +14,12 @@ import (
"github.com/grafana/grafana/pkg/services/folder"
)
func LegacyCreateCommandToUnstructured(cmd folder.CreateFolderCommand) unstructured.Unstructured {
func LegacyUpdateCommandToUnstructured(cmd folder.UpdateFolderCommand) unstructured.Unstructured {
// #TODO add other fields
obj := unstructured.Unstructured{
Object: map[string]interface{}{
"spec": map[string]interface{}{
"title": cmd.Title,
"title": cmd.NewTitle,
},
},
}
@ -27,6 +27,15 @@ func LegacyCreateCommandToUnstructured(cmd folder.CreateFolderCommand) unstructu
return obj
}
func UnstructuredToLegacyFolder(item unstructured.Unstructured) *folder.Folder {
spec := item.Object["spec"].(map[string]any)
return &folder.Folder{
UID: item.GetName(),
Title: spec["title"].(string),
// #TODO add other fields
}
}
func UnstructuredToLegacyFolderDTO(item unstructured.Unstructured) *dtos.Folder {
spec := item.Object["spec"].(map[string]any)
dto := &dtos.Folder{