mirror of https://github.com/grafana/grafana
Revert "Schema V2: Simplify annotations v1<->v2 conversions" (#107984)
Revert "Schema V2: Simplify annotations v1<->v2 conversions (#107390)"
This reverts commit d5a1781fb6
.
pull/107986/head
parent
15e59a0ca7
commit
2b8c5bea1a
@ -1,257 +0,0 @@ |
|||||||
{ |
|
||||||
"kind": "Dashboard", |
|
||||||
"apiVersion": "dashboard.grafana.app/v1beta1", |
|
||||||
"metadata": { |
|
||||||
"name": "test-v1-annotations", |
|
||||||
"annotations": { |
|
||||||
"hello": "world" |
|
||||||
}, |
|
||||||
"labels": { |
|
||||||
"region": "west" |
|
||||||
} |
|
||||||
}, |
|
||||||
"spec": { |
|
||||||
"annotations": { |
|
||||||
"list": [ |
|
||||||
{ |
|
||||||
"builtIn": 1, |
|
||||||
"datasource": { |
|
||||||
"type": "grafana", |
|
||||||
"uid": "-- Grafana --" |
|
||||||
}, |
|
||||||
"enable": true, |
|
||||||
"hide": false, |
|
||||||
"iconColor": "rgba(0, 211, 255, 1)", |
|
||||||
"name": "Annotations & Alerts", |
|
||||||
"target": { |
|
||||||
"limit": 100, |
|
||||||
"matchAny": false, |
|
||||||
"tags": [], |
|
||||||
"type": "dashboard" |
|
||||||
}, |
|
||||||
"type": "dashboard" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"datasource": { |
|
||||||
"type": "grafana-testdata-datasource", |
|
||||||
"uid": "PD8C576611E62080A" |
|
||||||
}, |
|
||||||
"enable": true, |
|
||||||
"hide": false, |
|
||||||
"iconColor": "blue", |
|
||||||
"name": "testdata-annos", |
|
||||||
"target": { |
|
||||||
"lines": 10, |
|
||||||
"refId": "Anno", |
|
||||||
"scenarioId": "annotations" |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"enable": true, |
|
||||||
"hide": false, |
|
||||||
"iconColor": "blue", |
|
||||||
"name": "no-ds-testdata-annos", |
|
||||||
"target": { |
|
||||||
"lines": 10, |
|
||||||
"refId": "Anno", |
|
||||||
"scenarioId": "annotations" |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"datasource": { |
|
||||||
"type": "prometheus", |
|
||||||
"uid": "gdev-prometheus" |
|
||||||
}, |
|
||||||
"enable": true, |
|
||||||
"hide": false, |
|
||||||
"iconColor": "yellow", |
|
||||||
"name": "prom-annos", |
|
||||||
"target": { |
|
||||||
"expr": "{action=\"add_client\"}", |
|
||||||
"interval": "", |
|
||||||
"lines": 10, |
|
||||||
"refId": "Anno", |
|
||||||
"scenarioId": "annotations" |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"enable": true, |
|
||||||
"hide": false, |
|
||||||
"iconColor": "yellow", |
|
||||||
"name": "no-ds-prom-annos", |
|
||||||
"target": { |
|
||||||
"expr": "{action=\"add_client\"}", |
|
||||||
"interval": "", |
|
||||||
"lines": 10, |
|
||||||
"refId": "Anno", |
|
||||||
"scenarioId": "annotations" |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"datasource": { |
|
||||||
"type": "grafana-postgresql-datasource", |
|
||||||
"uid": "PBBCEC2D313BC06C3" |
|
||||||
}, |
|
||||||
"enable": true, |
|
||||||
"hide": false, |
|
||||||
"iconColor": "red", |
|
||||||
"name": "postgress-annos", |
|
||||||
"target": { |
|
||||||
"editorMode": "builder", |
|
||||||
"format": "table", |
|
||||||
"lines": 10, |
|
||||||
"rawSql": "", |
|
||||||
"refId": "Anno", |
|
||||||
"scenarioId": "annotations", |
|
||||||
"sql": { |
|
||||||
"columns": [ |
|
||||||
{ |
|
||||||
"parameters": [], |
|
||||||
"type": "function" |
|
||||||
} |
|
||||||
], |
|
||||||
"groupBy": [ |
|
||||||
{ |
|
||||||
"property": { |
|
||||||
"type": "string" |
|
||||||
}, |
|
||||||
"type": "groupBy" |
|
||||||
} |
|
||||||
], |
|
||||||
"limit": 50 |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"datasource": { |
|
||||||
"type": "elasticsearch", |
|
||||||
"uid": "gdev-elasticsearch" |
|
||||||
}, |
|
||||||
"enable": true, |
|
||||||
"hide": false, |
|
||||||
"iconColor": "red", |
|
||||||
"name": "elastic - annos", |
|
||||||
"tagsField": "asd", |
|
||||||
"target": { |
|
||||||
"lines": 10, |
|
||||||
"query": "test query", |
|
||||||
"refId": "Anno", |
|
||||||
"scenarioId": "annotations" |
|
||||||
}, |
|
||||||
"textField": "asd", |
|
||||||
"timeEndField": "asdas", |
|
||||||
"timeField": "asd" |
|
||||||
} |
|
||||||
] |
|
||||||
}, |
|
||||||
"editable": true, |
|
||||||
"fiscalYearStartMonth": 0, |
|
||||||
"graphTooltip": 0, |
|
||||||
"links": [], |
|
||||||
"panels": [ |
|
||||||
{ |
|
||||||
"datasource": { |
|
||||||
"type": "grafana-testdata-datasource", |
|
||||||
"uid": "PD8C576611E62080A" |
|
||||||
}, |
|
||||||
"fieldConfig": { |
|
||||||
"defaults": { |
|
||||||
"color": { |
|
||||||
"mode": "palette-classic" |
|
||||||
}, |
|
||||||
"custom": { |
|
||||||
"axisBorderShow": false, |
|
||||||
"axisCenteredZero": false, |
|
||||||
"axisColorMode": "text", |
|
||||||
"axisLabel": "", |
|
||||||
"axisPlacement": "auto", |
|
||||||
"barAlignment": 0, |
|
||||||
"barWidthFactor": 0.6, |
|
||||||
"drawStyle": "line", |
|
||||||
"fillOpacity": 0, |
|
||||||
"gradientMode": "none", |
|
||||||
"hideFrom": { |
|
||||||
"legend": false, |
|
||||||
"tooltip": false, |
|
||||||
"viz": false |
|
||||||
}, |
|
||||||
"insertNulls": false, |
|
||||||
"lineInterpolation": "linear", |
|
||||||
"lineWidth": 1, |
|
||||||
"pointSize": 5, |
|
||||||
"scaleDistribution": { |
|
||||||
"type": "linear" |
|
||||||
}, |
|
||||||
"showPoints": "auto", |
|
||||||
"spanNulls": false, |
|
||||||
"stacking": { |
|
||||||
"group": "A", |
|
||||||
"mode": "none" |
|
||||||
}, |
|
||||||
"thresholdsStyle": { |
|
||||||
"mode": "off" |
|
||||||
} |
|
||||||
}, |
|
||||||
"mappings": [], |
|
||||||
"thresholds": { |
|
||||||
"mode": "absolute", |
|
||||||
"steps": [ |
|
||||||
{ |
|
||||||
"color": "green", |
|
||||||
"value": 0 |
|
||||||
}, |
|
||||||
{ |
|
||||||
"color": "red", |
|
||||||
"value": 80 |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
||||||
}, |
|
||||||
"overrides": [] |
|
||||||
}, |
|
||||||
"gridPos": { |
|
||||||
"h": 8, |
|
||||||
"w": 12, |
|
||||||
"x": 0, |
|
||||||
"y": 0 |
|
||||||
}, |
|
||||||
"id": 1, |
|
||||||
"options": { |
|
||||||
"legend": { |
|
||||||
"calcs": [], |
|
||||||
"displayMode": "list", |
|
||||||
"placement": "bottom", |
|
||||||
"showLegend": true |
|
||||||
}, |
|
||||||
"tooltip": { |
|
||||||
"hideZeros": false, |
|
||||||
"mode": "single", |
|
||||||
"sort": "none" |
|
||||||
} |
|
||||||
}, |
|
||||||
"pluginVersion": "12.1.0-pre", |
|
||||||
"targets": [ |
|
||||||
{ |
|
||||||
"refId": "A" |
|
||||||
} |
|
||||||
], |
|
||||||
"title": "New panel", |
|
||||||
"type": "timeseries" |
|
||||||
} |
|
||||||
], |
|
||||||
"preload": false, |
|
||||||
"schemaVersion": 41, |
|
||||||
"tags": [], |
|
||||||
"templating": { |
|
||||||
"list": [] |
|
||||||
}, |
|
||||||
"time": { |
|
||||||
"from": "now-6h", |
|
||||||
"to": "now" |
|
||||||
}, |
|
||||||
"timepicker": {}, |
|
||||||
"timezone": "browser", |
|
||||||
"title": "Test: V1 dashboard with annotations", |
|
||||||
"version": 8 |
|
||||||
} |
|
||||||
} |
|
@ -1,226 +0,0 @@ |
|||||||
import { AnnotationQuery } from '@grafana/data'; |
|
||||||
import { AnnotationQueryKind } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha1/types.spec.gen'; |
|
||||||
|
|
||||||
import { transformV1ToV2AnnotationQuery, transformV2ToV1AnnotationQuery } from './annotations'; |
|
||||||
|
|
||||||
describe('V1<->V2 annotation convertions', () => { |
|
||||||
test('given grafana-built in annotations', () => { |
|
||||||
// test case
|
|
||||||
const annotationDefinition: AnnotationQuery = { |
|
||||||
builtIn: 1, |
|
||||||
datasource: { |
|
||||||
type: 'grafana', |
|
||||||
uid: 'grafana', |
|
||||||
}, |
|
||||||
enable: true, |
|
||||||
hide: false, |
|
||||||
iconColor: 'yellow', |
|
||||||
name: 'Annotations \u0026 Alerts', |
|
||||||
target: { |
|
||||||
// @ts-expect-error
|
|
||||||
limit: 100, |
|
||||||
matchAny: false, |
|
||||||
tags: [], |
|
||||||
type: 'dashboard', |
|
||||||
}, |
|
||||||
type: 'dashboard', |
|
||||||
}; |
|
||||||
|
|
||||||
const expectedV2: AnnotationQueryKind = { |
|
||||||
kind: 'AnnotationQuery', |
|
||||||
spec: { |
|
||||||
builtIn: true, |
|
||||||
enable: true, |
|
||||||
hide: false, |
|
||||||
iconColor: 'yellow', |
|
||||||
name: 'Annotations \u0026 Alerts', |
|
||||||
query: { |
|
||||||
kind: 'DataQuery', |
|
||||||
group: 'grafana', |
|
||||||
version: 'v0', |
|
||||||
datasource: { |
|
||||||
name: 'grafana', |
|
||||||
}, |
|
||||||
spec: { |
|
||||||
limit: 100, |
|
||||||
matchAny: false, |
|
||||||
tags: [], |
|
||||||
type: 'dashboard', |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
const resultV2: AnnotationQueryKind = transformV1ToV2AnnotationQuery(annotationDefinition, 'grafana', 'grafana'); |
|
||||||
|
|
||||||
expect(resultV2).toEqual(expectedV2); |
|
||||||
|
|
||||||
const resultV1: AnnotationQuery = transformV2ToV1AnnotationQuery(expectedV2); |
|
||||||
expect(resultV1).toEqual(annotationDefinition); |
|
||||||
}); |
|
||||||
|
|
||||||
test('given annotations with datasource', () => { |
|
||||||
const annotationDefinition = { |
|
||||||
datasource: { |
|
||||||
type: 'grafana-testdata-datasource', |
|
||||||
uid: 'uid', |
|
||||||
}, |
|
||||||
enable: true, |
|
||||||
hide: false, |
|
||||||
iconColor: 'blue', |
|
||||||
name: 'testdata-annos', |
|
||||||
target: { |
|
||||||
lines: 10, |
|
||||||
refId: 'Anno', |
|
||||||
scenarioId: 'annotations', |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
const expectedV2: AnnotationQueryKind = { |
|
||||||
kind: 'AnnotationQuery', |
|
||||||
spec: { |
|
||||||
enable: true, |
|
||||||
hide: false, |
|
||||||
iconColor: 'blue', |
|
||||||
name: 'testdata-annos', |
|
||||||
builtIn: false, |
|
||||||
query: { |
|
||||||
kind: 'DataQuery', |
|
||||||
group: 'grafana-testdata-datasource', |
|
||||||
version: 'v0', |
|
||||||
datasource: { |
|
||||||
name: 'uid', |
|
||||||
}, |
|
||||||
spec: { |
|
||||||
lines: 10, |
|
||||||
refId: 'Anno', |
|
||||||
scenarioId: 'annotations', |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
const resultV2: AnnotationQueryKind = transformV1ToV2AnnotationQuery( |
|
||||||
annotationDefinition, |
|
||||||
'grafana-testdata-datasource', |
|
||||||
'uid' |
|
||||||
); |
|
||||||
|
|
||||||
expect(resultV2).toEqual(expectedV2); |
|
||||||
|
|
||||||
const resultV1: AnnotationQuery = transformV2ToV1AnnotationQuery(expectedV2); |
|
||||||
expect(resultV1).toEqual(annotationDefinition); |
|
||||||
}); |
|
||||||
|
|
||||||
test('given annotations with target', () => { |
|
||||||
const annotationDefinition = { |
|
||||||
datasource: { |
|
||||||
type: 'prometheus', |
|
||||||
uid: 'uid', |
|
||||||
}, |
|
||||||
enable: true, |
|
||||||
hide: false, |
|
||||||
iconColor: 'yellow', |
|
||||||
name: 'prom-annos', |
|
||||||
target: { |
|
||||||
expr: '{action="add_client"}', |
|
||||||
interval: '', |
|
||||||
lines: 10, |
|
||||||
refId: 'Anno', |
|
||||||
scenarioId: 'annotations', |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
const expectedV2: AnnotationQueryKind = { |
|
||||||
kind: 'AnnotationQuery', |
|
||||||
spec: { |
|
||||||
enable: true, |
|
||||||
hide: false, |
|
||||||
iconColor: 'yellow', |
|
||||||
name: 'prom-annos', |
|
||||||
builtIn: false, |
|
||||||
query: { |
|
||||||
kind: 'DataQuery', |
|
||||||
group: 'prometheus', |
|
||||||
version: 'v0', |
|
||||||
datasource: { |
|
||||||
name: 'uid', |
|
||||||
}, |
|
||||||
spec: { |
|
||||||
expr: '{action="add_client"}', |
|
||||||
interval: '', |
|
||||||
lines: 10, |
|
||||||
refId: 'Anno', |
|
||||||
scenarioId: 'annotations', |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
const resultV2: AnnotationQueryKind = transformV1ToV2AnnotationQuery(annotationDefinition, 'prometheus', 'uid'); |
|
||||||
expect(resultV2).toEqual(expectedV2); |
|
||||||
|
|
||||||
const resultV1: AnnotationQuery = transformV2ToV1AnnotationQuery(expectedV2); |
|
||||||
expect(resultV1).toEqual(annotationDefinition); |
|
||||||
}); |
|
||||||
|
|
||||||
test('given annotations with non-schematised options / legacyOptions', () => { |
|
||||||
const annotationDefinition = { |
|
||||||
datasource: { |
|
||||||
type: 'elasticsearch', |
|
||||||
uid: 'uid', |
|
||||||
}, |
|
||||||
enable: true, |
|
||||||
hide: false, |
|
||||||
iconColor: 'red', |
|
||||||
name: 'elastic - annos', |
|
||||||
tagsField: 'asd', |
|
||||||
target: { |
|
||||||
lines: 10, |
|
||||||
query: 'test query', |
|
||||||
refId: 'Anno', |
|
||||||
scenarioId: 'annotations', |
|
||||||
}, |
|
||||||
textField: 'asd', |
|
||||||
timeEndField: 'asdas', |
|
||||||
timeField: 'asd', |
|
||||||
}; |
|
||||||
|
|
||||||
const expectedV2: AnnotationQueryKind = { |
|
||||||
kind: 'AnnotationQuery', |
|
||||||
spec: { |
|
||||||
enable: true, |
|
||||||
hide: false, |
|
||||||
iconColor: 'red', |
|
||||||
name: 'elastic - annos', |
|
||||||
builtIn: false, |
|
||||||
query: { |
|
||||||
kind: 'DataQuery', |
|
||||||
group: 'elasticsearch', |
|
||||||
version: 'v0', |
|
||||||
datasource: { |
|
||||||
name: 'uid', |
|
||||||
}, |
|
||||||
spec: { |
|
||||||
lines: 10, |
|
||||||
query: 'test query', |
|
||||||
refId: 'Anno', |
|
||||||
scenarioId: 'annotations', |
|
||||||
}, |
|
||||||
}, |
|
||||||
legacyOptions: { |
|
||||||
tagsField: 'asd', |
|
||||||
textField: 'asd', |
|
||||||
timeEndField: 'asdas', |
|
||||||
timeField: 'asd', |
|
||||||
}, |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
const resultV2: AnnotationQueryKind = transformV1ToV2AnnotationQuery(annotationDefinition, 'elasticsearch', 'uid'); |
|
||||||
expect(resultV2).toEqual(expectedV2); |
|
||||||
|
|
||||||
const resultV1: AnnotationQuery = transformV2ToV1AnnotationQuery(expectedV2); |
|
||||||
expect(resultV1).toEqual(annotationDefinition); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,118 +0,0 @@ |
|||||||
import { AnnotationQuery } from '@grafana/data'; |
|
||||||
import { |
|
||||||
AnnotationQueryKind, |
|
||||||
defaultDataQueryKind, |
|
||||||
} from '@grafana/schema/dist/esm/schema/dashboard/v2alpha1/types.spec.gen'; |
|
||||||
|
|
||||||
import { getRuntimePanelDataSource } from './layoutSerializers/utils'; |
|
||||||
|
|
||||||
export function transformV1ToV2AnnotationQuery( |
|
||||||
annotation: AnnotationQuery, |
|
||||||
|
|
||||||
dsType: string, |
|
||||||
dsUID?: string, |
|
||||||
// Overrides are used to provide properties based on scene's annotations data layer object state
|
|
||||||
override?: Partial<AnnotationQuery> |
|
||||||
): AnnotationQueryKind { |
|
||||||
const group = annotation.builtIn ? 'grafana' : dsType; |
|
||||||
|
|
||||||
const { |
|
||||||
// known properties documented in v1 schema
|
|
||||||
enable, |
|
||||||
hide, |
|
||||||
iconColor, |
|
||||||
name, |
|
||||||
builtIn, |
|
||||||
filter, |
|
||||||
mappings, |
|
||||||
datasource, |
|
||||||
target, |
|
||||||
snapshotData, |
|
||||||
type, |
|
||||||
|
|
||||||
// unknown properties that are still available for configuration through API
|
|
||||||
...legacyOptions |
|
||||||
} = annotation; |
|
||||||
|
|
||||||
const result: AnnotationQueryKind = { |
|
||||||
kind: 'AnnotationQuery', |
|
||||||
spec: { |
|
||||||
builtIn: Boolean(annotation.builtIn), |
|
||||||
name: annotation.name, |
|
||||||
enable: Boolean(override?.enable) || Boolean(annotation.enable), |
|
||||||
hide: Boolean(override?.hide) || Boolean(annotation.hide), |
|
||||||
iconColor: annotation.iconColor, |
|
||||||
|
|
||||||
query: { |
|
||||||
kind: 'DataQuery', |
|
||||||
version: defaultDataQueryKind().version, |
|
||||||
group, // Annotation layer has a datasource type provided in runtime.
|
|
||||||
spec: target || {}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
if (dsUID) { |
|
||||||
result.spec.query.datasource = { |
|
||||||
name: dsUID, |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
// if legacy options is not an empty object, add it to the result
|
|
||||||
if (Object.keys(legacyOptions).length > 0) { |
|
||||||
result.spec.legacyOptions = legacyOptions; |
|
||||||
} |
|
||||||
|
|
||||||
if (annotation.filter?.ids?.length) { |
|
||||||
result.spec.filter = annotation.filter; |
|
||||||
} |
|
||||||
|
|
||||||
// TODO: add mappings
|
|
||||||
|
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
export function transformV2ToV1AnnotationQuery(annotation: AnnotationQueryKind): AnnotationQuery { |
|
||||||
let { query: dataQuery, ...annotationQuery } = annotation.spec; |
|
||||||
|
|
||||||
// Mapping from AnnotationQueryKind to AnnotationQuery used by scenes.
|
|
||||||
let annoQuerySpec: AnnotationQuery = { |
|
||||||
enable: annotation.spec.enable, |
|
||||||
hide: annotation.spec.hide, |
|
||||||
iconColor: annotation.spec.iconColor, |
|
||||||
name: annotation.spec.name, |
|
||||||
// TOOO: mappings
|
|
||||||
}; |
|
||||||
|
|
||||||
if (Object.keys(dataQuery.spec).length > 0) { |
|
||||||
// @ts-expect-error DataQueryKind spec should be typed as DataQuery interface
|
|
||||||
annoQuerySpec.target = { |
|
||||||
...dataQuery?.spec, |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
if (annotation.spec.builtIn) { |
|
||||||
annoQuerySpec.type = 'dashboard'; |
|
||||||
annoQuerySpec.builtIn = 1; |
|
||||||
} |
|
||||||
|
|
||||||
if (annotation.spec.filter) { |
|
||||||
annoQuerySpec.filter = annotation.spec.filter; |
|
||||||
} |
|
||||||
|
|
||||||
// some annotations will contain in the legacyOptions properties that need to be
|
|
||||||
// added to the root level AnnotationQuery
|
|
||||||
if (annotationQuery.legacyOptions) { |
|
||||||
annoQuerySpec = { |
|
||||||
...annoQuerySpec, |
|
||||||
...annotationQuery.legacyOptions, |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
// get data source from annotation query
|
|
||||||
const datasource = getRuntimePanelDataSource(dataQuery); |
|
||||||
|
|
||||||
annoQuerySpec.datasource = datasource; |
|
||||||
|
|
||||||
return annoQuerySpec; |
|
||||||
} |
|
Loading…
Reference in new issue