Correlations: Allow creating correlations for provisioned data sources (#73737)

* Allow creating correlations for provisioned data sources

* Update docs

* Fix linting

* Add missing props

* Add missing props

* Fix linting

* Fix linting

* Clarify error name

* Removed error handling for a non-existing use case

* Create a list of deleted data datasources based on all configs

* Add org_id to correlations

* Add tests

* Allow org_id to be null in case org_id=0 is used

* Create organization to ensure stable id is generated

* Fix linting

* Ensure backwards compatibility

* Add deprecation information

* Update comments

* Override existing datasSource variable so the UID is retrieved correctly

* Migrate correlations indices

* Default org_id when migrating

* Remove redundant default

* Make PK non-nullable

* Post merge fixes

* Separate data sources / correlations provisioning

* Adjust comments

* Store new data sources in spy store so it can be used to test correlations as well

* Fix linting

* Update tests

* Ensure response is closed

* Avoid creating duplicates during provisioning

* Fix updating provisioned column and update tests

* Rename error message

* Fix linting errors

* Fix linting errors and rename variable

* Update test

* Update pkg/services/sqlstore/migrations/correlations_mig.go

Co-authored-by: Giordano Ricci <me@giordanoricci.com>

* Remove unused error

* Fix lining

---------

Co-authored-by: Giordano Ricci <me@giordanoricci.com>
This commit is contained in:
Piotr Jamróz
2023-09-13 15:10:09 +02:00
committed by GitHub
parent 38c3483594
commit 946da57b6a
21 changed files with 464 additions and 158 deletions

View File

@@ -47,7 +47,7 @@ const renderWithContext = async (
const matches = url.match(/^\/api\/datasources\/uid\/(?<sourceUID>[a-zA-Z0-9]+)\/correlations$/);
if (matches?.groups) {
const { sourceUID } = matches.groups;
const correlation = { sourceUID, ...data, uid: uniqueId() };
const correlation = { sourceUID, ...data, uid: uniqueId(), provisioned: false };
correlations.push(correlation);
return createCreateCorrelationResponse(correlation);
}
@@ -66,7 +66,7 @@ const renderWithContext = async (
}
return c;
});
return createUpdateCorrelationResponse({ sourceUID, ...data, uid: uniqueId() });
return createUpdateCorrelationResponse({ sourceUID, ...data, uid: uniqueId(), provisioned: false });
}
throw createFetchCorrelationsError();
@@ -358,6 +358,7 @@ describe('CorrelationsPage', () => {
targetUID: 'loki',
uid: '1',
label: 'Some label',
provisioned: false,
config: {
field: 'line',
target: {},
@@ -373,6 +374,7 @@ describe('CorrelationsPage', () => {
uid: '2',
label: 'Prometheus to Loki',
config: { field: 'label', target: {}, type: 'query' },
provisioned: false,
},
]
);
@@ -580,6 +582,7 @@ describe('CorrelationsPage', () => {
targetUID: 'loki',
uid: '1',
label: 'Loki to Loki',
provisioned: false,
config: {
field: 'line',
target: {},
@@ -594,6 +597,7 @@ describe('CorrelationsPage', () => {
targetUID: 'prometheus',
uid: '2',
label: 'Loki to Prometheus',
provisioned: false,
config: {
field: 'line',
target: {},
@@ -609,6 +613,7 @@ describe('CorrelationsPage', () => {
uid: '3',
label: 'Prometheus to Loki',
config: { field: 'label', target: {}, type: 'query' },
provisioned: false,
},
{
sourceUID: 'prometheus',
@@ -616,6 +621,7 @@ describe('CorrelationsPage', () => {
uid: '4',
label: 'Prometheus to Prometheus',
config: { field: 'label', target: {}, type: 'query' },
provisioned: false,
},
]
);
@@ -638,6 +644,7 @@ describe('CorrelationsPage', () => {
targetUID: 'loki',
uid: '1',
label: 'Some label',
provisioned: true,
config: {
field: 'line',
target: {},

View File

@@ -32,7 +32,7 @@ import { CorrelationData, useCorrelations } from './useCorrelations';
const sortDatasource: SortByFn<CorrelationData> = (a, b, column) =>
a.values[column].name.localeCompare(b.values[column].name);
const isSourceReadOnly = ({ source }: Pick<CorrelationData, 'source'>) => source.readOnly;
const isCorrelationsReadOnly = (correlation: CorrelationData) => correlation.provisioned;
const loaderWrapper = css`
display: flex;
@@ -91,13 +91,14 @@ export default function CorrelationsPage() {
row: {
index,
original: {
source: { uid: sourceUID, readOnly },
source: { uid: sourceUID },
provisioned,
uid,
},
},
}: CellProps<CorrelationData, void>) => {
return (
!readOnly && (
!provisioned && (
<DeleteButton
aria-label="delete correlation"
onConfirm={() =>
@@ -118,7 +119,7 @@ export default function CorrelationsPage() {
id: 'info',
cell: InfoCell,
disableGrow: true,
visible: (data) => data.some(isSourceReadOnly),
visible: (data) => data.some(isCorrelationsReadOnly),
},
{
id: 'source',
@@ -137,7 +138,7 @@ export default function CorrelationsPage() {
id: 'actions',
cell: RowActions,
disableGrow: true,
visible: (data) => canWriteCorrelations && data.some(negate(isSourceReadOnly)),
visible: (data) => canWriteCorrelations && data.some(negate(isCorrelationsReadOnly)),
},
],
[RowActions, canWriteCorrelations]
@@ -195,7 +196,7 @@ export default function CorrelationsPage() {
<ExpendedRow
correlation={correlation}
onUpdated={handleUpdated}
readOnly={isSourceReadOnly({ source: correlation.source }) || !canWriteCorrelations}
readOnly={isCorrelationsReadOnly(correlation) || !canWriteCorrelations}
/>
)}
columns={columns}
@@ -275,7 +276,7 @@ const noWrap = css`
const InfoCell = memo(
function InfoCell({ ...props }: CellProps<CorrelationData, void>) {
const readOnly = props.row.original.source.readOnly;
const readOnly = props.row.original.provisioned;
if (readOnly) {
return <Badge text="Read only" color="purple" className={noWrap} />;

View File

@@ -49,10 +49,6 @@ export const ConfigureCorrelationSourceForm = () => {
name="sourceUID"
rules={{
required: { value: true, message: 'This field is required.' },
validate: {
writable: (uid: string) =>
!getDatasourceSrv().getInstanceSettings(uid)?.readOnly || "Source can't be a read-only data source.",
},
}}
render={({ field: { onChange, value } }) => (
<Field

View File

@@ -41,6 +41,7 @@ export interface Correlation {
targetUID: string;
label?: string;
description?: string;
provisioned: boolean;
config: CorrelationConfig;
}
@@ -49,5 +50,5 @@ export type GetCorrelationsParams = {
};
export type RemoveCorrelationParams = Pick<Correlation, 'sourceUID' | 'uid'>;
export type CreateCorrelationParams = Omit<Correlation, 'uid'>;
export type UpdateCorrelationParams = Omit<Correlation, 'targetUID'>;
export type CreateCorrelationParams = Omit<Correlation, 'uid' | 'provisioned'>;
export type UpdateCorrelationParams = Omit<Correlation, 'targetUID' | 'provisioned'>;

View File

@@ -110,6 +110,7 @@ function setup() {
source: loki,
target: prometheus,
config: { type: 'query', field: 'traceId', target: { expr: 'target Prometheus query' } },
provisioned: false,
},
// Test multiple correlations attached to the same field
{
@@ -118,6 +119,7 @@ function setup() {
source: loki,
target: elastic,
config: { type: 'query', field: 'traceId', target: { expr: 'target Elastic query' } },
provisioned: false,
},
{
uid: 'prometheus-to-elastic',
@@ -125,6 +127,7 @@ function setup() {
source: prometheus,
target: elastic,
config: { type: 'query', field: 'value', target: { expr: 'target Elastic query' } },
provisioned: false,
},
];