API: Introduce health and resources data source endpoints using the data source UID (#48676)
* API: introduce health and resources datasource endpoints with UID * Document endpoints * Update swagger
This commit is contained in:
@@ -340,9 +340,15 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
apiRoute.Any("/datasources/proxy/uid/:uid/*", authorize(reqSignedIn, ac.EvalPermission(datasources.ActionQuery)), hs.ProxyDataSourceRequestWithUID)
|
||||
apiRoute.Any("/datasources/proxy/:id", authorize(reqSignedIn, ac.EvalPermission(datasources.ActionQuery)), hs.ProxyDataSourceRequest)
|
||||
apiRoute.Any("/datasources/proxy/uid/:uid", authorize(reqSignedIn, ac.EvalPermission(datasources.ActionQuery)), hs.ProxyDataSourceRequestWithUID)
|
||||
// Deprecated: use /datasources/uid/:uid/resources API instead.
|
||||
apiRoute.Any("/datasources/:id/resources", authorize(reqSignedIn, ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResource)
|
||||
apiRoute.Any("/datasources/uid/:uid/resources", authorize(reqSignedIn, ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResourceWithUID)
|
||||
// Deprecated: use /datasources/uid/:uid/resources/* API instead.
|
||||
apiRoute.Any("/datasources/:id/resources/*", authorize(reqSignedIn, ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResource)
|
||||
apiRoute.Any("/datasources/uid/:uid/resources/*", authorize(reqSignedIn, ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResourceWithUID)
|
||||
// Deprecated: use /datasources/uid/:uid/health API instead.
|
||||
apiRoute.Any("/datasources/:id/health", authorize(reqSignedIn, ac.EvalPermission(datasources.ActionQuery)), routing.Wrap(hs.CheckDatasourceHealth))
|
||||
apiRoute.Any("/datasources/uid/:uid/health", authorize(reqSignedIn, ac.EvalPermission(datasources.ActionQuery)), routing.Wrap(hs.CheckDatasourceHealthWithUID))
|
||||
|
||||
// Folders
|
||||
apiRoute.Group("/folders", func(folderRoute routing.RouteRegister) {
|
||||
|
||||
+49
-1
@@ -425,6 +425,33 @@ func (hs *HTTPServer) CallDatasourceResource(c *models.ReqContext) {
|
||||
hs.callPluginResourceWithDataSource(c, plugin.ID, ds)
|
||||
}
|
||||
|
||||
// /api/datasources/uid/:uid/resources/*
|
||||
func (hs *HTTPServer) CallDatasourceResourceWithUID(c *models.ReqContext) {
|
||||
dsUID := web.Params(c.Req)[":uid"]
|
||||
if !util.IsValidShortUID(dsUID) {
|
||||
c.JsonApiErr(http.StatusBadRequest, "UID is invalid", nil)
|
||||
return
|
||||
}
|
||||
|
||||
ds, err := hs.DataSourceCache.GetDatasourceByUID(c.Req.Context(), dsUID, c.SignedInUser, c.SkipCache)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceAccessDenied) {
|
||||
c.JsonApiErr(http.StatusForbidden, "Access denied to datasource", err)
|
||||
return
|
||||
}
|
||||
c.JsonApiErr(http.StatusInternalServerError, "Unable to load datasource meta data", err)
|
||||
return
|
||||
}
|
||||
|
||||
plugin, exists := hs.pluginStore.Plugin(c.Req.Context(), ds.Type)
|
||||
if !exists {
|
||||
c.JsonApiErr(http.StatusInternalServerError, "Unable to find datasource plugin", err)
|
||||
return
|
||||
}
|
||||
|
||||
hs.callPluginResourceWithDataSource(c, plugin.ID, ds)
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) convertModelToDtos(ctx context.Context, ds *models.DataSource) dtos.DataSource {
|
||||
dto := dtos.DataSource{
|
||||
Id: ds.Id,
|
||||
@@ -462,6 +489,24 @@ func (hs *HTTPServer) convertModelToDtos(ctx context.Context, ds *models.DataSou
|
||||
return dto
|
||||
}
|
||||
|
||||
// CheckDatasourceHealthWithUID sends a health check request to the plugin datasource
|
||||
// /api/datasource/uid/:uid/health
|
||||
func (hs *HTTPServer) CheckDatasourceHealthWithUID(c *models.ReqContext) response.Response {
|
||||
dsUID := web.Params(c.Req)[":uid"]
|
||||
if !util.IsValidShortUID(dsUID) {
|
||||
return response.Error(http.StatusBadRequest, "UID is invalid", nil)
|
||||
}
|
||||
|
||||
ds, err := hs.DataSourceCache.GetDatasourceByUID(c.Req.Context(), dsUID, c.SignedInUser, c.SkipCache)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceAccessDenied) {
|
||||
return response.Error(http.StatusForbidden, "Access denied to datasource", err)
|
||||
}
|
||||
return response.Error(http.StatusInternalServerError, "Unable to load datasource metadata", err)
|
||||
}
|
||||
return hs.checkDatasourceHealth(c, ds)
|
||||
}
|
||||
|
||||
// CheckDatasourceHealth sends a health check request to the plugin datasource
|
||||
// /api/datasource/:id/health
|
||||
func (hs *HTTPServer) CheckDatasourceHealth(c *models.ReqContext) response.Response {
|
||||
@@ -477,10 +522,13 @@ func (hs *HTTPServer) CheckDatasourceHealth(c *models.ReqContext) response.Respo
|
||||
}
|
||||
return response.Error(http.StatusInternalServerError, "Unable to load datasource metadata", err)
|
||||
}
|
||||
return hs.checkDatasourceHealth(c, ds)
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) checkDatasourceHealth(c *models.ReqContext, ds *models.DataSource) response.Response {
|
||||
plugin, exists := hs.pluginStore.Plugin(c.Req.Context(), ds.Type)
|
||||
if !exists {
|
||||
return response.Error(http.StatusInternalServerError, "Unable to find datasource plugin", err)
|
||||
return response.Error(http.StatusInternalServerError, "Unable to find datasource plugin", nil)
|
||||
}
|
||||
|
||||
dsInstanceSettings, err := adapters.ModelToInstanceSettings(ds, hs.decryptSecureJsonDataFn(c.Req.Context()))
|
||||
|
||||
@@ -126,6 +126,60 @@ import (
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
|
||||
// swagger:route GET /datasources/{datasource_id}/health datasources checkDatasourceHealthByID
|
||||
//
|
||||
// Check data source health by Id.
|
||||
//
|
||||
// Please refer to [updated API](#/datasources/checkDatasourceHealth) instead
|
||||
//
|
||||
// Deprecated: true
|
||||
//
|
||||
// Responses:
|
||||
// 200: okResponse
|
||||
// 400: badRequestError
|
||||
// 401: unauthorisedError
|
||||
// 403: forbiddenError
|
||||
// 500: internalServerError
|
||||
|
||||
// swagger:route GET /datasources/uid/{datasource_uid}/health datasources checkDatasourceHealth
|
||||
//
|
||||
// Check data source health by Id.
|
||||
//
|
||||
// Responses:
|
||||
// 200: okResponse
|
||||
// 400: badRequestError
|
||||
// 401: unauthorisedError
|
||||
// 403: forbiddenError
|
||||
// 500: internalServerError
|
||||
|
||||
// swagger:route GET /datasources/{datasource_id}/resources/{datasource_proxy_route} datasources fetchDatasourceResourcesByID
|
||||
//
|
||||
// Fetch data source resources by Id.
|
||||
//
|
||||
// Please refer to [updated API](#/datasources/fetchDatasourceResources) instead
|
||||
//
|
||||
// Deprecated: true
|
||||
//
|
||||
// Responses:
|
||||
// 200: okResponse
|
||||
// 400: badRequestError
|
||||
// 401: unauthorisedError
|
||||
// 403: forbiddenError
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
|
||||
// swagger:route GET /datasources/uid/{datasource_uid}/resources/{datasource_proxy_route} datasources fetchDatasourceResources
|
||||
//
|
||||
// Fetch data source resources.
|
||||
//
|
||||
// Responses:
|
||||
// 200: okResponse
|
||||
// 400: badRequestError
|
||||
// 401: unauthorisedError
|
||||
// 403: forbiddenError
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
|
||||
// swagger:route GET /datasources/name/{datasource_name} datasources getDatasourceByName
|
||||
//
|
||||
// Get a single data source by Name.
|
||||
@@ -264,6 +318,7 @@ import (
|
||||
|
||||
// swagger:parameters updateDatasource deleteDatasourceByID getDatasourceByID datasourceProxyGETcalls datasourceProxyPOSTcalls datasourceProxyDELETEcalls
|
||||
// swagger:parameters enablePermissions disablePermissions getPermissions deletePermissions
|
||||
// swagger:parameters checkDatasourceHealthByID fetchDatasourceResourcesByID
|
||||
type DatasourceID struct {
|
||||
// in:path
|
||||
// required:true
|
||||
@@ -271,6 +326,7 @@ type DatasourceID struct {
|
||||
}
|
||||
|
||||
// swagger:parameters deleteDatasourceByUID getDatasourceByUID datasourceProxyGETByUIDcalls datasourceProxyPOSTByUIDcalls datasourceProxyDELETEByUIDcalls
|
||||
// swagger:parameters checkDatasourceHealth fetchDatasourceResources
|
||||
type DatasourceUID struct {
|
||||
// in:path
|
||||
// required:true
|
||||
@@ -286,6 +342,7 @@ type DatasourceName struct {
|
||||
|
||||
// swagger:parameters datasourceProxyGETcalls datasourceProxyPOSTcalls datasourceProxyDELETEcalls datasourceProxyGETByUIDcalls
|
||||
// swagger:parameters datasourceProxyPOSTByUIDcalls datasourceProxyDELETEByUIDcalls
|
||||
// swagger:parameters fetchDatasourceResources fetchDatasourceResourcesByID
|
||||
type DatasourceProxyRouteParam struct {
|
||||
// in:path
|
||||
// required:true
|
||||
|
||||
Reference in New Issue
Block a user