diff --git a/pkg/services/ngalert/api/authorization.go b/pkg/services/ngalert/api/authorization.go index ffbf663b101..51c62b3d986 100644 --- a/pkg/services/ngalert/api/authorization.go +++ b/pkg/services/ngalert/api/authorization.go @@ -88,8 +88,8 @@ func (api *API) authorize(method, path string) web.Handler { eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalWrite, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID"))) // Lotex Prometheus-compatible Paths - case http.MethodGet + "/api/prometheus/{DatasourceID}/api/v1/rules": - eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":DatasourceID"))) + case http.MethodGet + "/api/prometheus/{DatasourceUID}/api/v1/rules": + eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID"))) // Lotex Rules testing case http.MethodPost + "/api/v1/rule/test/{DatasourceID}": @@ -140,8 +140,8 @@ func (api *API) authorize(method, path string) web.Handler { eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalWrite, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID"))) // Prometheus-compatible Paths - case http.MethodGet + "/api/prometheus/{DatasourceID}/api/v1/alerts": - eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalRead, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":DatasourceID"))) + case http.MethodGet + "/api/prometheus/{DatasourceUID}/api/v1/alerts": + eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalRead, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID"))) // Notification Policies, Contact Points and Templates diff --git a/pkg/services/ngalert/api/forked_prom.go b/pkg/services/ngalert/api/forked_prom.go index a0fdf927b69..b0a617ff5fb 100644 --- a/pkg/services/ngalert/api/forked_prom.go +++ b/pkg/services/ngalert/api/forked_prom.go @@ -25,7 +25,7 @@ func NewForkedProm(datasourceCache datasources.CacheService, proxy *LotexProm, g } func (f *ForkedPrometheusApi) forkRouteGetAlertStatuses(ctx *models.ReqContext) response.Response { - t, err := backendType(ctx, f.DatasourceCache) + t, err := backendTypeByUID(ctx, f.DatasourceCache) if err != nil { return ErrResp(400, err, "") } @@ -39,7 +39,7 @@ func (f *ForkedPrometheusApi) forkRouteGetAlertStatuses(ctx *models.ReqContext) } func (f *ForkedPrometheusApi) forkRouteGetRuleStatuses(ctx *models.ReqContext) response.Response { - t, err := backendType(ctx, f.DatasourceCache) + t, err := backendTypeByUID(ctx, f.DatasourceCache) if err != nil { return ErrResp(400, err, "") } diff --git a/pkg/services/ngalert/api/generated_base_api_prometheus.go b/pkg/services/ngalert/api/generated_base_api_prometheus.go index dc6c8327730..fd4cadcb18e 100644 --- a/pkg/services/ngalert/api/generated_base_api_prometheus.go +++ b/pkg/services/ngalert/api/generated_base_api_prometheus.go @@ -43,11 +43,11 @@ func (f *ForkedPrometheusApi) RouteGetRuleStatuses(ctx *models.ReqContext) respo func (api *API) RegisterPrometheusApiEndpoints(srv PrometheusApiForkingService, m *metrics.API) { api.RouteRegister.Group("", func(group routing.RouteRegister) { group.Get( - toMacaronPath("/api/prometheus/{DatasourceID}/api/v1/alerts"), - api.authorize(http.MethodGet, "/api/prometheus/{DatasourceID}/api/v1/alerts"), + toMacaronPath("/api/prometheus/{DatasourceUID}/api/v1/alerts"), + api.authorize(http.MethodGet, "/api/prometheus/{DatasourceUID}/api/v1/alerts"), metrics.Instrument( http.MethodGet, - "/api/prometheus/{DatasourceID}/api/v1/alerts", + "/api/prometheus/{DatasourceUID}/api/v1/alerts", srv.RouteGetAlertStatuses, m, ), @@ -73,11 +73,11 @@ func (api *API) RegisterPrometheusApiEndpoints(srv PrometheusApiForkingService, ), ) group.Get( - toMacaronPath("/api/prometheus/{DatasourceID}/api/v1/rules"), - api.authorize(http.MethodGet, "/api/prometheus/{DatasourceID}/api/v1/rules"), + toMacaronPath("/api/prometheus/{DatasourceUID}/api/v1/rules"), + api.authorize(http.MethodGet, "/api/prometheus/{DatasourceUID}/api/v1/rules"), metrics.Instrument( http.MethodGet, - "/api/prometheus/{DatasourceID}/api/v1/rules", + "/api/prometheus/{DatasourceUID}/api/v1/rules", srv.RouteGetRuleStatuses, m, ), diff --git a/pkg/services/ngalert/api/lotex_prom.go b/pkg/services/ngalert/api/lotex_prom.go index 011885e309d..f94797a4294 100644 --- a/pkg/services/ngalert/api/lotex_prom.go +++ b/pkg/services/ngalert/api/lotex_prom.go @@ -3,7 +3,6 @@ package api import ( "fmt" "net/http" - "strconv" "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/infra/log" @@ -78,12 +77,12 @@ func (p *LotexProm) RouteGetRuleStatuses(ctx *models.ReqContext) response.Respon } func (p *LotexProm) getEndpoints(ctx *models.ReqContext) (*promEndpoints, error) { - datasourceID, err := strconv.ParseInt(web.Params(ctx.Req)[":DatasourceID"], 10, 64) - if err != nil { - return nil, fmt.Errorf("datasource ID is invalid") + datasourceUID := web.Params(ctx.Req)[":DatasourceUID"] + if datasourceUID == "" { + return nil, fmt.Errorf("datasource UID is invalid") } - ds, err := p.DataProxy.DataSourceCache.GetDatasource(ctx.Req.Context(), datasourceID, ctx.SignedInUser, ctx.SkipCache) + ds, err := p.DataProxy.DataSourceCache.GetDatasourceByUID(ctx.Req.Context(), datasourceUID, ctx.SignedInUser, ctx.SkipCache) if err != nil { return nil, err } diff --git a/pkg/services/ngalert/api/tooling/definitions/alertmanager.go b/pkg/services/ngalert/api/tooling/definitions/alertmanager.go index 915e601c303..084aab24421 100644 --- a/pkg/services/ngalert/api/tooling/definitions/alertmanager.go +++ b/pkg/services/ngalert/api/tooling/definitions/alertmanager.go @@ -438,8 +438,6 @@ type BodyAlertingConfig struct { Body PostableUserConfig } -// prom routes -// swagger:parameters RouteGetRuleStatuses RouteGetAlertStatuses // testing routes // swagger:parameters RouteTestReceiverConfig RouteTestRuleConfig type DatasourceIDReference struct { @@ -450,6 +448,8 @@ type DatasourceIDReference struct { // alertmanager routes // swagger:parameters RoutePostAlertingConfig RouteGetAlertingConfig RouteDeleteAlertingConfig RouteGetAMStatus RouteGetAMAlerts RoutePostAMAlerts RouteGetAMAlertGroups RouteGetSilences RouteCreateSilence RouteGetSilence RouteDeleteSilence RoutePostAlertingConfig RoutePostTestReceivers +// prom routes +// swagger:parameters RouteGetRuleStatuses RouteGetAlertStatuses // ruler routes // swagger:parameters RouteGetRulesConfig RoutePostNameRulesConfig RouteGetNamespaceRulesConfig RouteDeleteNamespaceRulesConfig RouteGetRulegGroupConfig RouteDeleteRuleGroupConfig type DatasourceUIDReference struct { diff --git a/pkg/services/ngalert/api/tooling/definitions/prom.go b/pkg/services/ngalert/api/tooling/definitions/prom.go index 1ba9f835178..c5519eb2fe4 100644 --- a/pkg/services/ngalert/api/tooling/definitions/prom.go +++ b/pkg/services/ngalert/api/tooling/definitions/prom.go @@ -13,7 +13,7 @@ import ( // Responses: // 200: RuleResponse -// swagger:route GET /api/prometheus/{DatasourceID}/api/v1/rules prometheus RouteGetRuleStatuses +// swagger:route GET /api/prometheus/{DatasourceUID}/api/v1/rules prometheus RouteGetRuleStatuses // // gets the evaluation statuses of all rules // @@ -27,7 +27,7 @@ import ( // Responses: // 200: AlertResponse -// swagger:route GET /api/prometheus/{DatasourceID}/api/v1/alerts prometheus RouteGetAlertStatuses +// swagger:route GET /api/prometheus/{DatasourceUID}/api/v1/alerts prometheus RouteGetAlertStatuses // // gets the current alerts // diff --git a/pkg/services/ngalert/api/tooling/post.json b/pkg/services/ngalert/api/tooling/post.json index acdb3595265..14a483eaa66 100644 --- a/pkg/services/ngalert/api/tooling/post.json +++ b/pkg/services/ngalert/api/tooling/post.json @@ -2883,7 +2883,6 @@ "x-go-package": "github.com/prometheus/alertmanager/timeinterval" }, "URL": { - "description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.", "properties": { "ForceQuery": { "type": "boolean" @@ -2916,9 +2915,9 @@ "$ref": "#/definitions/Userinfo" } }, - "title": "A URL represents a parsed URL (technically, a URI reference).", + "title": "URL is a custom URL type that allows validation at configuration load time.", "type": "object", - "x-go-package": "net/url" + "x-go-package": "github.com/prometheus/common/config" }, "Userinfo": { "description": "The Userinfo type is an immutable encapsulation of username and\npassword details for a URL. An existing Userinfo value is guaranteed\nto have a username set (potentially empty, as allowed by RFC 2396),\nand optionally a password.", @@ -3115,7 +3114,6 @@ "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "alertGroup": { - "description": "AlertGroup alert group", "properties": { "alerts": { "description": "alerts", @@ -3137,7 +3135,9 @@ "labels", "receiver" ], - "type": "object" + "type": "object", + "x-go-name": "AlertGroup", + "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "alertGroups": { "items": { @@ -3328,11 +3328,12 @@ "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "gettableAlerts": { - "description": "GettableAlerts gettable alerts", "items": { "$ref": "#/definitions/gettableAlert" }, - "type": "array" + "type": "array", + "x-go-name": "GettableAlerts", + "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "gettableSilence": { "description": "GettableSilence gettable silence", @@ -3524,7 +3525,6 @@ "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "postableSilence": { - "description": "PostableSilence postable silence", "properties": { "comment": { "description": "comment", @@ -3564,7 +3564,9 @@ "matchers", "startsAt" ], - "type": "object" + "type": "object", + "x-go-name": "PostableSilence", + "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "receiver": { "description": "Receiver receiver", @@ -4745,18 +4747,17 @@ ] } }, - "/api/prometheus/{DatasourceID}/api/v1/alerts": { + "/api/prometheus/{DatasourceUID}/api/v1/alerts": { "get": { "description": "gets the current alerts", "operationId": "RouteGetAlertStatuses", "parameters": [ { - "description": "DatasourceID should be the numeric datasource identifier", - "format": "int64", + "description": "DatasoureUID should be the datasource UID identifier", "in": "path", - "name": "DatasourceID", + "name": "DatasourceUID", "required": true, - "type": "integer" + "type": "string" } ], "responses": { @@ -4772,18 +4773,17 @@ ] } }, - "/api/prometheus/{DatasourceID}/api/v1/rules": { + "/api/prometheus/{DatasourceUID}/api/v1/rules": { "get": { "description": "gets the evaluation statuses of all rules", "operationId": "RouteGetRuleStatuses", "parameters": [ { - "description": "DatasourceID should be the numeric datasource identifier", - "format": "int64", + "description": "DatasoureUID should be the datasource UID identifier", "in": "path", - "name": "DatasourceID", + "name": "DatasourceUID", "required": true, - "type": "integer" + "type": "string" } ], "responses": { diff --git a/pkg/services/ngalert/api/tooling/spec.json b/pkg/services/ngalert/api/tooling/spec.json index 656d563f1e2..07f858c16b9 100644 --- a/pkg/services/ngalert/api/tooling/spec.json +++ b/pkg/services/ngalert/api/tooling/spec.json @@ -1070,7 +1070,7 @@ } } }, - "/api/prometheus/{DatasourceID}/api/v1/alerts": { + "/api/prometheus/{DatasourceUID}/api/v1/alerts": { "get": { "description": "gets the current alerts", "tags": [ @@ -1079,10 +1079,9 @@ "operationId": "RouteGetAlertStatuses", "parameters": [ { - "type": "integer", - "format": "int64", - "description": "DatasourceID should be the numeric datasource identifier", - "name": "DatasourceID", + "type": "string", + "description": "DatasoureUID should be the datasource UID identifier", + "name": "DatasourceUID", "in": "path", "required": true } @@ -1097,7 +1096,7 @@ } } }, - "/api/prometheus/{DatasourceID}/api/v1/rules": { + "/api/prometheus/{DatasourceUID}/api/v1/rules": { "get": { "description": "gets the evaluation statuses of all rules", "tags": [ @@ -1106,10 +1105,9 @@ "operationId": "RouteGetRuleStatuses", "parameters": [ { - "type": "integer", - "format": "int64", - "description": "DatasourceID should be the numeric datasource identifier", - "name": "DatasourceID", + "type": "string", + "description": "DatasoureUID should be the datasource UID identifier", + "name": "DatasourceUID", "in": "path", "required": true } @@ -4864,9 +4862,8 @@ "x-go-package": "github.com/prometheus/alertmanager/timeinterval" }, "URL": { - "description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.", "type": "object", - "title": "A URL represents a parsed URL (technically, a URI reference).", + "title": "URL is a custom URL type that allows validation at configuration load time.", "properties": { "ForceQuery": { "type": "boolean" @@ -4899,7 +4896,7 @@ "$ref": "#/definitions/Userinfo" } }, - "x-go-package": "net/url" + "x-go-package": "github.com/prometheus/common/config" }, "Userinfo": { "description": "The Userinfo type is an immutable encapsulation of username and\npassword details for a URL. An existing Userinfo value is guaranteed\nto have a username set (potentially empty, as allowed by RFC 2396),\nand optionally a password.", @@ -5096,7 +5093,6 @@ "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "alertGroup": { - "description": "AlertGroup alert group", "type": "object", "required": [ "alerts", @@ -5119,6 +5115,8 @@ "$ref": "#/definitions/receiver" } }, + "x-go-name": "AlertGroup", + "x-go-package": "github.com/prometheus/alertmanager/api/v2/models", "$ref": "#/definitions/alertGroup" }, "alertGroups": { @@ -5312,11 +5310,12 @@ "$ref": "#/definitions/gettableAlert" }, "gettableAlerts": { - "description": "GettableAlerts gettable alerts", "type": "array", "items": { "$ref": "#/definitions/gettableAlert" }, + "x-go-name": "GettableAlerts", + "x-go-package": "github.com/prometheus/alertmanager/api/v2/models", "$ref": "#/definitions/gettableAlerts" }, "gettableSilence": { @@ -5511,7 +5510,6 @@ "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "postableSilence": { - "description": "PostableSilence postable silence", "type": "object", "required": [ "comment", @@ -5552,6 +5550,8 @@ "x-go-name": "StartsAt" } }, + "x-go-name": "PostableSilence", + "x-go-package": "github.com/prometheus/alertmanager/api/v2/models", "$ref": "#/definitions/postableSilence" }, "receiver": { diff --git a/pkg/services/ngalert/api/util.go b/pkg/services/ngalert/api/util.go index ed079702b2f..6654ba21485 100644 --- a/pkg/services/ngalert/api/util.go +++ b/pkg/services/ngalert/api/util.go @@ -35,23 +35,6 @@ func toMacaronPath(path string) string { })) } -func backendType(ctx *models.ReqContext, cache datasources.CacheService) (apimodels.Backend, error) { - datasourceID := web.Params(ctx.Req)[":DatasourceID"] - if datasourceID, err := strconv.ParseInt(datasourceID, 10, 64); err == nil { - if ds, err := cache.GetDatasource(ctx.Req.Context(), datasourceID, ctx.SignedInUser, ctx.SkipCache); err == nil { - switch ds.Type { - case "loki", "prometheus": - return apimodels.LoTexRulerBackend, nil - case "alertmanager": - return apimodels.AlertmanagerBackend, nil - default: - return 0, fmt.Errorf("unexpected backend type (%v)", ds.Type) - } - } - } - return 0, fmt.Errorf("unexpected backend type (%v)", datasourceID) -} - func backendTypeByUID(ctx *models.ReqContext, cache datasources.CacheService) (apimodels.Backend, error) { datasourceUID := web.Params(ctx.Req)[":DatasourceUID"] if ds, err := cache.GetDatasourceByUID(ctx.Req.Context(), datasourceUID, ctx.SignedInUser, ctx.SkipCache); err == nil { diff --git a/public/api-merged.json b/public/api-merged.json index 11c1856d659..8cc8b20cc78 100644 --- a/public/api-merged.json +++ b/public/api-merged.json @@ -6620,17 +6620,16 @@ } } }, - "/prometheus/{DatasourceID}/api/v1/alerts": { + "/prometheus/{DatasourceUID}/api/v1/alerts": { "get": { "description": "gets the current alerts", "tags": ["prometheus"], "operationId": "RouteGetAlertStatuses", "parameters": [ { - "type": "integer", - "format": "int64", - "description": "DatasourceID should be the numeric datasource identifier", - "name": "DatasourceID", + "type": "string", + "description": "DatasoureUID should be the datasource UID identifier", + "name": "DatasourceUID", "in": "path", "required": true } @@ -6645,17 +6644,16 @@ } } }, - "/prometheus/{DatasourceID}/api/v1/rules": { + "/prometheus/{DatasourceUID}/api/v1/rules": { "get": { "description": "gets the evaluation statuses of all rules", "tags": ["prometheus"], "operationId": "RouteGetRuleStatuses", "parameters": [ { - "type": "integer", - "format": "int64", - "description": "DatasourceID should be the numeric datasource identifier", - "name": "DatasourceID", + "type": "string", + "description": "DatasoureUID should be the datasource UID identifier", + "name": "DatasourceUID", "in": "path", "required": true } @@ -16375,9 +16373,8 @@ "x-go-package": "github.com/grafana/grafana/pkg/api/dtos" }, "URL": { - "description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.", "type": "object", - "title": "A URL represents a parsed URL (technically, a URI reference).", + "title": "URL is a custom URL type that allows validation at configuration load time.", "properties": { "ForceQuery": { "type": "boolean" @@ -16410,7 +16407,7 @@ "$ref": "#/definitions/Userinfo" } }, - "x-go-package": "net/url" + "x-go-package": "github.com/prometheus/common/config" }, "UpdateAlertNotificationCommand": { "type": "object", @@ -17487,11 +17484,12 @@ "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "gettableAlerts": { - "description": "GettableAlerts gettable alerts", "type": "array", "items": { "$ref": "#/definitions/gettableAlert" - } + }, + "x-go-name": "GettableAlerts", + "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "gettableSilence": { "description": "GettableSilence gettable silence", @@ -17665,7 +17663,6 @@ "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "postableSilence": { - "description": "PostableSilence postable silence", "type": "object", "required": ["comment", "createdBy", "endsAt", "matchers", "startsAt"], "properties": { @@ -17699,7 +17696,9 @@ "format": "date-time", "x-go-name": "StartsAt" } - } + }, + "x-go-name": "PostableSilence", + "x-go-package": "github.com/prometheus/alertmanager/api/v2/models" }, "receiver": { "type": "object", diff --git a/public/app/features/alerting/unified/api/prometheus.ts b/public/app/features/alerting/unified/api/prometheus.ts index acb42bd3678..b14373b5fc7 100644 --- a/public/app/features/alerting/unified/api/prometheus.ts +++ b/public/app/features/alerting/unified/api/prometheus.ts @@ -4,7 +4,7 @@ import { getBackendSrv } from '@grafana/runtime'; import { RuleNamespace } from 'app/types/unified-alerting'; import { PromRulesResponse } from 'app/types/unified-alerting-dto'; -import { getDatasourceAPIId, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; +import { getDatasourceAPIUid, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; export interface FetchPromRulesFilter { dashboardUID: string; @@ -24,7 +24,7 @@ export function prometheusUrlBuilder(dataSourceConfig: PrometheusDataSourceConfi const params = prepareRulesFilterQueryParams(searchParams, filter); return { - url: `/api/prometheus/${getDatasourceAPIId(dataSourceName)}/api/v1/rules`, + url: `/api/prometheus/${getDatasourceAPIUid(dataSourceName)}/api/v1/rules`, params: params, }; },