From 16034ef0624b16e1249aea6a0a8a488100d48c35 Mon Sep 17 00:00:00 2001 From: Ezequiel Victorero Date: Mon, 30 Oct 2023 10:32:07 -0300 Subject: [PATCH] PublicDashboards: Add swagger documentation (#75318) --- pkg/api/swagger_responses.go | 53 ++ pkg/services/publicdashboards/api/api.go | 132 +++- pkg/services/publicdashboards/api/query.go | 84 ++- public/api-enterprise-spec.json | 378 ++++++++++ public/api-merged.json | 688 +++++++++++++++++++ public/openapi3.json | 760 +++++++++++++++++++++ 6 files changed, 2076 insertions(+), 19 deletions(-) diff --git a/pkg/api/swagger_responses.go b/pkg/api/swagger_responses.go index 49e310051d8..715aa1e6c38 100644 --- a/pkg/api/swagger_responses.go +++ b/pkg/api/swagger_responses.go @@ -81,3 +81,56 @@ type UnauthorizedError GenericError // // swagger:response acceptedResponse type AcceptedResponse GenericError + +// documentation for PublicError defined in errutil.Error + +// swagger:response publicErrorResponse +type PublicErrorResponse struct { + // The response message + // in: body + Body PublicError `json:"body"` +} + +// PublicError is derived from Error and only contains information +// available to the end user. +// swagger:model publicError +type PublicError struct { + // StatusCode The HTTP status code returned + // required: true + StatusCode int `json:"statusCode"` + + // MessageID A unique identifier for the error + // required: true + MessageID string `json:"messageId"` + + // Message A human readable message + Message string `json:"message"` + + // Extra Additional information about the error + Extra map[string]any `json:"extra"` +} + +// NotFoundPublicError is returned when the requested resource was not found. +// +// swagger:response notFoundPublicError +type NotFoundPublicError PublicErrorResponse + +// BadRequestPublicError is returned when the request is invalid and it cannot be processed. +// +// swagger:response badRequestPublicError +type BadRequestPublicError PublicErrorResponse + +// UnauthorisedPublicError is returned when the request is not authenticated. +// +// swagger:response unauthorisedPublicError +type UnauthorisedPublicError PublicErrorResponse + +// ForbiddenPublicError is returned if the user/token has insufficient permissions to access the requested resource. +// +// swagger:response forbiddenPublicError +type ForbiddenPublicError PublicErrorResponse + +// InternalServerPublicError is a general error indicating something went wrong internally. +// +// swagger:response internalServerPublicError +type InternalServerPublicError PublicErrorResponse diff --git a/pkg/services/publicdashboards/api/api.go b/pkg/services/publicdashboards/api/api.go index 8ab2b0172e7..f714f348ce2 100644 --- a/pkg/services/publicdashboards/api/api.go +++ b/pkg/services/publicdashboards/api/api.go @@ -56,8 +56,9 @@ func (api *Api) RegisterAPIEndpoints() { // circular dependency api.RouteRegister.Get("/api/public/dashboards/:accessToken", routing.Wrap(api.ViewPublicDashboard)) + api.RouteRegister.Get("/api/public/dashboards/:accessToken/annotations", routing.Wrap(api.GetPublicAnnotations)) + api.RouteRegister.Post("/api/public/dashboards/:accessToken/panels/:panelId/query", routing.Wrap(api.QueryPublicDashboard)) - api.RouteRegister.Get("/api/public/dashboards/:accessToken/annotations", routing.Wrap(api.GetAnnotations)) // Auth endpoints auth := accesscontrol.Middleware(api.AccessControl) @@ -87,8 +88,15 @@ func (api *Api) RegisterAPIEndpoints() { routing.Wrap(api.DeletePublicDashboard)) } -// ListPublicDashboards Gets list of public dashboards by orgId -// GET /api/dashboards/public-dashboards +// swagger:route GET /dashboards/public-dashboards dashboard_public listPublicDashboards +// +// Get list of public dashboards +// +// Responses: +// 200: listPublicDashboardsResponse +// 401: unauthorisedPublicError +// 403: forbiddenPublicError +// 500: internalServerPublicError func (api *Api) ListPublicDashboards(c *contextmodel.ReqContext) response.Response { perPage := c.QueryInt("perpage") if perPage <= 0 { @@ -114,8 +122,17 @@ func (api *Api) ListPublicDashboards(c *contextmodel.ReqContext) response.Respon return response.JSON(http.StatusOK, resp) } -// GetPublicDashboard Gets public dashboard for dashboard -// GET /api/dashboards/uid/:dashboardUid/public-dashboards +// swagger:route GET /dashboards/uid/{dashboardUid}/public-dashboards dashboard_public getPublicDashboard +// +// Get public dashboard by dashboardUid +// +// Responses: +// 200: getPublicDashboardResponse +// 400: badRequestPublicError +// 401: unauthorisedPublicError +// 403: forbiddenPublicError +// 404: notFoundPublicError +// 500: internalServerPublicError func (api *Api) GetPublicDashboard(c *contextmodel.ReqContext) response.Response { // exit if we don't have a valid dashboardUid dashboardUid := web.Params(c.Req)[":dashboardUid"] @@ -135,8 +152,19 @@ func (api *Api) GetPublicDashboard(c *contextmodel.ReqContext) response.Response return response.JSON(http.StatusOK, pd) } -// CreatePublicDashboard Sets public dashboard for dashboard -// POST /api/dashboards/uid/:dashboardUid/public-dashboards +// swagger:route POST /dashboards/uid/{dashboardUid}/public-dashboards dashboard_public createPublicDashboard +// +// Create public dashboard for a dashboard +// +// Produces: +// - application/json +// +// Responses: +// 200: createPublicDashboardResponse +// 400: badRequestPublicError +// 401: unauthorisedPublicError +// 403: forbiddenPublicError +// 500: internalServerPublicError func (api *Api) CreatePublicDashboard(c *contextmodel.ReqContext) response.Response { // exit if we don't have a valid dashboardUid dashboardUid := web.Params(c.Req)[":dashboardUid"] @@ -178,8 +206,19 @@ func (api *Api) CreatePublicDashboard(c *contextmodel.ReqContext) response.Respo return response.JSON(http.StatusOK, pd) } -// UpdatePublicDashboard Sets public dashboard for dashboard -// PATCH /api/dashboards/uid/:dashboardUid/public-dashboards/:uid +// swagger:route PATCH /dashboards/uid/{dashboardUid}/public-dashboards/{uid} dashboard_public updatePublicDashboard +// +// Update public dashboard for a dashboard +// +// Produces: +// - application/json +// +// Responses: +// 200: updatePublicDashboardResponse +// 400: badRequestPublicError +// 401: unauthorisedPublicError +// 403: forbiddenPublicError +// 500: internalServerPublicError func (api *Api) UpdatePublicDashboard(c *contextmodel.ReqContext) response.Response { // exit if we don't have a valid dashboardUid dashboardUid := web.Params(c.Req)[":dashboardUid"] @@ -215,8 +254,16 @@ func (api *Api) UpdatePublicDashboard(c *contextmodel.ReqContext) response.Respo return response.JSON(http.StatusOK, pd) } -// Delete a public dashboard -// DELETE /api/dashboards/uid/:dashboardUid/public-dashboards/:uid +// swagger:route DELETE /dashboards/uid/{dashboardUid}/public-dashboards/{uid} dashboard_public deletePublicDashboard +// +// Delete public dashboard for a dashboard +// +// Responses: +// 200: okResponse +// 400: badRequestPublicError +// 401: unauthorisedPublicError +// 403: forbiddenPublicError +// 500: internalServerPublicError func (api *Api) DeletePublicDashboard(c *contextmodel.ReqContext) response.Response { uid := web.Params(c.Req)[":uid"] if !validation.IsValidShortUID(uid) { @@ -252,3 +299,66 @@ func toJsonStreamingResponse(features *featuremgmt.FeatureManager, qdr *backend. return response.JSONStreaming(statusCode, qdr) } + +// swagger:response listPublicDashboardsResponse +type ListPublicDashboardsResponse struct { + // in: body + Body PublicDashboardListResponseWithPagination `json:"body"` +} + +// swagger:parameters getPublicDashboard +type GetPublicDashboardParams struct { + // in:path + DashboardUid string `json:"dashboardUid"` +} + +// swagger:response getPublicDashboardResponse +type GetPublicDashboardResponse struct { + // in: body + Body PublicDashboard `json:"body"` +} + +// swagger:parameters createPublicDashboard +type CreatePublicDashboardParams struct { + // in:path + // required:true + DashboardUid string `json:"dashboardUid"` + // in:body + // required:true + Body PublicDashboardDTO +} + +// swagger:response createPublicDashboardResponse +type CreatePublicDashboardResponse struct { + // in: body + Body PublicDashboard `json:"body"` +} + +// swagger:parameters updatePublicDashboard +type UpdatePublicDashboardParams struct { + // in:path + // required:true + DashboardUid string `json:"dashboardUid"` + // in:path + // required:true + Uid string `json:"uid"` + // in:body + // required:true + Body PublicDashboardDTO +} + +// swagger:response updatePublicDashboardResponse +type UpdatePublicDashboardResponse struct { + // in: body + Body PublicDashboard `json:"body"` +} + +// swagger:parameters deletePublicDashboard +type DeletePublicDashboardParams struct { + // in:path + // required:true + DashboardUid string `json:"dashboardUid"` + // in:path + // required:true + Uid string `json:"uid"` +} diff --git a/pkg/services/publicdashboards/api/query.go b/pkg/services/publicdashboards/api/query.go index 0e3b29eb671..206df58ba2d 100644 --- a/pkg/services/publicdashboards/api/query.go +++ b/pkg/services/publicdashboards/api/query.go @@ -4,6 +4,8 @@ import ( "net/http" "strconv" + "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/api/response" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" . "github.com/grafana/grafana/pkg/services/publicdashboards/models" @@ -11,8 +13,17 @@ import ( "github.com/grafana/grafana/pkg/web" ) -// ViewPublicDashboard Gets public dashboard -// GET /api/public/dashboards/:accessToken +// swagger:route GET /public/dashboards/{accessToken} dashboard_public viewPublicDashboard +// +// Get public dashboard for view +// +// Responses: +// 200: viewPublicDashboardResponse +// 400: badRequestPublicError +// 401: unauthorisedPublicError +// 403: forbiddenPublicError +// 404: notFoundPublicError +// 500: internalServerPublicError func (api *Api) ViewPublicDashboard(c *contextmodel.ReqContext) response.Response { accessToken := web.Params(c.Req)[":accessToken"] if !validation.IsValidAccessToken(accessToken) { @@ -27,8 +38,18 @@ func (api *Api) ViewPublicDashboard(c *contextmodel.ReqContext) response.Respons return response.JSON(http.StatusOK, dto) } -// QueryPublicDashboard returns all results for a given panel on a public dashboard -// POST /api/public/dashboard/:accessToken/panels/:panelId/query +// swagger:route POST /public/dashboards/{accessToken}/panels/{panelId}/query dashboard_public queryPublicDashboard +// +// Get results for a given panel on a public dashboard +// +// Responses: +// 200: queryPublicDashboardResponse +// 400: badRequestPublicError +// 401: unauthorisedPublicError +// 404: panelNotFoundPublicError +// 404: notFoundPublicError +// 403: forbiddenPublicError +// 500: internalServerPublicError func (api *Api) QueryPublicDashboard(c *contextmodel.ReqContext) response.Response { accessToken := web.Params(c.Req)[":accessToken"] if !validation.IsValidAccessToken(accessToken) { @@ -53,12 +74,21 @@ func (api *Api) QueryPublicDashboard(c *contextmodel.ReqContext) response.Respon return toJsonStreamingResponse(api.Features, resp) } -// GetAnnotations returns annotations for a public dashboard -// GET /api/public/dashboards/:accessToken/annotations -func (api *Api) GetAnnotations(c *contextmodel.ReqContext) response.Response { +// swagger:route GET /public/dashboards/{accessToken}/annotations dashboard_public getPublicAnnotations +// +// Get annotations for a public dashboard +// +// Responses: +// 200: getPublicAnnotationsResponse +// 400: badRequestPublicError +// 404: notFoundPublicError +// 401: unauthorisedPublicError +// 403: forbiddenPublicError +// 500: internalServerPublicError +func (api *Api) GetPublicAnnotations(c *contextmodel.ReqContext) response.Response { accessToken := web.Params(c.Req)[":accessToken"] if !validation.IsValidAccessToken(accessToken) { - return response.Err(ErrInvalidAccessToken.Errorf("GetAnnotations: invalid access token")) + return response.Err(ErrInvalidAccessToken.Errorf("GetPublicAnnotations: invalid access token")) } reqDTO := AnnotationsQueryDTO{ @@ -73,3 +103,41 @@ func (api *Api) GetAnnotations(c *contextmodel.ReqContext) response.Response { return response.JSON(http.StatusOK, annotations) } + +// swagger:response viewPublicDashboardResponse +type ViewPublicDashboardResponse struct { + // in: body + Body dtos.DashboardFullWithMeta `json:"body"` +} + +// swagger:parameters viewPublicDashboard +type ViewPublicDashboardParams struct { + // in: path + AccessToken string `json:"accessToken"` +} + +// swagger:response queryPublicDashboardResponse +type QueryPublicDashboardResponse struct { + // in: body + Body backend.QueryDataResponse `json:"body"` +} + +// swagger:parameters queryPublicDashboard +type QueryPublicDashboardParams struct { + // in: path + AccessToken string `json:"accessToken"` + // in: path + PanelId int64 `json:"panelId"` +} + +// swagger:response getPublicAnnotationsResponse +type GetPublicAnnotationsResponse struct { + // in: body + Body []AnnotationEvent `json:"body"` +} + +// swagger:parameters getPublicAnnotations +type GetPublicAnnotationsParams struct { + // in: path + AccessToken string `json:"accessToken"` +} diff --git a/public/api-enterprise-spec.json b/public/api-enterprise-spec.json index f9e390481df..36113b6e632 100644 --- a/public/api-enterprise-spec.json +++ b/public/api-enterprise-spec.json @@ -2635,6 +2635,67 @@ } } }, + "AnnotationEvent": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "dashboardId": { + "type": "integer", + "format": "int64" + }, + "id": { + "type": "integer", + "format": "int64" + }, + "isRegion": { + "type": "boolean" + }, + "panelId": { + "type": "integer", + "format": "int64" + }, + "source": { + "$ref": "#/definitions/AnnotationQuery" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "text": { + "type": "string" + }, + "time": { + "type": "integer", + "format": "int64" + }, + "timeEnd": { + "type": "integer", + "format": "int64" + } + } + }, + "AnnotationPanelFilter": { + "type": "object", + "title": "AnnotationPanelFilter defines model for AnnotationPanelFilter.", + "properties": { + "exclude": { + "description": "Should the specified panels be included or excluded", + "type": "boolean" + }, + "ids": { + "description": "Panel IDs that should be included or excluded", + "type": "array", + "items": { + "type": "integer", + "format": "int64" + } + } + } + }, "AnnotationPermission": { "type": "object", "properties": { @@ -2646,6 +2707,72 @@ } } }, + "AnnotationQuery": { + "description": "TODO docs\nFROM: AnnotationQuery in grafana-data/src/types/annotations.ts", + "type": "object", + "properties": { + "builtIn": { + "description": "Set to 1 for the standard annotation query all dashboards have by default.", + "type": "number", + "format": "float" + }, + "datasource": { + "$ref": "#/definitions/DataSourceRef" + }, + "enable": { + "description": "When enabled the annotation query is issued with every dashboard refresh", + "type": "boolean" + }, + "filter": { + "$ref": "#/definitions/AnnotationPanelFilter" + }, + "hide": { + "description": "Annotation queries can be toggled on or off at the top of the dashboard.\nWhen hide is true, the toggle is not shown in the dashboard.", + "type": "boolean" + }, + "iconColor": { + "description": "Color to use for the annotation event markers", + "type": "string" + }, + "name": { + "description": "Name of annotation.", + "type": "string" + }, + "target": { + "$ref": "#/definitions/AnnotationTarget" + }, + "type": { + "description": "TODO -- this should not exist here, it is based on the --grafana-- datasource", + "type": "string" + } + } + }, + "AnnotationTarget": { + "description": "TODO: this should be a regular DataQuery that depends on the selected dashboard\nthese match the properties of the \"grafana\" datasouce that is default in most dashboards", + "type": "object", + "properties": { + "limit": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "type": "integer", + "format": "int64" + }, + "matchAny": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "type": "boolean" + }, + "tags": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "type": "array", + "items": { + "type": "string" + } + }, + "type": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "type": "string" + } + } + }, "ApiKeyDTO": { "type": "object", "properties": { @@ -4164,6 +4291,20 @@ } } }, + "DataSourceRef": { + "description": "Ref to a DataSource instance", + "type": "object", + "properties": { + "type": { + "description": "The plugin type-id", + "type": "string" + }, + "uid": { + "description": "Specific datasource instance", + "type": "string" + } + } + }, "DataTopic": { "description": "nolint:revive", "type": "string", @@ -4206,6 +4347,17 @@ "type": "integer", "format": "int64" }, + "EmailDTO": { + "type": "object", + "properties": { + "recipient": { + "type": "string" + }, + "uid": { + "type": "string" + } + } + }, "EnumFieldConfig": { "description": "Enum field config\nVector values are used as lookup keys into the enum fields", "type": "object", @@ -5928,6 +6080,120 @@ } } }, + "PublicDashboard": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "annotationsEnabled": { + "type": "boolean" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "integer", + "format": "int64" + }, + "dashboardUid": { + "type": "string" + }, + "isEnabled": { + "type": "boolean" + }, + "recipients": { + "type": "array", + "items": { + "$ref": "#/definitions/EmailDTO" + } + }, + "share": { + "$ref": "#/definitions/ShareType" + }, + "timeSelectionEnabled": { + "type": "boolean" + }, + "uid": { + "type": "string" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "updatedBy": { + "type": "integer", + "format": "int64" + } + } + }, + "PublicDashboardDTO": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "annotationsEnabled": { + "type": "boolean" + }, + "isEnabled": { + "type": "boolean" + }, + "share": { + "$ref": "#/definitions/ShareType" + }, + "timeSelectionEnabled": { + "type": "boolean" + }, + "uid": { + "type": "string" + } + } + }, + "PublicDashboardListResponse": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "dashboardUid": { + "type": "string" + }, + "isEnabled": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "uid": { + "type": "string" + } + } + }, + "PublicDashboardListResponseWithPagination": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "format": "int64" + }, + "perPage": { + "type": "integer", + "format": "int64" + }, + "publicDashboards": { + "type": "array", + "items": { + "$ref": "#/definitions/PublicDashboardListResponse" + } + }, + "totalCount": { + "type": "integer", + "format": "int64" + } + } + }, "PublicKeyAlgorithm": { "type": "integer", "format": "int64" @@ -6725,6 +6991,9 @@ } } }, + "ShareType": { + "type": "string" + }, "SignatureAlgorithm": { "type": "integer", "format": "int64" @@ -7922,6 +8191,34 @@ "VisType": { "type": "string", "title": "VisType is used to indicate how the data should be visualized in explore." + }, + "publicError": { + "description": "PublicError is derived from Error and only contains information\navailable to the end user.", + "type": "object", + "required": [ + "statusCode", + "messageId" + ], + "properties": { + "extra": { + "description": "Extra Additional information about the error", + "type": "object", + "additionalProperties": {} + }, + "message": { + "description": "Message A human readable message", + "type": "string" + }, + "messageId": { + "description": "MessageID A unique identifier for the error", + "type": "string" + }, + "statusCode": { + "description": "StatusCode The HTTP status code returned", + "type": "integer", + "format": "int64" + } + } } }, "responses": { @@ -7982,6 +8279,12 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "badRequestPublicError": { + "description": "BadRequestPublicError is returned when the request is invalid and it cannot be processed.", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "calculateDashboardDiffResponse": { "description": "", "schema": { @@ -8103,6 +8406,12 @@ "$ref": "#/definitions/Playlist" } }, + "createPublicDashboardResponse": { + "description": "", + "schema": { + "$ref": "#/definitions/PublicDashboard" + } + }, "createReportResponse": { "description": "", "schema": { @@ -8293,6 +8602,12 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "forbiddenPublicError": { + "description": "ForbiddenPublicError is returned if the user/token has insufficient permissions to access the requested resource.", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "genericError": { "description": "A GenericError is the default error message that is generated.\nFor certain status codes there are more appropriate error structures.", "schema": { @@ -8616,6 +8931,21 @@ "$ref": "#/definitions/Spec" } }, + "getPublicAnnotationsResponse": { + "description": "", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/AnnotationEvent" + } + } + }, + "getPublicDashboardResponse": { + "description": "", + "schema": { + "$ref": "#/definitions/PublicDashboard" + } + }, "getQueryHistoryDeleteQueryResponse": { "description": "", "schema": { @@ -8798,6 +9128,12 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "internalServerPublicError": { + "description": "InternalServerPublicError is a general error indicating something went wrong internally.", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "jwksResponse": { "description": "", "schema": { @@ -8824,6 +9160,12 @@ } } }, + "listPublicDashboardsResponse": { + "description": "", + "schema": { + "$ref": "#/definitions/PublicDashboardListResponseWithPagination" + } + }, "listRecordingRulesResponse": { "description": "", "schema": { @@ -8874,6 +9216,12 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "notFoundPublicError": { + "description": "NotFoundPublicError is returned when the requested resource was not found.", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "okResponse": { "description": "An OKResponse is returned if the request was successful.", "schema": { @@ -9012,12 +9360,24 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "publicErrorResponse": { + "description": "", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "queryMetricsWithExpressionsRespons": { "description": "", "schema": { "$ref": "#/definitions/QueryDataResponse" } }, + "queryPublicDashboardResponse": { + "description": "", + "schema": { + "$ref": "#/definitions/QueryDataResponse" + } + }, "recordingRuleResponse": { "description": "", "schema": { @@ -9135,6 +9495,12 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "unauthorisedPublicError": { + "description": "UnauthorisedPublicError is returned when the request is not authenticated.", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "unprocessableEntityError": { "description": "UnprocessableEntityError", "schema": { @@ -9153,6 +9519,12 @@ "$ref": "#/definitions/PlaylistDTO" } }, + "updatePublicDashboardResponse": { + "description": "", + "schema": { + "$ref": "#/definitions/PublicDashboard" + } + }, "updateServiceAccountResponse": { "description": "", "schema": { @@ -9190,6 +9562,12 @@ "type": "string" } } + }, + "viewPublicDashboardResponse": { + "description": "", + "schema": { + "$ref": "#/definitions/DashboardFullWithMeta" + } } }, "securityDefinitions": { diff --git a/public/api-merged.json b/public/api-merged.json index 8194ddb54cc..25324ec089f 100644 --- a/public/api-merged.json +++ b/public/api-merged.json @@ -3883,6 +3883,29 @@ } } }, + "/dashboards/public-dashboards": { + "get": { + "description": "Get list of public dashboards", + "tags": [ + "dashboard_public" + ], + "operationId": "listPublicDashboards", + "responses": { + "200": { + "$ref": "#/responses/listPublicDashboardsResponse" + }, + "401": { + "$ref": "#/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/responses/forbiddenPublicError" + }, + "500": { + "$ref": "#/responses/internalServerPublicError" + } + } + } + }, "/dashboards/tags": { "get": { "tags": [ @@ -3933,6 +3956,175 @@ } } }, + "/dashboards/uid/{dashboardUid}/public-dashboards": { + "get": { + "description": "Get public dashboard by dashboardUid", + "tags": [ + "dashboard_public" + ], + "operationId": "getPublicDashboard", + "parameters": [ + { + "type": "string", + "name": "dashboardUid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/getPublicDashboardResponse" + }, + "400": { + "$ref": "#/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/responses/forbiddenPublicError" + }, + "404": { + "$ref": "#/responses/notFoundPublicError" + }, + "500": { + "$ref": "#/responses/internalServerPublicError" + } + } + }, + "post": { + "description": "Create public dashboard for a dashboard", + "produces": [ + "application/json" + ], + "tags": [ + "dashboard_public" + ], + "operationId": "createPublicDashboard", + "parameters": [ + { + "type": "string", + "name": "dashboardUid", + "in": "path", + "required": true + }, + { + "name": "Body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PublicDashboardDTO" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/createPublicDashboardResponse" + }, + "400": { + "$ref": "#/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/responses/forbiddenPublicError" + }, + "500": { + "$ref": "#/responses/internalServerPublicError" + } + } + } + }, + "/dashboards/uid/{dashboardUid}/public-dashboards/{uid}": { + "delete": { + "description": "Delete public dashboard for a dashboard", + "tags": [ + "dashboard_public" + ], + "operationId": "deletePublicDashboard", + "parameters": [ + { + "type": "string", + "name": "dashboardUid", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "uid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/okResponse" + }, + "400": { + "$ref": "#/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/responses/forbiddenPublicError" + }, + "500": { + "$ref": "#/responses/internalServerPublicError" + } + } + }, + "patch": { + "description": "Update public dashboard for a dashboard", + "produces": [ + "application/json" + ], + "tags": [ + "dashboard_public" + ], + "operationId": "updatePublicDashboard", + "parameters": [ + { + "type": "string", + "name": "dashboardUid", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "uid", + "in": "path", + "required": true + }, + { + "name": "Body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PublicDashboardDTO" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/updatePublicDashboardResponse" + }, + "400": { + "$ref": "#/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/responses/forbiddenPublicError" + }, + "500": { + "$ref": "#/responses/internalServerPublicError" + } + } + } + }, "/dashboards/uid/{uid}": { "get": { "description": "Will return the dashboard given the dashboard unique identifier (uid).", @@ -7718,6 +7910,124 @@ } } }, + "/public/dashboards/{accessToken}": { + "get": { + "description": "Get public dashboard for view", + "tags": [ + "dashboard_public" + ], + "operationId": "viewPublicDashboard", + "parameters": [ + { + "type": "string", + "name": "accessToken", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/viewPublicDashboardResponse" + }, + "400": { + "$ref": "#/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/responses/forbiddenPublicError" + }, + "404": { + "$ref": "#/responses/notFoundPublicError" + }, + "500": { + "$ref": "#/responses/internalServerPublicError" + } + } + } + }, + "/public/dashboards/{accessToken}/annotations": { + "get": { + "description": "Get annotations for a public dashboard", + "tags": [ + "dashboard_public" + ], + "operationId": "getPublicAnnotations", + "parameters": [ + { + "type": "string", + "name": "accessToken", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/getPublicAnnotationsResponse" + }, + "400": { + "$ref": "#/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/responses/forbiddenPublicError" + }, + "404": { + "$ref": "#/responses/notFoundPublicError" + }, + "500": { + "$ref": "#/responses/internalServerPublicError" + } + } + } + }, + "/public/dashboards/{accessToken}/panels/{panelId}/query": { + "post": { + "description": "Get results for a given panel on a public dashboard", + "tags": [ + "dashboard_public" + ], + "operationId": "queryPublicDashboard", + "parameters": [ + { + "type": "string", + "name": "accessToken", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "name": "panelId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/queryPublicDashboardResponse" + }, + "400": { + "$ref": "#/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/responses/forbiddenPublicError" + }, + "404": { + "$ref": "#/responses/notFoundPublicError" + }, + "500": { + "$ref": "#/responses/internalServerPublicError" + } + } + } + }, "/query-history": { "get": { "description": "Returns a list of queries in the query history that matches the search criteria.\nQuery history search supports pagination. Use the `limit` parameter to control the maximum number of queries returned; the default limit is 100.\nYou can also use the `page` query parameter to fetch queries from any page other than the first one.", @@ -11761,6 +12071,67 @@ } } }, + "AnnotationEvent": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "dashboardId": { + "type": "integer", + "format": "int64" + }, + "id": { + "type": "integer", + "format": "int64" + }, + "isRegion": { + "type": "boolean" + }, + "panelId": { + "type": "integer", + "format": "int64" + }, + "source": { + "$ref": "#/definitions/AnnotationQuery" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "text": { + "type": "string" + }, + "time": { + "type": "integer", + "format": "int64" + }, + "timeEnd": { + "type": "integer", + "format": "int64" + } + } + }, + "AnnotationPanelFilter": { + "type": "object", + "title": "AnnotationPanelFilter defines model for AnnotationPanelFilter.", + "properties": { + "exclude": { + "description": "Should the specified panels be included or excluded", + "type": "boolean" + }, + "ids": { + "description": "Panel IDs that should be included or excluded", + "type": "array", + "items": { + "type": "integer", + "format": "int64" + } + } + } + }, "AnnotationPermission": { "type": "object", "properties": { @@ -11772,6 +12143,72 @@ } } }, + "AnnotationQuery": { + "description": "TODO docs\nFROM: AnnotationQuery in grafana-data/src/types/annotations.ts", + "type": "object", + "properties": { + "builtIn": { + "description": "Set to 1 for the standard annotation query all dashboards have by default.", + "type": "number", + "format": "float" + }, + "datasource": { + "$ref": "#/definitions/DataSourceRef" + }, + "enable": { + "description": "When enabled the annotation query is issued with every dashboard refresh", + "type": "boolean" + }, + "filter": { + "$ref": "#/definitions/AnnotationPanelFilter" + }, + "hide": { + "description": "Annotation queries can be toggled on or off at the top of the dashboard.\nWhen hide is true, the toggle is not shown in the dashboard.", + "type": "boolean" + }, + "iconColor": { + "description": "Color to use for the annotation event markers", + "type": "string" + }, + "name": { + "description": "Name of annotation.", + "type": "string" + }, + "target": { + "$ref": "#/definitions/AnnotationTarget" + }, + "type": { + "description": "TODO -- this should not exist here, it is based on the --grafana-- datasource", + "type": "string" + } + } + }, + "AnnotationTarget": { + "description": "TODO: this should be a regular DataQuery that depends on the selected dashboard\nthese match the properties of the \"grafana\" datasouce that is default in most dashboards", + "type": "object", + "properties": { + "limit": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "type": "integer", + "format": "int64" + }, + "matchAny": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "type": "boolean" + }, + "tags": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "type": "array", + "items": { + "type": "string" + } + }, + "type": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "type": "string" + } + } + }, "ApiKeyDTO": { "type": "object", "properties": { @@ -13467,6 +13904,20 @@ } } }, + "DataSourceRef": { + "description": "Ref to a DataSource instance", + "type": "object", + "properties": { + "type": { + "description": "The plugin type-id", + "type": "string" + }, + "uid": { + "description": "Specific datasource instance", + "type": "string" + } + } + }, "DataTopic": { "description": "nolint:revive", "type": "string", @@ -13602,6 +14053,17 @@ } } }, + "EmailDTO": { + "type": "object", + "properties": { + "recipient": { + "type": "string" + }, + "uid": { + "type": "string" + } + } + }, "EmbeddedContactPoint": { "description": "EmbeddedContactPoint is the contact point type that is used\nby grafanas embedded alertmanager implementation.", "type": "object", @@ -17002,6 +17464,120 @@ } } }, + "PublicDashboard": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "annotationsEnabled": { + "type": "boolean" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "integer", + "format": "int64" + }, + "dashboardUid": { + "type": "string" + }, + "isEnabled": { + "type": "boolean" + }, + "recipients": { + "type": "array", + "items": { + "$ref": "#/definitions/EmailDTO" + } + }, + "share": { + "$ref": "#/definitions/ShareType" + }, + "timeSelectionEnabled": { + "type": "boolean" + }, + "uid": { + "type": "string" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "updatedBy": { + "type": "integer", + "format": "int64" + } + } + }, + "PublicDashboardDTO": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "annotationsEnabled": { + "type": "boolean" + }, + "isEnabled": { + "type": "boolean" + }, + "share": { + "$ref": "#/definitions/ShareType" + }, + "timeSelectionEnabled": { + "type": "boolean" + }, + "uid": { + "type": "string" + } + } + }, + "PublicDashboardListResponse": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "dashboardUid": { + "type": "string" + }, + "isEnabled": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "uid": { + "type": "string" + } + } + }, + "PublicDashboardListResponseWithPagination": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "format": "int64" + }, + "perPage": { + "type": "integer", + "format": "int64" + }, + "publicDashboards": { + "type": "array", + "items": { + "$ref": "#/definitions/PublicDashboardListResponse" + } + }, + "totalCount": { + "type": "integer", + "format": "int64" + } + } + }, "PublicKeyAlgorithm": { "type": "integer", "format": "int64" @@ -18330,6 +18906,9 @@ } } }, + "ShareType": { + "type": "string" + }, "SigV4Config": { "description": "SigV4Config is the configuration for signing remote write requests with\nAWS's SigV4 verification process. Empty values will be retrieved using the\nAWS default credentials chain.", "type": "object", @@ -20615,6 +21194,34 @@ } } }, + "publicError": { + "description": "PublicError is derived from Error and only contains information\navailable to the end user.", + "type": "object", + "required": [ + "statusCode", + "messageId" + ], + "properties": { + "extra": { + "description": "Extra Additional information about the error", + "type": "object", + "additionalProperties": false + }, + "message": { + "description": "Message A human readable message", + "type": "string" + }, + "messageId": { + "description": "MessageID A unique identifier for the error", + "type": "string" + }, + "statusCode": { + "description": "StatusCode The HTTP status code returned", + "type": "integer", + "format": "int64" + } + } + }, "receiver": { "description": "Receiver receiver", "type": "object", @@ -20812,6 +21419,12 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "badRequestPublicError": { + "description": "BadRequestPublicError is returned when the request is invalid and it cannot be processed.", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "calculateDashboardDiffResponse": { "description": "(empty)", "schema": { @@ -20933,6 +21546,12 @@ "$ref": "#/definitions/Playlist" } }, + "createPublicDashboardResponse": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/PublicDashboard" + } + }, "createReportResponse": { "description": "(empty)", "schema": { @@ -21123,6 +21742,12 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "forbiddenPublicError": { + "description": "ForbiddenPublicError is returned if the user/token has insufficient permissions to access the requested resource.", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "genericError": { "description": "A GenericError is the default error message that is generated.\nFor certain status codes there are more appropriate error structures.", "schema": { @@ -21446,6 +22071,21 @@ "$ref": "#/definitions/Spec" } }, + "getPublicAnnotationsResponse": { + "description": "(empty)", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/AnnotationEvent" + } + } + }, + "getPublicDashboardResponse": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/PublicDashboard" + } + }, "getQueryHistoryDeleteQueryResponse": { "description": "(empty)", "schema": { @@ -21628,6 +22268,12 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "internalServerPublicError": { + "description": "InternalServerPublicError is a general error indicating something went wrong internally.", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "jwksResponse": { "description": "(empty)", "schema": { @@ -21654,6 +22300,12 @@ } } }, + "listPublicDashboardsResponse": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/PublicDashboardListResponseWithPagination" + } + }, "listRecordingRulesResponse": { "description": "(empty)", "schema": { @@ -21704,6 +22356,12 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "notFoundPublicError": { + "description": "NotFoundPublicError is returned when the requested resource was not found.", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "okResponse": { "description": "An OKResponse is returned if the request was successful.", "schema": { @@ -21842,12 +22500,24 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "publicErrorResponse": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "queryMetricsWithExpressionsRespons": { "description": "(empty)", "schema": { "$ref": "#/definitions/QueryDataResponse" } }, + "queryPublicDashboardResponse": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/QueryDataResponse" + } + }, "receiversResponse": { "description": "(empty)", "schema": { @@ -21974,6 +22644,12 @@ "$ref": "#/definitions/ErrorResponseBody" } }, + "unauthorisedPublicError": { + "description": "UnauthorisedPublicError is returned when the request is not authenticated.", + "schema": { + "$ref": "#/definitions/publicError" + } + }, "unprocessableEntityError": { "description": "UnprocessableEntityError", "schema": { @@ -21992,6 +22668,12 @@ "$ref": "#/definitions/PlaylistDTO" } }, + "updatePublicDashboardResponse": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/PublicDashboard" + } + }, "updateServiceAccountResponse": { "description": "(empty)", "schema": { @@ -22029,6 +22711,12 @@ "type": "string" } } + }, + "viewPublicDashboardResponse": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/DashboardFullWithMeta" + } } }, "securityDefinitions": { diff --git a/public/openapi3.json b/public/openapi3.json index c855b84e7d4..361cfd8926e 100644 --- a/public/openapi3.json +++ b/public/openapi3.json @@ -122,6 +122,16 @@ }, "description": "BadRequestError is returned when the request is invalid and it cannot be processed." }, + "badRequestPublicError": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/publicError" + } + } + }, + "description": "BadRequestPublicError is returned when the request is invalid and it cannot be processed." + }, "calculateDashboardDiffResponse": { "content": { "application/json": { @@ -275,6 +285,16 @@ }, "description": "(empty)" }, + "createPublicDashboardResponse": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicDashboard" + } + } + }, + "description": "(empty)" + }, "createReportResponse": { "content": { "application/json": { @@ -525,6 +545,16 @@ }, "description": "ForbiddenError is returned if the user/token has insufficient permissions to access the requested resource." }, + "forbiddenPublicError": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/publicError" + } + } + }, + "description": "ForbiddenPublicError is returned if the user/token has insufficient permissions to access the requested resource." + }, "genericError": { "content": { "application/json": { @@ -1016,6 +1046,29 @@ }, "description": "(empty)" }, + "getPublicAnnotationsResponse": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AnnotationEvent" + }, + "type": "array" + } + } + }, + "description": "(empty)" + }, + "getPublicDashboardResponse": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicDashboard" + } + } + }, + "description": "(empty)" + }, "getQueryHistoryDeleteQueryResponse": { "content": { "application/json": { @@ -1286,6 +1339,16 @@ }, "description": "InternalServerError is a general error indicating something went wrong internally." }, + "internalServerPublicError": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/publicError" + } + } + }, + "description": "InternalServerPublicError is a general error indicating something went wrong internally." + }, "jwksResponse": { "content": { "application/json": { @@ -1320,6 +1383,16 @@ }, "description": "(empty)" }, + "listPublicDashboardsResponse": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicDashboardListResponseWithPagination" + } + } + }, + "description": "(empty)" + }, "listRecordingRulesResponse": { "content": { "application/json": { @@ -1390,6 +1463,16 @@ }, "description": "NotFoundError is returned when the requested resource was not found." }, + "notFoundPublicError": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/publicError" + } + } + }, + "description": "NotFoundPublicError is returned when the requested resource was not found." + }, "okResponse": { "content": { "application/json": { @@ -1556,6 +1639,16 @@ }, "description": "PreconditionFailedError" }, + "publicErrorResponse": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/publicError" + } + } + }, + "description": "(empty)" + }, "queryMetricsWithExpressionsRespons": { "content": { "application/json": { @@ -1566,6 +1659,16 @@ }, "description": "(empty)" }, + "queryPublicDashboardResponse": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueryDataResponse" + } + } + }, + "description": "(empty)" + }, "receiversResponse": { "content": { "application/json": { @@ -1768,6 +1871,16 @@ }, "description": "UnauthorizedError is returned when the request is not authenticated." }, + "unauthorisedPublicError": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/publicError" + } + } + }, + "description": "UnauthorisedPublicError is returned when the request is not authenticated." + }, "unprocessableEntityError": { "content": { "application/json": { @@ -1798,6 +1911,16 @@ }, "description": "(empty)" }, + "updatePublicDashboardResponse": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicDashboard" + } + } + }, + "description": "(empty)" + }, "updateServiceAccountResponse": { "content": { "application/json": { @@ -1847,6 +1970,16 @@ } } } + }, + "viewPublicDashboardResponse": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DashboardFullWithMeta" + } + } + }, + "description": "(empty)" } }, "schemas": { @@ -2828,6 +2961,67 @@ }, "type": "object" }, + "AnnotationEvent": { + "properties": { + "color": { + "type": "string" + }, + "dashboardId": { + "format": "int64", + "type": "integer" + }, + "id": { + "format": "int64", + "type": "integer" + }, + "isRegion": { + "type": "boolean" + }, + "panelId": { + "format": "int64", + "type": "integer" + }, + "source": { + "$ref": "#/components/schemas/AnnotationQuery" + }, + "tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "text": { + "type": "string" + }, + "time": { + "format": "int64", + "type": "integer" + }, + "timeEnd": { + "format": "int64", + "type": "integer" + } + }, + "type": "object" + }, + "AnnotationPanelFilter": { + "properties": { + "exclude": { + "description": "Should the specified panels be included or excluded", + "type": "boolean" + }, + "ids": { + "description": "Panel IDs that should be included or excluded", + "items": { + "format": "int64", + "type": "integer" + }, + "type": "array" + } + }, + "title": "AnnotationPanelFilter defines model for AnnotationPanelFilter.", + "type": "object" + }, "AnnotationPermission": { "properties": { "dashboard": { @@ -2839,6 +3033,72 @@ }, "type": "object" }, + "AnnotationQuery": { + "description": "TODO docs\nFROM: AnnotationQuery in grafana-data/src/types/annotations.ts", + "properties": { + "builtIn": { + "description": "Set to 1 for the standard annotation query all dashboards have by default.", + "format": "float", + "type": "number" + }, + "datasource": { + "$ref": "#/components/schemas/DataSourceRef" + }, + "enable": { + "description": "When enabled the annotation query is issued with every dashboard refresh", + "type": "boolean" + }, + "filter": { + "$ref": "#/components/schemas/AnnotationPanelFilter" + }, + "hide": { + "description": "Annotation queries can be toggled on or off at the top of the dashboard.\nWhen hide is true, the toggle is not shown in the dashboard.", + "type": "boolean" + }, + "iconColor": { + "description": "Color to use for the annotation event markers", + "type": "string" + }, + "name": { + "description": "Name of annotation.", + "type": "string" + }, + "target": { + "$ref": "#/components/schemas/AnnotationTarget" + }, + "type": { + "description": "TODO -- this should not exist here, it is based on the --grafana-- datasource", + "type": "string" + } + }, + "type": "object" + }, + "AnnotationTarget": { + "description": "TODO: this should be a regular DataQuery that depends on the selected dashboard\nthese match the properties of the \"grafana\" datasouce that is default in most dashboards", + "properties": { + "limit": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "format": "int64", + "type": "integer" + }, + "matchAny": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "type": "boolean" + }, + "tags": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "description": "Only required/valid for the grafana datasource...\nbut code+tests is already depending on it so hard to change", + "type": "string" + } + }, + "type": "object" + }, "ApiKeyDTO": { "properties": { "accessControl": { @@ -4534,6 +4794,20 @@ }, "type": "object" }, + "DataSourceRef": { + "description": "Ref to a DataSource instance", + "properties": { + "type": { + "description": "The plugin type-id", + "type": "string" + }, + "uid": { + "description": "Specific datasource instance", + "type": "string" + } + }, + "type": "object" + }, "DataTopic": { "description": "nolint:revive", "title": "DataTopic is used to identify which topic the frame should be assigned to.", @@ -4669,6 +4943,17 @@ "title": "EmailConfig configures notifications via mail.", "type": "object" }, + "EmailDTO": { + "properties": { + "recipient": { + "type": "string" + }, + "uid": { + "type": "string" + } + }, + "type": "object" + }, "EmbeddedContactPoint": { "description": "EmbeddedContactPoint is the contact point type that is used\nby grafanas embedded alertmanager implementation.", "properties": { @@ -8068,6 +8353,120 @@ }, "type": "object" }, + "PublicDashboard": { + "properties": { + "accessToken": { + "type": "string" + }, + "annotationsEnabled": { + "type": "boolean" + }, + "createdAt": { + "format": "date-time", + "type": "string" + }, + "createdBy": { + "format": "int64", + "type": "integer" + }, + "dashboardUid": { + "type": "string" + }, + "isEnabled": { + "type": "boolean" + }, + "recipients": { + "items": { + "$ref": "#/components/schemas/EmailDTO" + }, + "type": "array" + }, + "share": { + "$ref": "#/components/schemas/ShareType" + }, + "timeSelectionEnabled": { + "type": "boolean" + }, + "uid": { + "type": "string" + }, + "updatedAt": { + "format": "date-time", + "type": "string" + }, + "updatedBy": { + "format": "int64", + "type": "integer" + } + }, + "type": "object" + }, + "PublicDashboardDTO": { + "properties": { + "accessToken": { + "type": "string" + }, + "annotationsEnabled": { + "type": "boolean" + }, + "isEnabled": { + "type": "boolean" + }, + "share": { + "$ref": "#/components/schemas/ShareType" + }, + "timeSelectionEnabled": { + "type": "boolean" + }, + "uid": { + "type": "string" + } + }, + "type": "object" + }, + "PublicDashboardListResponse": { + "properties": { + "accessToken": { + "type": "string" + }, + "dashboardUid": { + "type": "string" + }, + "isEnabled": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "uid": { + "type": "string" + } + }, + "type": "object" + }, + "PublicDashboardListResponseWithPagination": { + "properties": { + "page": { + "format": "int64", + "type": "integer" + }, + "perPage": { + "format": "int64", + "type": "integer" + }, + "publicDashboards": { + "items": { + "$ref": "#/components/schemas/PublicDashboardListResponse" + }, + "type": "array" + }, + "totalCount": { + "format": "int64", + "type": "integer" + } + }, + "type": "object" + }, "PublicKeyAlgorithm": { "format": "int64", "type": "integer" @@ -9395,6 +9794,9 @@ }, "type": "object" }, + "ShareType": { + "type": "string" + }, "SigV4Config": { "description": "SigV4Config is the configuration for signing remote write requests with\nAWS's SigV4 verification process. Empty values will be retrieved using the\nAWS default credentials chain.", "properties": { @@ -11680,6 +12082,34 @@ ], "type": "object" }, + "publicError": { + "description": "PublicError is derived from Error and only contains information\navailable to the end user.", + "properties": { + "extra": { + "additionalProperties": false, + "description": "Extra Additional information about the error", + "type": "object" + }, + "message": { + "description": "Message A human readable message", + "type": "string" + }, + "messageId": { + "description": "MessageID A unique identifier for the error", + "type": "string" + }, + "statusCode": { + "description": "StatusCode The HTTP status code returned", + "format": "int64", + "type": "integer" + } + }, + "required": [ + "statusCode", + "messageId" + ], + "type": "object" + }, "receiver": { "description": "Receiver receiver", "properties": { @@ -16092,6 +16522,29 @@ ] } }, + "/dashboards/public-dashboards": { + "get": { + "description": "Get list of public dashboards", + "operationId": "listPublicDashboards", + "responses": { + "200": { + "$ref": "#/components/responses/listPublicDashboardsResponse" + }, + "401": { + "$ref": "#/components/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/components/responses/forbiddenPublicError" + }, + "500": { + "$ref": "#/components/responses/internalServerPublicError" + } + }, + "tags": [ + "dashboard_public" + ] + } + }, "/dashboards/tags": { "get": { "operationId": "getDashboardTags", @@ -16143,6 +16596,187 @@ ] } }, + "/dashboards/uid/{dashboardUid}/public-dashboards": { + "get": { + "description": "Get public dashboard by dashboardUid", + "operationId": "getPublicDashboard", + "parameters": [ + { + "in": "path", + "name": "dashboardUid", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "$ref": "#/components/responses/getPublicDashboardResponse" + }, + "400": { + "$ref": "#/components/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/components/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/components/responses/forbiddenPublicError" + }, + "404": { + "$ref": "#/components/responses/notFoundPublicError" + }, + "500": { + "$ref": "#/components/responses/internalServerPublicError" + } + }, + "tags": [ + "dashboard_public" + ] + }, + "post": { + "description": "Create public dashboard for a dashboard", + "operationId": "createPublicDashboard", + "parameters": [ + { + "in": "path", + "name": "dashboardUid", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicDashboardDTO" + } + } + }, + "required": true, + "x-originalParamName": "Body" + }, + "responses": { + "200": { + "$ref": "#/components/responses/createPublicDashboardResponse" + }, + "400": { + "$ref": "#/components/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/components/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/components/responses/forbiddenPublicError" + }, + "500": { + "$ref": "#/components/responses/internalServerPublicError" + } + }, + "tags": [ + "dashboard_public" + ] + } + }, + "/dashboards/uid/{dashboardUid}/public-dashboards/{uid}": { + "delete": { + "description": "Delete public dashboard for a dashboard", + "operationId": "deletePublicDashboard", + "parameters": [ + { + "in": "path", + "name": "dashboardUid", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "uid", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "$ref": "#/components/responses/okResponse" + }, + "400": { + "$ref": "#/components/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/components/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/components/responses/forbiddenPublicError" + }, + "500": { + "$ref": "#/components/responses/internalServerPublicError" + } + }, + "tags": [ + "dashboard_public" + ] + }, + "patch": { + "description": "Update public dashboard for a dashboard", + "operationId": "updatePublicDashboard", + "parameters": [ + { + "in": "path", + "name": "dashboardUid", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "uid", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicDashboardDTO" + } + } + }, + "required": true, + "x-originalParamName": "Body" + }, + "responses": { + "200": { + "$ref": "#/components/responses/updatePublicDashboardResponse" + }, + "400": { + "$ref": "#/components/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/components/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/components/responses/forbiddenPublicError" + }, + "500": { + "$ref": "#/components/responses/internalServerPublicError" + } + }, + "tags": [ + "dashboard_public" + ] + } + }, "/dashboards/uid/{uid}": { "delete": { "description": "Will delete the dashboard given the specified unique identifier (uid).", @@ -20222,6 +20856,132 @@ ] } }, + "/public/dashboards/{accessToken}": { + "get": { + "description": "Get public dashboard for view", + "operationId": "viewPublicDashboard", + "parameters": [ + { + "in": "path", + "name": "accessToken", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "$ref": "#/components/responses/viewPublicDashboardResponse" + }, + "400": { + "$ref": "#/components/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/components/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/components/responses/forbiddenPublicError" + }, + "404": { + "$ref": "#/components/responses/notFoundPublicError" + }, + "500": { + "$ref": "#/components/responses/internalServerPublicError" + } + }, + "tags": [ + "dashboard_public" + ] + } + }, + "/public/dashboards/{accessToken}/annotations": { + "get": { + "description": "Get annotations for a public dashboard", + "operationId": "getPublicAnnotations", + "parameters": [ + { + "in": "path", + "name": "accessToken", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "$ref": "#/components/responses/getPublicAnnotationsResponse" + }, + "400": { + "$ref": "#/components/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/components/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/components/responses/forbiddenPublicError" + }, + "404": { + "$ref": "#/components/responses/notFoundPublicError" + }, + "500": { + "$ref": "#/components/responses/internalServerPublicError" + } + }, + "tags": [ + "dashboard_public" + ] + } + }, + "/public/dashboards/{accessToken}/panels/{panelId}/query": { + "post": { + "description": "Get results for a given panel on a public dashboard", + "operationId": "queryPublicDashboard", + "parameters": [ + { + "in": "path", + "name": "accessToken", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "panelId", + "required": true, + "schema": { + "format": "int64", + "type": "integer" + } + } + ], + "responses": { + "200": { + "$ref": "#/components/responses/queryPublicDashboardResponse" + }, + "400": { + "$ref": "#/components/responses/badRequestPublicError" + }, + "401": { + "$ref": "#/components/responses/unauthorisedPublicError" + }, + "403": { + "$ref": "#/components/responses/forbiddenPublicError" + }, + "404": { + "$ref": "#/components/responses/notFoundPublicError" + }, + "500": { + "$ref": "#/components/responses/internalServerPublicError" + } + }, + "tags": [ + "dashboard_public" + ] + } + }, "/query-history": { "get": { "description": "Returns a list of queries in the query history that matches the search criteria.\nQuery history search supports pagination. Use the `limit` parameter to control the maximum number of queries returned; the default limit is 100.\nYou can also use the `page` query parameter to fetch queries from any page other than the first one.",