Files
grafana/packages/grafana-prometheus/src/migrations/variableMigration.ts
Brendan O'Handley f85470d652 Prometheus: Use the frontend package in Prometheus and remove feature toggle (#86080)
* add history links for monaco completion provider folder

* add history links for monaco query field folder

* add history links for components folder

* add history links for configuration folder

* add history links for dashboard json folder

* add history links for gcopypaste folder

* add history link for variableMigration

* add history link for querybuilder/components/metrics-modal folder

* add history link for querybuilder/components/promqail folder

* add history links for querybuilder/components folder

* add history links for querybuilder/hooks folder

* add history links for querybuilder/shared folder

* add history links for querybuilder folder

* add history links for querycache folder

* add history links for src folder

* use frontend package and custom auth in module.ts

* remove files and fix import issues

* remove usePrometheusFrontendPackage

* remove extra files

* update betterer

* remove extra files after rebase

* fix betterer for rebase

* fix e2e flakiness
2024-04-15 16:45:23 -05:00

139 lines
4.5 KiB
TypeScript

// Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/migrations/variableMigration.ts
import { promQueryModeller } from '../querybuilder/PromQueryModeller';
import { buildVisualQueryFromString } from '../querybuilder/parsing';
import { PromVariableQuery, PromVariableQueryType as QueryType } from '../types';
export const PrometheusLabelNamesRegex = /^label_names\(\)\s*$/;
// Note that this regex is different from the one in metric_find_query.ts because this is used pre-interpolation
export const PrometheusLabelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_$][a-zA-Z0-9_]*)\)\s*$/;
export const PrometheusMetricNamesRegex = /^metrics\((.+)\)\s*$/;
export const PrometheusQueryResultRegex = /^query_result\((.+)\)\s*$/;
export const PrometheusLabelNamesRegexWithMatch = /^label_names\((.+)\)\s*$/;
export function migrateVariableQueryToEditor(rawQuery: string | PromVariableQuery): PromVariableQuery {
// If not string, we assume PromVariableQuery
if (typeof rawQuery !== 'string') {
return rawQuery;
}
const queryBase = {
refId: 'PrometheusDatasource-VariableQuery',
qryType: QueryType.LabelNames,
};
const labelNamesMatchQuery = rawQuery.match(PrometheusLabelNamesRegexWithMatch);
if (labelNamesMatchQuery) {
return {
...queryBase,
qryType: QueryType.LabelNames,
match: labelNamesMatchQuery[1],
};
}
const labelNames = rawQuery.match(PrometheusLabelNamesRegex);
if (labelNames) {
return {
...queryBase,
qryType: QueryType.LabelNames,
};
}
const labelValuesCheck = rawQuery.match(/^label_values\(/);
if (labelValuesCheck) {
const labelValues = rawQuery.match(PrometheusLabelValuesRegex);
const label = labelValues ? labelValues[2] : '';
const metric = labelValues ? labelValues[1] : '';
if (metric) {
const visQuery = buildVisualQueryFromString(metric);
return {
...queryBase,
qryType: QueryType.LabelValues,
label,
metric: visQuery.query.metric,
labelFilters: visQuery.query.labels,
};
} else {
return {
...queryBase,
qryType: QueryType.LabelValues,
label,
};
}
}
const metricNamesCheck = rawQuery.match(/^metrics\(/);
if (metricNamesCheck) {
const metricNames = rawQuery.match(PrometheusMetricNamesRegex);
const metric = metricNames ? metricNames[1] : '';
return {
...queryBase,
qryType: QueryType.MetricNames,
metric,
};
}
const queryResultCheck = rawQuery.match(/^query_result\(/);
if (queryResultCheck) {
const queryResult = rawQuery.match(PrometheusQueryResultRegex);
const varQuery = queryResult ? queryResult[1] : '';
return {
...queryBase,
qryType: QueryType.VarQueryResult,
varQuery,
};
}
// seriesQuery does not have a function and no regex above
if (!labelNames && !labelValuesCheck && !metricNamesCheck && !queryResultCheck) {
return {
...queryBase,
qryType: QueryType.SeriesQuery,
seriesQuery: rawQuery,
};
}
return queryBase;
}
// migrate it back to a string with the correct varialbes in place
export function migrateVariableEditorBackToVariableSupport(QueryVariable: PromVariableQuery): string {
switch (QueryVariable.qryType) {
case QueryType.LabelNames:
if (QueryVariable.match) {
return `label_names(${QueryVariable.match})`;
}
return 'label_names()';
case QueryType.LabelValues:
if (QueryVariable.metric || (QueryVariable.labelFilters && QueryVariable.labelFilters.length !== 0)) {
const visualQueryQuery = {
metric: QueryVariable.metric,
labels: QueryVariable.labelFilters ?? [],
operations: [],
};
const metric = promQueryModeller.renderQuery(visualQueryQuery);
return `label_values(${metric},${QueryVariable.label})`;
} else {
return `label_values(${QueryVariable.label})`;
}
case QueryType.MetricNames:
return `metrics(${QueryVariable.metric})`;
case QueryType.VarQueryResult:
const varQuery = removeLineBreaks(QueryVariable.varQuery);
return `query_result(${varQuery})`;
case QueryType.SeriesQuery:
return QueryVariable.seriesQuery ?? '';
case QueryType.ClassicQuery:
return QueryVariable.classicQuery ?? '';
}
return '';
}
// allow line breaks in query result textarea
function removeLineBreaks(input?: string) {
return input ? input.replace(/[\r\n]+/gm, '') : '';
}