Alerting: Update forking request handlers to use the same errors (#52965)

* generalize error handling in forking request handlers
* remove MatchesBackend and change test to test Can
* add 404 to route specs
* change backendTypeByUID to getDatasourceByUID of expected type
* use common errors in api testing
* handle 401 in errorToResponse
* replace backend type error with "unexpected datasource type"
* update swagger spec
This commit is contained in:
Yuriy Tseretyan
2022-08-02 09:33:59 -04:00
committed by GitHub
parent 28e27e1365
commit 718620c197
15 changed files with 3204 additions and 596 deletions
+482 -6
View File
@@ -96,9 +96,6 @@
"title": "AlertManager models a configured Alert Manager.",
"type": "object"
},
"AlertManagerNotFound": {
"type": "object"
},
"AlertManagerNotReady": {
"type": "object"
},
@@ -284,6 +281,9 @@
},
"type": "object"
},
"AlertStateType": {
"type": "string"
},
"AlertingRule": {
"description": "adapted from cortex",
"properties": {
@@ -401,6 +401,11 @@
"title": "BasicAuth contains basic HTTP authentication credentials.",
"type": "object"
},
"ConfFloat64": {
"description": "ConfFloat64 is a float64. It Marshals float64 values of NaN of Inf\nto null.",
"format": "double",
"type": "number"
},
"Config": {
"properties": {
"global": {
@@ -437,6 +442,39 @@
},
"type": "array"
},
"DataLink": {
"description": "DataLink define what",
"properties": {
"targetBlank": {
"type": "boolean"
},
"title": {
"type": "string"
},
"url": {
"type": "string"
}
},
"type": "object"
},
"DataResponse": {
"description": "A map of RefIDs (unique query identifiers) to this type makes up the Responses property of a QueryDataResponse.\nThe Error property is used to allow for partial success responses from the containing QueryDataResponse.",
"properties": {
"Error": {
"description": "Error is a property to be set if the the corresponding DataQuery has an error.",
"type": "string"
},
"Frames": {
"$ref": "#/definitions/Frames"
}
},
"title": "DataResponse contains the results from a DataQuery.",
"type": "object"
},
"DataTopic": {
"title": "DataTopic is used to identify which topic the frame should be assigned to.",
"type": "string"
},
"DateTime": {
"description": "DateTime is a time but it serializes to ISO8601 format with millis\nIt knows how to read 3 different variations of a RFC3339 date time.\nMost APIs we encounter want either millisecond or second precision times.\nThis just tries to make it worry-free.",
"format": "date-time",
@@ -664,6 +702,197 @@
"Failure": {
"$ref": "#/definitions/ResponseDetails"
},
"Field": {
"description": "A Field is essentially a slice of various types with extra properties and methods.\nSee NewField() for supported types.\n\nThe slice data in the Field is a not exported, so methods on the Field are used to to manipulate its data.",
"properties": {
"config": {
"$ref": "#/definitions/FieldConfig"
},
"labels": {
"$ref": "#/definitions/FrameLabels"
},
"name": {
"description": "Name is default identifier of the field. The name does not have to be unique, but the combination\nof name and Labels should be unique for proper behavior in all situations.",
"type": "string"
}
},
"title": "Field represents a typed column of data within a Frame.",
"type": "object"
},
"FieldConfig": {
"properties": {
"color": {
"additionalProperties": {
"type": "object"
},
"description": "Map values to a display color\nNOTE: this interface is under development in the frontend... so simple map for now",
"type": "object"
},
"custom": {
"additionalProperties": {
"type": "object"
},
"description": "Panel Specific Values",
"type": "object"
},
"decimals": {
"format": "uint16",
"type": "integer"
},
"description": {
"description": "Description is human readable field metadata",
"type": "string"
},
"displayName": {
"description": "DisplayName overrides Grafana default naming, should not be used from a data source",
"type": "string"
},
"displayNameFromDS": {
"description": "DisplayNameFromDS overrides Grafana default naming in a better way that allows users to override it easily.",
"type": "string"
},
"filterable": {
"description": "Filterable indicates if the Field's data can be filtered by additional calls.",
"type": "boolean"
},
"interval": {
"description": "Interval indicates the expected regular step between values in the series.\nWhen an interval exists, consumers can identify \"missing\" values when the expected value is not present.\nThe grafana timeseries visualization will render disconnected values when missing values are found it the time field.\nThe interval uses the same units as the values. For time.Time, this is defined in milliseconds.",
"format": "double",
"type": "number"
},
"links": {
"description": "The behavior when clicking on a result",
"items": {
"$ref": "#/definitions/DataLink"
},
"type": "array"
},
"mappings": {
"$ref": "#/definitions/ValueMappings"
},
"max": {
"$ref": "#/definitions/ConfFloat64"
},
"min": {
"$ref": "#/definitions/ConfFloat64"
},
"noValue": {
"description": "Alternative to empty string",
"type": "string"
},
"path": {
"description": "Path is an explicit path to the field in the datasource. When the frame meta includes a path,\nthis will default to `${frame.meta.path}/${field.name}\n\nWhen defined, this value can be used as an identifier within the datasource scope, and\nmay be used as an identifier to update values in a subsequent request",
"type": "string"
},
"thresholds": {
"$ref": "#/definitions/ThresholdsConfig"
},
"unit": {
"description": "Numeric Options",
"type": "string"
},
"writeable": {
"description": "Writeable indicates that the datasource knows how to update this value",
"type": "boolean"
}
},
"title": "FieldConfig represents the display properties for a Field.",
"type": "object"
},
"Frame": {
"description": "Each Field is well typed by its FieldType and supports optional Labels.\n\nA Frame is a general data container for Grafana. A Frame can be table data\nor time series data depending on its content and field types.",
"properties": {
"Fields": {
"description": "Fields are the columns of a frame.\nAll Fields must be of the same the length when marshalling the Frame for transmission.",
"items": {
"$ref": "#/definitions/Field"
},
"type": "array"
},
"Meta": {
"$ref": "#/definitions/FrameMeta"
},
"Name": {
"description": "Name is used in some Grafana visualizations.",
"type": "string"
},
"RefID": {
"description": "RefID is a property that can be set to match a Frame to its originating query.",
"type": "string"
}
},
"title": "Frame is a columnar data structure where each column is a Field.",
"type": "object"
},
"FrameLabels": {
"additionalProperties": {
"type": "string"
},
"description": "Labels are used to add metadata to an object. The JSON will always be sorted keys",
"type": "object"
},
"FrameMeta": {
"description": "https://github.com/grafana/grafana/blob/master/packages/grafana-data/src/types/data.ts#L11\nNOTE -- in javascript this can accept any `[key: string]: any;` however\nthis interface only exposes the values we want to be exposed",
"properties": {
"channel": {
"description": "Channel is the path to a stream in grafana live that has real-time updates for this data.",
"type": "string"
},
"custom": {
"description": "Custom datasource specific values.",
"type": "object"
},
"dataTopic": {
"$ref": "#/definitions/DataTopic"
},
"executedQueryString": {
"description": "ExecutedQueryString is the raw query sent to the underlying system. All macros and templating\nhave been applied. When metadata contains this value, it will be shown in the query inspector.",
"type": "string"
},
"notices": {
"description": "Notices provide additional information about the data in the Frame that\nGrafana can display to the user in the user interface.",
"items": {
"$ref": "#/definitions/Notice"
},
"type": "array"
},
"path": {
"description": "Path is a browsable path on the datasource.",
"type": "string"
},
"pathSeparator": {
"description": "PathSeparator defines the separator pattern to decode a hierarchy. The default separator is '/'.",
"type": "string"
},
"preferredVisualisationType": {
"$ref": "#/definitions/VisType"
},
"stats": {
"description": "Stats is an array of query result statistics.",
"items": {
"$ref": "#/definitions/QueryStat"
},
"type": "array"
},
"type": {
"$ref": "#/definitions/FrameType"
}
},
"title": "FrameMeta matches:",
"type": "object"
},
"FrameType": {
"description": "A FrameType string, when present in a frame's metadata, asserts that the\nframe's structure conforms to the FrameType's specification.\nThis property is currently optional, so FrameType may be FrameTypeUnknown even if the properties of\nthe Frame correspond to a defined FrameType.",
"type": "string"
},
"Frames": {
"description": "It is the main data container within a backend.DataResponse.",
"items": {
"$ref": "#/definitions/Frame"
},
"title": "Frames is a slice of Frame pointers.",
"type": "array"
},
"GettableAlertmanagers": {
"properties": {
"data": {
@@ -1176,6 +1405,11 @@
},
"type": "object"
},
"InspectType": {
"format": "int64",
"title": "InspectType is a type for the Inspect property of a Notice.",
"type": "integer"
},
"Json": {
"type": "object"
},
@@ -1217,6 +1451,82 @@
},
"type": "array"
},
"LegacyAlert": {
"properties": {
"Created": {
"format": "date-time",
"type": "string"
},
"DashboardId": {
"format": "int64",
"type": "integer"
},
"EvalData": {
"$ref": "#/definitions/Json"
},
"ExecutionError": {
"type": "string"
},
"For": {
"$ref": "#/definitions/Duration"
},
"Frequency": {
"format": "int64",
"type": "integer"
},
"Handler": {
"format": "int64",
"type": "integer"
},
"Id": {
"format": "int64",
"type": "integer"
},
"Message": {
"type": "string"
},
"Name": {
"type": "string"
},
"NewStateDate": {
"format": "date-time",
"type": "string"
},
"OrgId": {
"format": "int64",
"type": "integer"
},
"PanelId": {
"format": "int64",
"type": "integer"
},
"Settings": {
"$ref": "#/definitions/Json"
},
"Severity": {
"type": "string"
},
"Silenced": {
"type": "boolean"
},
"State": {
"$ref": "#/definitions/AlertStateType"
},
"StateChanges": {
"format": "int64",
"type": "integer"
},
"Updated": {
"format": "date-time",
"type": "string"
},
"Version": {
"format": "int64",
"type": "integer"
}
},
"type": "object"
},
"MatchRegexps": {
"additionalProperties": {
"$ref": "#/definitions/Regexp"
@@ -1329,6 +1639,31 @@
"NotFound": {
"type": "object"
},
"Notice": {
"properties": {
"inspect": {
"$ref": "#/definitions/InspectType"
},
"link": {
"description": "Link is an optional link for display in the user interface and can be an\nabsolute URL or a path relative to Grafana's root url.",
"type": "string"
},
"severity": {
"$ref": "#/definitions/NoticeSeverity"
},
"text": {
"description": "Text is freeform descriptive text for the notice.",
"type": "string"
}
},
"title": "Notice provides a structure for presenting notifications in Grafana's user interface.",
"type": "object"
},
"NoticeSeverity": {
"format": "int64",
"title": "NoticeSeverity is a type for the Severity property of a Notice.",
"type": "integer"
},
"NotifierConfig": {
"properties": {
"send_resolved": {
@@ -2008,6 +2343,91 @@
},
"type": "object"
},
"QueryStat": {
"description": "The embedded FieldConfig's display name must be set.\nIt corresponds to the QueryResultMetaStat on the frontend (https://github.com/grafana/grafana/blob/master/packages/grafana-data/src/types/data.ts#L53).",
"properties": {
"color": {
"additionalProperties": {
"type": "object"
},
"description": "Map values to a display color\nNOTE: this interface is under development in the frontend... so simple map for now",
"type": "object"
},
"custom": {
"additionalProperties": {
"type": "object"
},
"description": "Panel Specific Values",
"type": "object"
},
"decimals": {
"format": "uint16",
"type": "integer"
},
"description": {
"description": "Description is human readable field metadata",
"type": "string"
},
"displayName": {
"description": "DisplayName overrides Grafana default naming, should not be used from a data source",
"type": "string"
},
"displayNameFromDS": {
"description": "DisplayNameFromDS overrides Grafana default naming in a better way that allows users to override it easily.",
"type": "string"
},
"filterable": {
"description": "Filterable indicates if the Field's data can be filtered by additional calls.",
"type": "boolean"
},
"interval": {
"description": "Interval indicates the expected regular step between values in the series.\nWhen an interval exists, consumers can identify \"missing\" values when the expected value is not present.\nThe grafana timeseries visualization will render disconnected values when missing values are found it the time field.\nThe interval uses the same units as the values. For time.Time, this is defined in milliseconds.",
"format": "double",
"type": "number"
},
"links": {
"description": "The behavior when clicking on a result",
"items": {
"$ref": "#/definitions/DataLink"
},
"type": "array"
},
"mappings": {
"$ref": "#/definitions/ValueMappings"
},
"max": {
"$ref": "#/definitions/ConfFloat64"
},
"min": {
"$ref": "#/definitions/ConfFloat64"
},
"noValue": {
"description": "Alternative to empty string",
"type": "string"
},
"path": {
"description": "Path is an explicit path to the field in the datasource. When the frame meta includes a path,\nthis will default to `${frame.meta.path}/${field.name}\n\nWhen defined, this value can be used as an identifier within the datasource scope, and\nmay be used as an identifier to update values in a subsequent request",
"type": "string"
},
"thresholds": {
"$ref": "#/definitions/ThresholdsConfig"
},
"unit": {
"description": "Numeric Options",
"type": "string"
},
"value": {
"format": "double",
"type": "number"
},
"writeable": {
"description": "Writeable indicates that the datasource knows how to update this value",
"type": "boolean"
}
},
"title": "QueryStat is used for storing arbitrary statistics metadata related to a query and its result, e.g. total request time, data processing time.",
"type": "object"
},
"Receiver": {
"properties": {
"email_configs": {
@@ -2097,6 +2517,14 @@
},
"type": "object"
},
"Responses": {
"additionalProperties": {
"$ref": "#/definitions/DataResponse"
},
"description": "The QueryData method the QueryDataHandler method will set the RefId\nproperty on the DataResponses' frames based on these RefIDs.",
"title": "Responses is a map of RefIDs (Unique Query ID) to DataResponses.",
"type": "object"
},
"Route": {
"description": "A Route is a node that contains definitions of how to handle alerts. This is modified\nfrom the upstream alertmanager in that it adds the ObjectMatchers property.",
"properties": {
@@ -2650,6 +3078,41 @@
},
"type": "object"
},
"Threshold": {
"description": "Threshold a single step on the threshold list",
"properties": {
"color": {
"type": "string"
},
"state": {
"type": "string"
},
"value": {
"$ref": "#/definitions/ConfFloat64"
}
},
"type": "object"
},
"ThresholdsConfig": {
"description": "ThresholdsConfig setup thresholds",
"properties": {
"mode": {
"$ref": "#/definitions/ThresholdsMode"
},
"steps": {
"description": "Must be sorted by 'value', first value is always -Infinity",
"items": {
"$ref": "#/definitions/Threshold"
},
"type": "array"
}
},
"type": "object"
},
"ThresholdsMode": {
"description": "ThresholdsMode absolute or percentage",
"type": "string"
},
"TimeInterval": {
"description": "TimeInterval describes intervals of time. ContainsTime will tell you if a golang time is contained\nwithin the interval.",
"properties": {
@@ -2751,6 +3214,16 @@
},
"type": "object"
},
"ValueMapping": {
"description": "ValueMapping allows mapping input values to text and color",
"type": "object"
},
"ValueMappings": {
"items": {
"$ref": "#/definitions/ValueMapping"
},
"type": "array"
},
"Vector": {
"description": "Vector is basically only an alias for model.Samples, but the\ncontract is that in a Vector, all Samples have the same timestamp.",
"items": {
@@ -2800,6 +3273,10 @@
"title": "VictorOpsConfig configures notifications via VictorOps.",
"type": "object"
},
"VisType": {
"title": "VisType is used to indicate how the data should be visualized in explore.",
"type": "string"
},
"WebhookConfig": {
"properties": {
"http_config": {
@@ -2929,7 +3406,6 @@
"type": "object"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"items": {
"$ref": "#/definitions/alertGroup"
},
@@ -3037,6 +3513,7 @@
"$ref": "#/definitions/Duration"
},
"gettableAlert": {
"description": "GettableAlert gettable alert",
"properties": {
"annotations": {
"$ref": "#/definitions/labelSet"
@@ -3099,7 +3576,6 @@
"type": "array"
},
"gettableSilence": {
"description": "GettableSilence gettable silence",
"properties": {
"comment": {
"description": "comment",
@@ -3148,6 +3624,7 @@
"type": "object"
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"items": {
"$ref": "#/definitions/gettableSilence"
},
@@ -3296,7 +3773,6 @@
"type": "object"
},
"receiver": {
"description": "Receiver receiver",
"properties": {
"name": {
"description": "name",