mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
API: Add endpoint for updating a data source by its UID (#49396)
* API: Add endpoint for updating a data source by UID * Update docs markdown * Update swagger * Apply suggestions from code review Co-authored-by: Selene <selenepinillos@gmail.com>
This commit is contained in:
committed by
GitHub
parent
8f4c3e94b0
commit
be0d043673
@@ -415,10 +415,12 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Example Response**:
|
**Example Response**:
|
||||||
`GET /api/datasources/:datasourceId/resources/*`
|
|
||||||
```http
|
```http
|
||||||
HTTP/1.1 200
|
HTTP/1.1 200
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## Check data source health
|
## Check data source health
|
||||||
|
|
||||||
@@ -466,6 +468,7 @@ Content-Type: application/json
|
|||||||
|
|
||||||
**Example Response**:
|
**Example Response**:
|
||||||
|
|
||||||
|
```http
|
||||||
HTTP/1.1 200
|
HTTP/1.1 200
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
@@ -495,6 +498,88 @@ Content-Type: application/json
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Query a data source
|
||||||
|
|
||||||
|
Queries a data source having a backend implementation.
|
||||||
|
|
||||||
|
`POST /api/ds/query`
|
||||||
|
|
||||||
|
> **Note:** Grafana's built-in data sources usually have a backend implementation.
|
||||||
|
|
||||||
|
**Example request for the Test data source**:
|
||||||
|
|
||||||
|
```http
|
||||||
|
POST /api/ds/query HTTP/1.1
|
||||||
|
Accept: application/json
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
JSON Body schema:
|
||||||
|
|
||||||
|
- **from/to** – Specifies the time range for the queries. The time can be either epoch timestamps in milliseconds or relative using Grafana time units. For example, `now-5m`.
|
||||||
|
- **queries** – Specifies one or more queries. Must contain at least 1.
|
||||||
|
- **queries.datasource.uid** – Specifies the UID of data source to be queried. Each query in the request must have a unique `datasource`.
|
||||||
|
- **queries.refId** – Specifies an identifier of the query. Defaults to "A".
|
||||||
|
- **queries.format** – Specifies the format the data should be returned in. Valid options are `time_series` or `table` depending on the data source.
|
||||||
|
- **queries.maxDataPoints** - Species the maximum amount of data points that a dashboard panel can render. Defaults to 100.
|
||||||
|
- **queries.intervalMs** - Specifies the time series time interval in milliseconds. Defaults to 1000.
|
||||||
|
|
||||||
|
In addition, specific properties of each data source should be added in a request (for example **queries.stringInput** as shown in the request above). To better understand how to form a query for a certain data source, use the Developer Tools in your browser of choice and inspect the HTTP requests being made to `/api/ds/query`.
|
||||||
|
|
||||||
|
**Example Test data source time series query response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"results": {
|
||||||
|
"A": {
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"schema": {
|
||||||
|
"refId": "A",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "time",
|
||||||
|
"type": "time",
|
||||||
|
"typeInfo": {
|
||||||
|
"frame": "time.Time"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "A-series",
|
||||||
|
"type": "number",
|
||||||
|
"typeInfo": {
|
||||||
|
"frame": "int64",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"values": [
|
||||||
|
[1644488152084, 1644488212084, 1644488272084, 1644488332084, 1644488392084, 1644488452084],
|
||||||
|
[1, 20, 90, 30, 5, 0]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Status codes
|
||||||
|
|
||||||
|
| Code | Description |
|
||||||
|
| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| 200 | All data source queries returned a successful response. |
|
||||||
|
| 400 | Bad request due to invalid JSON, missing content type, missing or invalid fields, etc. Or one or more data source queries were unsuccessful. Refer to the body for more details. |
|
||||||
|
| 403 | Access denied. |
|
||||||
|
| 404 | Either the data source or plugin required to fulfil the request could not be found. |
|
||||||
|
| 500 | Unexpected error. Refer to the body and/or server logs for more details. |
|
||||||
|
|
||||||
|
## Deprecated resources
|
||||||
|
|
||||||
The following resources have been deprecated. They will be removed in a future release.
|
The following resources have been deprecated. They will be removed in a future release.
|
||||||
|
|
||||||
|
|||||||
@@ -305,7 +305,8 @@ func (hs *HTTPServer) registerRoutes() {
|
|||||||
apiRoute.Group("/datasources", func(datasourceRoute routing.RouteRegister) {
|
apiRoute.Group("/datasources", func(datasourceRoute routing.RouteRegister) {
|
||||||
datasourceRoute.Get("/", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionRead)), routing.Wrap(hs.GetDataSources))
|
datasourceRoute.Get("/", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionRead)), routing.Wrap(hs.GetDataSources))
|
||||||
datasourceRoute.Post("/", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionCreate)), quota("data_source"), routing.Wrap(hs.AddDataSource))
|
datasourceRoute.Post("/", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionCreate)), quota("data_source"), routing.Wrap(hs.AddDataSource))
|
||||||
datasourceRoute.Put("/:id", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionWrite, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":id")))), routing.Wrap(hs.UpdateDataSource))
|
datasourceRoute.Put("/:id", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionWrite, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":id")))), routing.Wrap(hs.UpdateDataSourceByID))
|
||||||
|
datasourceRoute.Put("/uid/:uid", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionWrite, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":uid")))), routing.Wrap(hs.UpdateDataSourceByUID))
|
||||||
datasourceRoute.Delete("/:id", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionDelete, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":id")))), routing.Wrap(hs.DeleteDataSourceById))
|
datasourceRoute.Delete("/:id", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionDelete, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":id")))), routing.Wrap(hs.DeleteDataSourceById))
|
||||||
datasourceRoute.Delete("/uid/:uid", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionDelete, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":uid")))), routing.Wrap(hs.DeleteDataSourceByUID))
|
datasourceRoute.Delete("/uid/:uid", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionDelete, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":uid")))), routing.Wrap(hs.DeleteDataSourceByUID))
|
||||||
datasourceRoute.Delete("/name/:name", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionDelete, datasources.ScopeProvider.GetResourceScopeName(ac.Parameter(":name")))), routing.Wrap(hs.DeleteDataSourceByName))
|
datasourceRoute.Delete("/name/:name", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionDelete, datasources.ScopeProvider.GetResourceScopeName(ac.Parameter(":name")))), routing.Wrap(hs.DeleteDataSourceByName))
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ func (hs *HTTPServer) AddDataSource(c *models.ReqContext) response.Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PUT /api/datasources/:id
|
// PUT /api/datasources/:id
|
||||||
func (hs *HTTPServer) UpdateDataSource(c *models.ReqContext) response.Response {
|
func (hs *HTTPServer) UpdateDataSourceByID(c *models.ReqContext) response.Response {
|
||||||
cmd := models.UpdateDataSourceCommand{}
|
cmd := models.UpdateDataSourceCommand{}
|
||||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||||
@@ -297,12 +297,38 @@ func (hs *HTTPServer) UpdateDataSource(c *models.ReqContext) response.Response {
|
|||||||
}
|
}
|
||||||
return response.Error(500, "Failed to update datasource", err)
|
return response.Error(500, "Failed to update datasource", err)
|
||||||
}
|
}
|
||||||
|
return hs.updateDataSourceByID(c, ds, cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT /api/datasources/:uid
|
||||||
|
func (hs *HTTPServer) UpdateDataSourceByUID(c *models.ReqContext) response.Response {
|
||||||
|
cmd := models.UpdateDataSourceCommand{}
|
||||||
|
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||||
|
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||||
|
}
|
||||||
|
datasourcesLogger.Debug("Received command to update data source", "url", cmd.Url)
|
||||||
|
cmd.OrgId = c.OrgId
|
||||||
|
if resp := validateURL(cmd.Type, cmd.Url); resp != nil {
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
ds, err := hs.getRawDataSourceByUID(c.Req.Context(), web.Params(c.Req)[":uid"], c.OrgId)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, models.ErrDataSourceNotFound) {
|
||||||
|
return response.Error(http.StatusNotFound, "Data source not found", nil)
|
||||||
|
}
|
||||||
|
return response.Error(http.StatusInternalServerError, "Failed to update datasource", err)
|
||||||
|
}
|
||||||
|
cmd.Id = ds.Id
|
||||||
|
return hs.updateDataSourceByID(c, ds, cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hs *HTTPServer) updateDataSourceByID(c *models.ReqContext, ds *models.DataSource, cmd models.UpdateDataSourceCommand) response.Response {
|
||||||
if ds.ReadOnly {
|
if ds.ReadOnly {
|
||||||
return response.Error(403, "Cannot update read-only data source", nil)
|
return response.Error(403, "Cannot update read-only data source", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hs.DataSourcesService.UpdateDataSource(c.Req.Context(), &cmd)
|
err := hs.DataSourcesService.UpdateDataSource(c.Req.Context(), &cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, models.ErrDataSourceUpdatingOldVersion) {
|
if errors.Is(err, models.ErrDataSourceUpdatingOldVersion) {
|
||||||
return response.Error(409, "Datasource has already been updated by someone else. Please reload and try again", err)
|
return response.Error(409, "Datasource has already been updated by someone else. Please reload and try again", err)
|
||||||
|
|||||||
@@ -37,7 +37,28 @@ import (
|
|||||||
// 409: conflictError
|
// 409: conflictError
|
||||||
// 500: internalServerError
|
// 500: internalServerError
|
||||||
|
|
||||||
// swagger:route PUT /datasources/{datasource_id} datasources updateDatasource
|
// swagger:route PUT /datasources/{datasource_id} datasources updateDatasourceByID
|
||||||
|
//
|
||||||
|
// Update an existing data source by its sequential ID.
|
||||||
|
//
|
||||||
|
// Similar to creating a data source, `password` and `basicAuthPassword` should be defined under
|
||||||
|
// secureJsonData in order to be stored securely as an encrypted blob in the database. Then, the
|
||||||
|
// encrypted fields are listed under secureJsonFields section in the response.
|
||||||
|
//
|
||||||
|
// If you are running Grafana Enterprise and have Fine-grained access control enabled
|
||||||
|
// you need to have a permission with action: `datasources:write` and scopes: `datasources:*`, `datasources:id:*` and `datasources:id:1` (single data source).
|
||||||
|
//
|
||||||
|
// Please refer to [updated API](#/datasources/updateDatasourceByUID) instead
|
||||||
|
//
|
||||||
|
// Deprecated: true
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: createOrUpdateDatasourceResponse
|
||||||
|
// 401: unauthorisedError
|
||||||
|
// 403: forbiddenError
|
||||||
|
// 500: internalServerError
|
||||||
|
|
||||||
|
// swagger:route PUT /datasources/uid/{datasource_uid} datasources updateDatasourceByUID
|
||||||
//
|
//
|
||||||
// Update an existing data source.
|
// Update an existing data source.
|
||||||
//
|
//
|
||||||
@@ -316,7 +337,7 @@ import (
|
|||||||
// 404: notFoundError
|
// 404: notFoundError
|
||||||
// 500: internalServerError
|
// 500: internalServerError
|
||||||
|
|
||||||
// swagger:parameters updateDatasource deleteDatasourceByID getDatasourceByID datasourceProxyGETcalls datasourceProxyPOSTcalls datasourceProxyDELETEcalls
|
// swagger:parameters updateDatasourceByID deleteDatasourceByID getDatasourceByID datasourceProxyGETcalls datasourceProxyPOSTcalls datasourceProxyDELETEcalls
|
||||||
// swagger:parameters enablePermissions disablePermissions getPermissions deletePermissions
|
// swagger:parameters enablePermissions disablePermissions getPermissions deletePermissions
|
||||||
// swagger:parameters checkDatasourceHealthByID fetchDatasourceResourcesByID
|
// swagger:parameters checkDatasourceHealthByID fetchDatasourceResourcesByID
|
||||||
type DatasourceID struct {
|
type DatasourceID struct {
|
||||||
@@ -325,7 +346,7 @@ type DatasourceID struct {
|
|||||||
DatasourceID string `json:"datasource_id"`
|
DatasourceID string `json:"datasource_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// swagger:parameters deleteDatasourceByUID getDatasourceByUID datasourceProxyGETByUIDcalls datasourceProxyPOSTByUIDcalls datasourceProxyDELETEByUIDcalls
|
// swagger:parameters updateDatasourceByUID deleteDatasourceByUID getDatasourceByUID datasourceProxyGETByUIDcalls datasourceProxyPOSTByUIDcalls datasourceProxyDELETEByUIDcalls
|
||||||
// swagger:parameters checkDatasourceHealth fetchDatasourceResources
|
// swagger:parameters checkDatasourceHealth fetchDatasourceResources
|
||||||
type DatasourceUID struct {
|
type DatasourceUID struct {
|
||||||
// in:path
|
// in:path
|
||||||
@@ -363,7 +384,7 @@ type AddDatasourceParam struct {
|
|||||||
Body models.AddDataSourceCommand
|
Body models.AddDataSourceCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
// swagger:parameters updateDatasource
|
// swagger:parameters updateDatasourceByID updateDatasourceByUID
|
||||||
type UpdateDatasource struct {
|
type UpdateDatasource struct {
|
||||||
// in:body
|
// in:body
|
||||||
// required:true
|
// required:true
|
||||||
|
|||||||
@@ -4598,6 +4598,43 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"put": {
|
||||||
|
"description": "Similar to creating a data source, `password` and `basicAuthPassword` should be defined under\nsecureJsonData in order to be stored securely as an encrypted blob in the database. Then, the\nencrypted fields are listed under secureJsonFields section in the response.\n\nIf you are running Grafana Enterprise and have Fine-grained access control enabled\nyou need to have a permission with action: `datasources:write` and scopes: `datasources:*`, `datasources:uid:*` and `datasources:uid:1` (single data source).",
|
||||||
|
"tags": ["datasources"],
|
||||||
|
"summary": "Update an existing data source.",
|
||||||
|
"operationId": "updateDatasourceByUID",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "DatasourceUID",
|
||||||
|
"name": "datasource_uid",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/UpdateDataSourceCommand"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/createOrUpdateDatasourceResponse"
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"$ref": "#/responses/unauthorisedError"
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"$ref": "#/responses/forbiddenError"
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"$ref": "#/responses/internalServerError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"delete": {
|
"delete": {
|
||||||
"description": "If you are running Grafana Enterprise and have Fine-grained access control enabled\nyou need to have a permission with action: `datasources:delete` and scopes: `datasources:*`, `datasources:uid:*` and `datasources:uid:kLtEtcRGk` (single data source).",
|
"description": "If you are running Grafana Enterprise and have Fine-grained access control enabled\nyou need to have a permission with action: `datasources:delete` and scopes: `datasources:*`, `datasources:uid:*` and `datasources:uid:kLtEtcRGk` (single data source).",
|
||||||
"tags": ["datasources"],
|
"tags": ["datasources"],
|
||||||
@@ -4744,10 +4781,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"put": {
|
"put": {
|
||||||
"description": "Similar to creating a data source, `password` and `basicAuthPassword` should be defined under\nsecureJsonData in order to be stored securely as an encrypted blob in the database. Then, the\nencrypted fields are listed under secureJsonFields section in the response.\n\nIf you are running Grafana Enterprise and have Fine-grained access control enabled\nyou need to have a permission with action: `datasources:write` and scopes: `datasources:*`, `datasources:uid:*` and `datasources:uid:1` (single data source).",
|
"description": "Similar to creating a data source, `password` and `basicAuthPassword` should be defined under\nsecureJsonData in order to be stored securely as an encrypted blob in the database. Then, the\nencrypted fields are listed under secureJsonFields section in the response.\n\nIf you are running Grafana Enterprise and have Fine-grained access control enabled\nyou need to have a permission with action: `datasources:write` and scopes: `datasources:*`, `datasources:id:*` and `datasources:id:1` (single data source).\n\nPlease refer to [updated API](#/datasources/updateDatasourceByUID) instead",
|
||||||
"tags": ["datasources"],
|
"tags": ["datasources"],
|
||||||
"summary": "Update an existing data source.",
|
"summary": "Update an existing data source by its sequential ID.",
|
||||||
"operationId": "updateDatasource",
|
"operationId": "updateDatasourceByID",
|
||||||
|
"deprecated": true,
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -7574,11 +7612,12 @@
|
|||||||
},
|
},
|
||||||
"/reports/render/pdf/{DashboardID}": {
|
"/reports/render/pdf/{DashboardID}": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Available to all users and with a valid license.",
|
"description": "Please refer to [reports enterprise](#/reports/renderReportPDFs) instead. This will be removed in Grafana 10.",
|
||||||
"produces": ["application/pdf"],
|
"produces": ["application/pdf"],
|
||||||
"tags": ["reports", "enterprise"],
|
"tags": ["reports", "enterprise"],
|
||||||
"summary": "Render report for dashboard.",
|
"summary": "Render report for dashboard.",
|
||||||
"operationId": "renderReportPDF",
|
"operationId": "renderReportPDF",
|
||||||
|
"deprecated": true,
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
@@ -7604,6 +7643,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/reports/render/pdfs": {
|
||||||
|
"get": {
|
||||||
|
"description": "Available to all users and with a valid license.",
|
||||||
|
"produces": ["application/pdf"],
|
||||||
|
"tags": ["reports", "enterprise"],
|
||||||
|
"summary": "Render report for multiple dashboards.",
|
||||||
|
"operationId": "renderReportPDFs",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/contentResponse"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"$ref": "#/responses/badRequestError"
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"$ref": "#/responses/unauthorisedError"
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"$ref": "#/responses/internalServerError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/reports/settings": {
|
"/reports/settings": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Available to org admins only and with a valid or expired license\n\nYou need to have a permission with action `reports.settings:read`x.",
|
"description": "Available to org admins only and with a valid or expired license\n\nYou need to have a permission with action `reports.settings:read`x.",
|
||||||
@@ -8643,14 +8705,6 @@
|
|||||||
"summary": "Add External Group.",
|
"summary": "Add External Group.",
|
||||||
"operationId": "addTeamGroupApi",
|
"operationId": "addTeamGroupApi",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"format": "int64",
|
|
||||||
"x-go-name": "TeamID",
|
|
||||||
"name": "teamId",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"x-go-name": "Body",
|
"x-go-name": "Body",
|
||||||
"name": "body",
|
"name": "body",
|
||||||
@@ -8659,6 +8713,14 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/TeamGroupMapping"
|
"$ref": "#/definitions/TeamGroupMapping"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"x-go-name": "TeamID",
|
||||||
|
"name": "teamId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -8692,16 +8754,16 @@
|
|||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "TeamID",
|
"x-go-name": "GroupID",
|
||||||
"name": "teamId",
|
"name": "groupId",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "GroupID",
|
"x-go-name": "TeamID",
|
||||||
"name": "groupId",
|
"name": "teamId",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
@@ -11130,6 +11192,13 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "DashboardUID"
|
"x-go-name": "DashboardUID"
|
||||||
},
|
},
|
||||||
|
"dashboards": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/DashboardDTO"
|
||||||
|
},
|
||||||
|
"x-go-name": "Dashboards"
|
||||||
|
},
|
||||||
"enableCsv": {
|
"enableCsv": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"x-go-name": "EnableCSV"
|
"x-go-name": "EnableCSV"
|
||||||
@@ -11341,6 +11410,13 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "DashboardUID"
|
"x-go-name": "DashboardUID"
|
||||||
},
|
},
|
||||||
|
"dashboards": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/DashboardDTO"
|
||||||
|
},
|
||||||
|
"x-go-name": "Dashboards"
|
||||||
|
},
|
||||||
"enableCsv": {
|
"enableCsv": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"x-go-name": "EnableCSV"
|
"x-go-name": "EnableCSV"
|
||||||
@@ -11631,6 +11707,22 @@
|
|||||||
},
|
},
|
||||||
"x-go-package": "github.com/grafana/grafana/pkg/api/dtos"
|
"x-go-package": "github.com/grafana/grafana/pkg/api/dtos"
|
||||||
},
|
},
|
||||||
|
"DashboardDTO": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"dashboard": {
|
||||||
|
"$ref": "#/definitions/DashboardReportDTO"
|
||||||
|
},
|
||||||
|
"reportVariables": {
|
||||||
|
"type": "object",
|
||||||
|
"x-go-name": "ReportVariables"
|
||||||
|
},
|
||||||
|
"timeRange": {
|
||||||
|
"$ref": "#/definitions/TimeRangeDTO"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "github.com/grafana/grafana/pkg/extensions/report/api"
|
||||||
|
},
|
||||||
"DashboardFullWithMeta": {
|
"DashboardFullWithMeta": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -11771,6 +11863,25 @@
|
|||||||
},
|
},
|
||||||
"x-go-package": "github.com/grafana/grafana/pkg/api/dtos"
|
"x-go-package": "github.com/grafana/grafana/pkg/api/dtos"
|
||||||
},
|
},
|
||||||
|
"DashboardReportDTO": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"x-go-name": "ID"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "Name"
|
||||||
|
},
|
||||||
|
"uid": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "UID"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "github.com/grafana/grafana/pkg/extensions/report/api"
|
||||||
|
},
|
||||||
"DashboardSnapshot": {
|
"DashboardSnapshot": {
|
||||||
"description": "DashboardSnapshot model",
|
"description": "DashboardSnapshot model",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -14052,7 +14163,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Id"
|
"x-go-name": "ID"
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -14067,7 +14178,7 @@
|
|||||||
"x-go-name": "Url"
|
"x-go-name": "Url"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-go-package": "github.com/grafana/grafana/pkg/models"
|
"x-go-package": "github.com/grafana/grafana/pkg/services/preference"
|
||||||
},
|
},
|
||||||
"NavbarPreference": {
|
"NavbarPreference": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -14080,7 +14191,7 @@
|
|||||||
"x-go-name": "SavedItems"
|
"x-go-name": "SavedItems"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-go-package": "github.com/grafana/grafana/pkg/models"
|
"x-go-package": "github.com/grafana/grafana/pkg/services/preference"
|
||||||
},
|
},
|
||||||
"NewApiKeyResult": {
|
"NewApiKeyResult": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -15164,7 +15275,7 @@
|
|||||||
"x-go-name": "HomeTab"
|
"x-go-name": "HomeTab"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-go-package": "github.com/grafana/grafana/pkg/services/preference"
|
"x-go-package": "github.com/grafana/grafana/pkg/models"
|
||||||
},
|
},
|
||||||
"Receiver": {
|
"Receiver": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|||||||
@@ -3660,6 +3660,43 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"put": {
|
||||||
|
"description": "Similar to creating a data source, `password` and `basicAuthPassword` should be defined under\nsecureJsonData in order to be stored securely as an encrypted blob in the database. Then, the\nencrypted fields are listed under secureJsonFields section in the response.\n\nIf you are running Grafana Enterprise and have Fine-grained access control enabled\nyou need to have a permission with action: `datasources:write` and scopes: `datasources:*`, `datasources:uid:*` and `datasources:uid:1` (single data source).",
|
||||||
|
"tags": ["datasources"],
|
||||||
|
"summary": "Update an existing data source.",
|
||||||
|
"operationId": "updateDatasourceByUID",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "DatasourceUID",
|
||||||
|
"name": "datasource_uid",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/UpdateDataSourceCommand"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/createOrUpdateDatasourceResponse"
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"$ref": "#/responses/unauthorisedError"
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"$ref": "#/responses/forbiddenError"
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"$ref": "#/responses/internalServerError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"delete": {
|
"delete": {
|
||||||
"description": "If you are running Grafana Enterprise and have Fine-grained access control enabled\nyou need to have a permission with action: `datasources:delete` and scopes: `datasources:*`, `datasources:uid:*` and `datasources:uid:kLtEtcRGk` (single data source).",
|
"description": "If you are running Grafana Enterprise and have Fine-grained access control enabled\nyou need to have a permission with action: `datasources:delete` and scopes: `datasources:*`, `datasources:uid:*` and `datasources:uid:kLtEtcRGk` (single data source).",
|
||||||
"tags": ["datasources"],
|
"tags": ["datasources"],
|
||||||
@@ -3806,10 +3843,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"put": {
|
"put": {
|
||||||
"description": "Similar to creating a data source, `password` and `basicAuthPassword` should be defined under\nsecureJsonData in order to be stored securely as an encrypted blob in the database. Then, the\nencrypted fields are listed under secureJsonFields section in the response.\n\nIf you are running Grafana Enterprise and have Fine-grained access control enabled\nyou need to have a permission with action: `datasources:write` and scopes: `datasources:*`, `datasources:uid:*` and `datasources:uid:1` (single data source).",
|
"description": "Similar to creating a data source, `password` and `basicAuthPassword` should be defined under\nsecureJsonData in order to be stored securely as an encrypted blob in the database. Then, the\nencrypted fields are listed under secureJsonFields section in the response.\n\nIf you are running Grafana Enterprise and have Fine-grained access control enabled\nyou need to have a permission with action: `datasources:write` and scopes: `datasources:*`, `datasources:id:*` and `datasources:id:1` (single data source).\n\nPlease refer to [updated API](#/datasources/updateDatasourceByUID) instead",
|
||||||
"tags": ["datasources"],
|
"tags": ["datasources"],
|
||||||
"summary": "Update an existing data source.",
|
"summary": "Update an existing data source by its sequential ID.",
|
||||||
"operationId": "updateDatasource",
|
"operationId": "updateDatasourceByID",
|
||||||
|
"deprecated": true,
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -6281,11 +6319,12 @@
|
|||||||
},
|
},
|
||||||
"/reports/render/pdf/{DashboardID}": {
|
"/reports/render/pdf/{DashboardID}": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Available to all users and with a valid license.",
|
"description": "Please refer to [reports enterprise](#/reports/renderReportPDFs) instead. This will be removed in Grafana 10.",
|
||||||
"produces": ["application/pdf"],
|
"produces": ["application/pdf"],
|
||||||
"tags": ["reports", "enterprise"],
|
"tags": ["reports", "enterprise"],
|
||||||
"summary": "Render report for dashboard.",
|
"summary": "Render report for dashboard.",
|
||||||
"operationId": "renderReportPDF",
|
"operationId": "renderReportPDF",
|
||||||
|
"deprecated": true,
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
@@ -6311,6 +6350,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/reports/render/pdfs": {
|
||||||
|
"get": {
|
||||||
|
"description": "Available to all users and with a valid license.",
|
||||||
|
"produces": ["application/pdf"],
|
||||||
|
"tags": ["reports", "enterprise"],
|
||||||
|
"summary": "Render report for multiple dashboards.",
|
||||||
|
"operationId": "renderReportPDFs",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/contentResponse"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"$ref": "#/responses/badRequestError"
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"$ref": "#/responses/unauthorisedError"
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"$ref": "#/responses/internalServerError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/reports/settings": {
|
"/reports/settings": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Available to org admins only and with a valid or expired license\n\nYou need to have a permission with action `reports.settings:read`x.",
|
"description": "Available to org admins only and with a valid or expired license\n\nYou need to have a permission with action `reports.settings:read`x.",
|
||||||
@@ -6988,14 +7050,6 @@
|
|||||||
"summary": "Add External Group.",
|
"summary": "Add External Group.",
|
||||||
"operationId": "addTeamGroupApi",
|
"operationId": "addTeamGroupApi",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"format": "int64",
|
|
||||||
"x-go-name": "TeamID",
|
|
||||||
"name": "teamId",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"x-go-name": "Body",
|
"x-go-name": "Body",
|
||||||
"name": "body",
|
"name": "body",
|
||||||
@@ -7004,6 +7058,14 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/TeamGroupMapping"
|
"$ref": "#/definitions/TeamGroupMapping"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"x-go-name": "TeamID",
|
||||||
|
"name": "teamId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -7037,16 +7099,16 @@
|
|||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "TeamID",
|
"x-go-name": "GroupID",
|
||||||
"name": "teamId",
|
"name": "groupId",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "GroupID",
|
"x-go-name": "TeamID",
|
||||||
"name": "groupId",
|
"name": "teamId",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
@@ -9054,6 +9116,13 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "DashboardUID"
|
"x-go-name": "DashboardUID"
|
||||||
},
|
},
|
||||||
|
"dashboards": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/DashboardDTO"
|
||||||
|
},
|
||||||
|
"x-go-name": "Dashboards"
|
||||||
|
},
|
||||||
"enableCsv": {
|
"enableCsv": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"x-go-name": "EnableCSV"
|
"x-go-name": "EnableCSV"
|
||||||
@@ -9265,6 +9334,13 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "DashboardUID"
|
"x-go-name": "DashboardUID"
|
||||||
},
|
},
|
||||||
|
"dashboards": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/DashboardDTO"
|
||||||
|
},
|
||||||
|
"x-go-name": "Dashboards"
|
||||||
|
},
|
||||||
"enableCsv": {
|
"enableCsv": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"x-go-name": "EnableCSV"
|
"x-go-name": "EnableCSV"
|
||||||
@@ -9555,6 +9631,22 @@
|
|||||||
},
|
},
|
||||||
"x-go-package": "github.com/grafana/grafana/pkg/api/dtos"
|
"x-go-package": "github.com/grafana/grafana/pkg/api/dtos"
|
||||||
},
|
},
|
||||||
|
"DashboardDTO": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"dashboard": {
|
||||||
|
"$ref": "#/definitions/DashboardReportDTO"
|
||||||
|
},
|
||||||
|
"reportVariables": {
|
||||||
|
"type": "object",
|
||||||
|
"x-go-name": "ReportVariables"
|
||||||
|
},
|
||||||
|
"timeRange": {
|
||||||
|
"$ref": "#/definitions/TimeRangeDTO"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "github.com/grafana/grafana/pkg/extensions/report/api"
|
||||||
|
},
|
||||||
"DashboardFullWithMeta": {
|
"DashboardFullWithMeta": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -9695,6 +9787,25 @@
|
|||||||
},
|
},
|
||||||
"x-go-package": "github.com/grafana/grafana/pkg/api/dtos"
|
"x-go-package": "github.com/grafana/grafana/pkg/api/dtos"
|
||||||
},
|
},
|
||||||
|
"DashboardReportDTO": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"x-go-name": "ID"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "Name"
|
||||||
|
},
|
||||||
|
"uid": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "UID"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "github.com/grafana/grafana/pkg/extensions/report/api"
|
||||||
|
},
|
||||||
"DashboardSnapshot": {
|
"DashboardSnapshot": {
|
||||||
"description": "DashboardSnapshot model",
|
"description": "DashboardSnapshot model",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -11060,7 +11171,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Id"
|
"x-go-name": "ID"
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -11075,7 +11186,7 @@
|
|||||||
"x-go-name": "Url"
|
"x-go-name": "Url"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-go-package": "github.com/grafana/grafana/pkg/models"
|
"x-go-package": "github.com/grafana/grafana/pkg/services/preference"
|
||||||
},
|
},
|
||||||
"NavbarPreference": {
|
"NavbarPreference": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -11088,7 +11199,7 @@
|
|||||||
"x-go-name": "SavedItems"
|
"x-go-name": "SavedItems"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-go-package": "github.com/grafana/grafana/pkg/models"
|
"x-go-package": "github.com/grafana/grafana/pkg/services/preference"
|
||||||
},
|
},
|
||||||
"NewApiKeyResult": {
|
"NewApiKeyResult": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -11541,7 +11652,7 @@
|
|||||||
"x-go-name": "HomeTab"
|
"x-go-name": "HomeTab"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-go-package": "github.com/grafana/grafana/pkg/services/preference"
|
"x-go-package": "github.com/grafana/grafana/pkg/models"
|
||||||
},
|
},
|
||||||
"RecordingRuleJSON": {
|
"RecordingRuleJSON": {
|
||||||
"description": "RecordingRuleJSON is the external representation of a recording rule",
|
"description": "RecordingRuleJSON is the external representation of a recording rule",
|
||||||
|
|||||||
Reference in New Issue
Block a user