mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
@@ -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: {},
|
||||
|
||||
@@ -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} />;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'>;
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user