From 0d14c27eb99d327fb0b284ed4d2dfab0bf174f60 Mon Sep 17 00:00:00 2001 From: ying-jeanne <74549700+ying-jeanne@users.noreply.github.com> Date: Thu, 5 May 2022 10:04:54 +0200 Subject: [PATCH] Chore: add Folderuid into panel-library API (#48577) * add folderuid into interface * panellibrary id/uid things * modify doc * update doc * correct some comments --- docs/sources/http_api/library_element.md | 10 ++- pkg/services/libraryelements/api.go | 44 +++++++++++ pkg/services/libraryelements/database.go | 3 +- .../libraryelements_create_test.go | 6 ++ .../libraryelements_patch_test.go | 4 + pkg/services/libraryelements/models.go | 5 ++ public/api-merged.json | 74 +++++++++++-------- public/api-spec.json | 74 +++++++++++-------- 8 files changed, 156 insertions(+), 64 deletions(-) diff --git a/docs/sources/http_api/library_element.md b/docs/sources/http_api/library_element.md index 3b500f3837a..7b40d5d2087 100644 --- a/docs/sources/http_api/library_element.md +++ b/docs/sources/http_api/library_element.md @@ -269,7 +269,8 @@ Creates a new library element. JSON Body schema: -- **folderId** – Optional, the ID of the folder where the library element is stored. +- **folderId** – ID of the folder where the library element is stored. It is deprecated since Grafana v9 +- **folderUid** – Optional, the UID of the folder where the library element is stored, empty string when it is General folder - **name** – Optional, the name of the library element. - **model** – The JSON model for the library element. - **kind** – Kind of element to create, Use `1` for library panels or `2` for library variables. @@ -285,7 +286,7 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk { "uid": "nErXDvCkzz", - "folderId": 0, + "folderUid": "", "name": "Example library panel", "model": {...}, "kind": 1 @@ -303,6 +304,7 @@ Content-Type: application/json "id": 28, "orgId": 1, "folderId": 0, + "folderUid": "", "uid": "nErXDvCkzz", "name": "Example library panel", "kind": 1, @@ -346,7 +348,8 @@ Updates an existing library element identified by uid. JSON Body schema: -- **folderId** – ID of the folder where the library element is stored. +- **folderId** – ID of the folder where the library element is stored. It is deprecated since Grafana v9 +- **folderUid** – UID of the folder where the library element is stored, empty string when it is General folder. - **name** – Name of the library element. - **model** – The JSON model for the library element. - **kind** – Kind of element to create. Use `1` for library panels or `2` for library variables. @@ -379,6 +382,7 @@ Content-Type: application/json "id": 28, "orgId": 1, "folderId": 0, + "folderUid": "", "uid": "nErXDvCkzz", "name": "Renamed library panel", "kind": 1, diff --git a/pkg/services/libraryelements/api.go b/pkg/services/libraryelements/api.go index f14c876b8e4..d78cc817fb3 100644 --- a/pkg/services/libraryelements/api.go +++ b/pkg/services/libraryelements/api.go @@ -30,11 +30,33 @@ func (l *LibraryElementService) createHandler(c *models.ReqContext) response.Res return response.Error(http.StatusBadRequest, "bad request data", err) } + if cmd.FolderUID != nil { + if *cmd.FolderUID == "" { + cmd.FolderID = 0 + } else { + folder, err := l.folderService.GetFolderByUID(c.Req.Context(), c.SignedInUser, c.OrgId, *cmd.FolderUID) + if err != nil || folder == nil { + return response.Error(http.StatusBadRequest, "failed to get folder", err) + } + cmd.FolderID = folder.Id + } + } + element, err := l.createLibraryElement(c.Req.Context(), c.SignedInUser, cmd) if err != nil { return toLibraryElementError(err, "Failed to create library element") } + if element.FolderID != 0 { + folder, err := l.folderService.GetFolderByID(c.Req.Context(), c.SignedInUser, element.FolderID, c.OrgId) + if err != nil { + return response.Error(http.StatusInternalServerError, "failed to get folder", err) + } + element.FolderUID = folder.Uid + element.Meta.FolderUID = folder.Uid + element.Meta.FolderName = folder.Title + } + return response.JSON(http.StatusOK, LibraryElementResponse{Result: element}) } @@ -88,11 +110,33 @@ func (l *LibraryElementService) patchHandler(c *models.ReqContext) response.Resp return response.Error(http.StatusBadRequest, "bad request data", err) } + if cmd.FolderUID != nil { + if *cmd.FolderUID == "" { + cmd.FolderID = 0 + } else { + folder, err := l.folderService.GetFolderByUID(c.Req.Context(), c.SignedInUser, c.OrgId, *cmd.FolderUID) + if err != nil || folder == nil { + return response.Error(http.StatusBadRequest, "failed to get folder", err) + } + cmd.FolderID = folder.Id + } + } + element, err := l.patchLibraryElement(c.Req.Context(), c.SignedInUser, cmd, web.Params(c.Req)[":uid"]) if err != nil { return toLibraryElementError(err, "Failed to update library element") } + if element.FolderID != 0 { + folder, err := l.folderService.GetFolderByID(c.Req.Context(), c.SignedInUser, element.FolderID, c.OrgId) + if err != nil { + return response.Error(http.StatusInternalServerError, "failed to get folder", err) + } + element.FolderUID = folder.Uid + element.Meta.FolderUID = folder.Uid + element.Meta.FolderName = folder.Title + } + return response.JSON(http.StatusOK, LibraryElementResponse{Result: element}) } diff --git a/pkg/services/libraryelements/database.go b/pkg/services/libraryelements/database.go index 88b95a957ee..9b4470224c6 100644 --- a/pkg/services/libraryelements/database.go +++ b/pkg/services/libraryelements/database.go @@ -245,6 +245,7 @@ func getLibraryElements(c context.Context, store *sqlstore.SQLStore, signedInUse ID: libraryElement.ID, OrgID: libraryElement.OrgID, FolderID: libraryElement.FolderID, + FolderUID: libraryElement.FolderUID, UID: libraryElement.UID, Name: libraryElement.Name, Kind: libraryElement.Kind, @@ -357,6 +358,7 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI ID: element.ID, OrgID: element.OrgID, FolderID: element.FolderID, + FolderUID: element.FolderUID, UID: element.UID, Name: element.Name, Kind: element.Kind, @@ -530,7 +532,6 @@ func (l *LibraryElementService) patchLibraryElement(c context.Context, signedInU }, }, } - return nil }) diff --git a/pkg/services/libraryelements/libraryelements_create_test.go b/pkg/services/libraryelements/libraryelements_create_test.go index fdcbd730e1d..afde9ceaf09 100644 --- a/pkg/services/libraryelements/libraryelements_create_test.go +++ b/pkg/services/libraryelements/libraryelements_create_test.go @@ -40,6 +40,8 @@ func TestCreateLibraryElement(t *testing.T) { }, Version: 1, Meta: LibraryElementDTOMeta{ + FolderName: "ScenarioFolder", + FolderUID: "ScenarioFolder", ConnectedDashboards: 0, Created: sc.initialResult.Result.Meta.Created, Updated: sc.initialResult.Result.Meta.Updated, @@ -87,6 +89,8 @@ func TestCreateLibraryElement(t *testing.T) { }, Version: 1, Meta: LibraryElementDTOMeta{ + FolderName: "ScenarioFolder", + FolderUID: "ScenarioFolder", ConnectedDashboards: 0, Created: result.Result.Meta.Created, Updated: result.Result.Meta.Updated, @@ -160,6 +164,8 @@ func TestCreateLibraryElement(t *testing.T) { }, Version: 1, Meta: LibraryElementDTOMeta{ + FolderName: "ScenarioFolder", + FolderUID: "ScenarioFolder", ConnectedDashboards: 0, Created: result.Result.Meta.Created, Updated: result.Result.Meta.Updated, diff --git a/pkg/services/libraryelements/libraryelements_patch_test.go b/pkg/services/libraryelements/libraryelements_patch_test.go index 0633a014593..6ee59606c44 100644 --- a/pkg/services/libraryelements/libraryelements_patch_test.go +++ b/pkg/services/libraryelements/libraryelements_patch_test.go @@ -63,6 +63,8 @@ func TestPatchLibraryElement(t *testing.T) { }, Version: 2, Meta: LibraryElementDTOMeta{ + FolderName: "NewFolder", + FolderUID: "NewFolder", ConnectedDashboards: 0, Created: sc.initialResult.Result.Meta.Created, Updated: result.Result.Meta.Updated, @@ -102,6 +104,8 @@ func TestPatchLibraryElement(t *testing.T) { sc.initialResult.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar sc.initialResult.Result.Meta.Updated = result.Result.Meta.Updated sc.initialResult.Result.Version = 2 + sc.initialResult.Result.Meta.FolderName = "NewFolder" + sc.initialResult.Result.Meta.FolderUID = "NewFolder" if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { t.Fatalf("Result mismatch (-want +got):\n%s", diff) } diff --git a/pkg/services/libraryelements/models.go b/pkg/services/libraryelements/models.go index 3765141c792..a684f8075fe 100644 --- a/pkg/services/libraryelements/models.go +++ b/pkg/services/libraryelements/models.go @@ -64,6 +64,7 @@ type LibraryElementDTO struct { ID int64 `json:"id"` OrgID int64 `json:"orgId"` FolderID int64 `json:"folderId"` + FolderUID string `json:"folderUid"` UID string `json:"uid"` Name string `json:"name"` Kind int64 `json:"kind"` @@ -162,6 +163,8 @@ var ( type CreateLibraryElementCommand struct { // ID of the folder where the library element is stored. FolderID int64 `json:"folderId"` + // UID of the folder where the library element is stored. + FolderUID *string `json:"folderUid"` // Name of the library element. Name string `json:"name"` // The JSON model for the library element. @@ -181,6 +184,8 @@ type CreateLibraryElementCommand struct { type PatchLibraryElementCommand struct { // ID of the folder where the library element is stored. FolderID int64 `json:"folderId" binding:"Default(-1)"` + // UID of the folder where the library element is stored. + FolderUID *string `json:"folderUid"` // Name of the library element. Name string `json:"name"` // The JSON model for the library element. diff --git a/public/api-merged.json b/public/api-merged.json index adcdd972323..876ebc32d7c 100644 --- a/public/api-merged.json +++ b/public/api-merged.json @@ -506,14 +506,6 @@ "summary": "Add a user role assignment.", "operationId": "addUserRole", "parameters": [ - { - "type": "integer", - "format": "int64", - "x-go-name": "UserID", - "name": "user_id", - "in": "path", - "required": true - }, { "x-go-name": "Body", "name": "body", @@ -522,6 +514,14 @@ "schema": { "$ref": "#/definitions/AddUserRoleCommand" } + }, + { + "type": "integer", + "format": "int64", + "x-go-name": "UserID", + "name": "user_id", + "in": "path", + "required": true } ], "responses": { @@ -547,14 +547,6 @@ "summary": "Remove a user role assignment.", "operationId": "removeUserRole", "parameters": [ - { - "type": "integer", - "format": "int64", - "x-go-name": "UserID", - "name": "user_id", - "in": "path", - "required": true - }, { "type": "string", "x-go-name": "RoleUID", @@ -568,6 +560,14 @@ "description": "A flag indicating if the assignment is global or not. If set to false, the default org ID of the authenticated user will be used from the request to remove assignment.", "name": "global", "in": "query" + }, + { + "type": "integer", + "format": "int64", + "x-go-name": "UserID", + "name": "user_id", + "in": "path", + "required": true } ], "responses": { @@ -8261,6 +8261,14 @@ "summary": "Add External Group.", "operationId": "addTeamGroupApi", "parameters": [ + { + "type": "integer", + "format": "int64", + "x-go-name": "TeamID", + "name": "teamId", + "in": "path", + "required": true + }, { "x-go-name": "Body", "name": "body", @@ -8269,14 +8277,6 @@ "schema": { "$ref": "#/definitions/TeamGroupMapping" } - }, - { - "type": "integer", - "format": "int64", - "x-go-name": "TeamID", - "name": "teamId", - "in": "path", - "required": true } ], "responses": { @@ -8310,16 +8310,16 @@ { "type": "integer", "format": "int64", - "x-go-name": "GroupID", - "name": "groupId", + "x-go-name": "TeamID", + "name": "teamId", "in": "path", "required": true }, { "type": "integer", "format": "int64", - "x-go-name": "TeamID", - "name": "teamId", + "x-go-name": "GroupID", + "name": "groupId", "in": "path", "required": true } @@ -10919,6 +10919,11 @@ "format": "int64", "x-go-name": "FolderID" }, + "folderUID": { + "description": "UID of the folder where the library element is stored.", + "type": "string", + "x-go-name": "FolderUID" + }, "kind": { "description": "Kind of element to create, Use 1 for library panels or 2 for c.\nDescription:\n1 - library panels\n2 - library variables", "type": "integer", @@ -13326,6 +13331,10 @@ "format": "int64", "x-go-name": "FolderID" }, + "folderUID": { + "type": "string", + "x-go-name": "FolderUID" + }, "id": { "type": "integer", "format": "int64", @@ -13638,7 +13647,7 @@ "properties": { "id": { "type": "string", - "x-go-name": "ID" + "x-go-name": "Id" }, "target": { "type": "string", @@ -13653,7 +13662,7 @@ "x-go-name": "Url" } }, - "x-go-package": "github.com/grafana/grafana/pkg/services/preference" + "x-go-package": "github.com/grafana/grafana/pkg/models" }, "NavbarPreference": { "type": "object", @@ -14113,6 +14122,11 @@ "format": "int64", "x-go-name": "FolderID" }, + "folderUID": { + "description": "UID of the folder where the library element is stored.", + "type": "string", + "x-go-name": "FolderUID" + }, "kind": { "description": "Kind of element to create, Use 1 for library panels or 2 for c.\nDescription:\n1 - library panels\n2 - library variables", "type": "integer", diff --git a/public/api-spec.json b/public/api-spec.json index c9f744551dd..32d01405a32 100644 --- a/public/api-spec.json +++ b/public/api-spec.json @@ -506,14 +506,6 @@ "summary": "Add a user role assignment.", "operationId": "addUserRole", "parameters": [ - { - "type": "integer", - "format": "int64", - "x-go-name": "UserID", - "name": "user_id", - "in": "path", - "required": true - }, { "x-go-name": "Body", "name": "body", @@ -522,6 +514,14 @@ "schema": { "$ref": "#/definitions/AddUserRoleCommand" } + }, + { + "type": "integer", + "format": "int64", + "x-go-name": "UserID", + "name": "user_id", + "in": "path", + "required": true } ], "responses": { @@ -547,14 +547,6 @@ "summary": "Remove a user role assignment.", "operationId": "removeUserRole", "parameters": [ - { - "type": "integer", - "format": "int64", - "x-go-name": "UserID", - "name": "user_id", - "in": "path", - "required": true - }, { "type": "string", "x-go-name": "RoleUID", @@ -568,6 +560,14 @@ "description": "A flag indicating if the assignment is global or not. If set to false, the default org ID of the authenticated user will be used from the request to remove assignment.", "name": "global", "in": "query" + }, + { + "type": "integer", + "format": "int64", + "x-go-name": "UserID", + "name": "user_id", + "in": "path", + "required": true } ], "responses": { @@ -6670,6 +6670,14 @@ "summary": "Add External Group.", "operationId": "addTeamGroupApi", "parameters": [ + { + "type": "integer", + "format": "int64", + "x-go-name": "TeamID", + "name": "teamId", + "in": "path", + "required": true + }, { "x-go-name": "Body", "name": "body", @@ -6678,14 +6686,6 @@ "schema": { "$ref": "#/definitions/TeamGroupMapping" } - }, - { - "type": "integer", - "format": "int64", - "x-go-name": "TeamID", - "name": "teamId", - "in": "path", - "required": true } ], "responses": { @@ -6719,16 +6719,16 @@ { "type": "integer", "format": "int64", - "x-go-name": "GroupID", - "name": "groupId", + "x-go-name": "TeamID", + "name": "teamId", "in": "path", "required": true }, { "type": "integer", "format": "int64", - "x-go-name": "TeamID", - "name": "teamId", + "x-go-name": "GroupID", + "name": "groupId", "in": "path", "required": true } @@ -8906,6 +8906,11 @@ "format": "int64", "x-go-name": "FolderID" }, + "folderUID": { + "description": "UID of the folder where the library element is stored.", + "type": "string", + "x-go-name": "FolderUID" + }, "kind": { "description": "Kind of element to create, Use 1 for library panels or 2 for c.\nDescription:\n1 - library panels\n2 - library variables", "type": "integer", @@ -10493,6 +10498,10 @@ "format": "int64", "x-go-name": "FolderID" }, + "folderUID": { + "type": "string", + "x-go-name": "FolderUID" + }, "id": { "type": "integer", "format": "int64", @@ -10721,7 +10730,7 @@ "properties": { "id": { "type": "string", - "x-go-name": "ID" + "x-go-name": "Id" }, "target": { "type": "string", @@ -10736,7 +10745,7 @@ "x-go-name": "Url" } }, - "x-go-package": "github.com/grafana/grafana/pkg/services/preference" + "x-go-package": "github.com/grafana/grafana/pkg/models" }, "NavbarPreference": { "type": "object", @@ -10938,6 +10947,11 @@ "format": "int64", "x-go-name": "FolderID" }, + "folderUID": { + "description": "UID of the folder where the library element is stored.", + "type": "string", + "x-go-name": "FolderUID" + }, "kind": { "description": "Kind of element to create, Use 1 for library panels or 2 for c.\nDescription:\n1 - library panels\n2 - library variables", "type": "integer",