Glue: Correlations minor APIs behavior improvements (#56078)

* add correlation config type, CorrelationConfig validator & default values

* make config required when creating correlations

* make targetUID optional, add validation for createCommand & configType

* fix tests

* update remaining tests

* fix lint error

* Update pkg/services/correlations/models.go

Co-authored-by: Piotr Jamróz <pm.jamroz@gmail.com>

* update docs

Co-authored-by: Piotr Jamróz <pm.jamroz@gmail.com>
This commit is contained in:
Giordano Ricci
2022-10-04 09:39:55 +01:00
committed by GitHub
co-authored by Piotr Jamróz
parent 3381629d3d
commit 489b302c03
11 changed files with 313 additions and 76 deletions
@@ -120,7 +120,12 @@ func TestIntegrationCreateCorrelation(t *testing.T) {
res := ctx.Post(PostParams{
url: fmt.Sprintf("/api/datasources/uid/%s/correlations", "nonexistent-ds-uid"),
body: fmt.Sprintf(`{
"targetUID": "%s"
"targetUID": "%s",
"config": {
"type": "query",
"field": "message",
"target": {}
}
}`, writableDs),
user: adminUser,
})
@@ -139,11 +144,16 @@ func TestIntegrationCreateCorrelation(t *testing.T) {
require.NoError(t, res.Body.Close())
})
t.Run("inexistent target data source should result in a 404", func(t *testing.T) {
t.Run("inexistent target data source should result in a 404 if config.type=query", func(t *testing.T) {
res := ctx.Post(PostParams{
url: fmt.Sprintf("/api/datasources/uid/%s/correlations", writableDs),
body: `{
"targetUID": "nonexistent-uid-uid"
"targetUID": "nonexistent-uid-uid",
"config": {
"type": "query",
"field": "message",
"target": {}
}
}`,
user: adminUser,
})
@@ -166,7 +176,12 @@ func TestIntegrationCreateCorrelation(t *testing.T) {
res := ctx.Post(PostParams{
url: fmt.Sprintf("/api/datasources/uid/%s/correlations", readOnlyDS),
body: fmt.Sprintf(`{
"targetUID": "%s"
"targetUID": "%s",
"config": {
"type": "query",
"field": "message",
"target": {}
}
}`, readOnlyDS),
user: adminUser,
})
@@ -189,7 +204,12 @@ func TestIntegrationCreateCorrelation(t *testing.T) {
res := ctx.Post(PostParams{
url: fmt.Sprintf("/api/datasources/uid/%s/correlations", writableDs),
body: fmt.Sprintf(`{
"targetUID": "%s"
"targetUID": "%s",
"config": {
"type": "query",
"field": "message",
"target": {}
}
}`, readOnlyDS),
user: adminUser,
})
@@ -204,46 +224,18 @@ func TestIntegrationCreateCorrelation(t *testing.T) {
require.Equal(t, "Correlation created", response.Message)
require.Equal(t, writableDs, response.Result.SourceUID)
require.Equal(t, readOnlyDS, response.Result.TargetUID)
require.Equal(t, readOnlyDS, *response.Result.TargetUID)
require.Equal(t, "", response.Result.Description)
require.Equal(t, "", response.Result.Label)
require.NoError(t, res.Body.Close())
})
t.Run("Should correctly create a correlation without a config", func(t *testing.T) {
description := "a description"
label := "a label"
res := ctx.Post(PostParams{
url: fmt.Sprintf("/api/datasources/uid/%s/correlations", writableDs),
body: fmt.Sprintf(`{
"targetUID": "%s",
"description": "%s",
"label": "%s"
}`, writableDs, description, label),
user: adminUser,
})
require.Equal(t, http.StatusOK, res.StatusCode)
responseBody, err := io.ReadAll(res.Body)
require.NoError(t, err)
var response correlations.CreateCorrelationResponseBody
err = json.Unmarshal(responseBody, &response)
require.NoError(t, err)
require.Equal(t, "Correlation created", response.Message)
require.Equal(t, writableDs, response.Result.SourceUID)
require.Equal(t, writableDs, response.Result.TargetUID)
require.Equal(t, description, response.Result.Description)
require.Equal(t, label, response.Result.Label)
require.NoError(t, res.Body.Close())
})
t.Run("Should correctly create a correlation with a correct config", func(t *testing.T) {
description := "a description"
label := "a label"
fieldName := "fieldName"
configType := correlations.ConfigTypeQuery
res := ctx.Post(PostParams{
url: fmt.Sprintf("/api/datasources/uid/%s/correlations", writableDs),
body: fmt.Sprintf(`{
@@ -251,10 +243,11 @@ func TestIntegrationCreateCorrelation(t *testing.T) {
"description": "%s",
"label": "%s",
"config": {
"field": "fieldName",
"type": "%s",
"field": "%s",
"target": { "expr": "foo" }
}
}`, writableDs, description, label),
}`, writableDs, description, label, configType, fieldName),
user: adminUser,
})
require.Equal(t, http.StatusOK, res.StatusCode)
@@ -268,10 +261,11 @@ func TestIntegrationCreateCorrelation(t *testing.T) {
require.Equal(t, "Correlation created", response.Message)
require.Equal(t, writableDs, response.Result.SourceUID)
require.Equal(t, writableDs, response.Result.TargetUID)
require.Equal(t, writableDs, *response.Result.TargetUID)
require.Equal(t, description, response.Result.Description)
require.Equal(t, label, response.Result.Label)
require.Equal(t, "fieldName", response.Result.Config.Field)
require.Equal(t, configType, response.Result.Config.Type)
require.Equal(t, fieldName, response.Result.Config.Field)
require.Equal(t, map[string]interface{}{"expr": "foo"}, response.Result.Config.Target)
require.NoError(t, res.Body.Close())
@@ -305,4 +299,62 @@ func TestIntegrationCreateCorrelation(t *testing.T) {
require.NoError(t, res.Body.Close())
})
t.Run("Should not create a correlation without a config", func(t *testing.T) {
description := "a description"
label := "a label"
res := ctx.Post(PostParams{
url: fmt.Sprintf("/api/datasources/uid/%s/correlations", writableDs),
body: fmt.Sprintf(`{
"targetUID": "%s",
"description": "%s",
"label": "%s"
}`, writableDs, description, label),
user: adminUser,
})
require.Equal(t, http.StatusBadRequest, res.StatusCode)
responseBody, err := io.ReadAll(res.Body)
require.NoError(t, err)
var response errorResponseBody
err = json.Unmarshal(responseBody, &response)
require.NoError(t, err)
require.Contains(t, response.Message, "bad request data")
require.NoError(t, res.Body.Close())
})
t.Run("Should not create a correlation with an invalid config type", func(t *testing.T) {
description := "a description"
label := "a label"
configType := "nonexistent-config-type"
res := ctx.Post(PostParams{
url: fmt.Sprintf("/api/datasources/uid/%s/correlations", writableDs),
body: fmt.Sprintf(`{
"targetUID": "%s",
"description": "%s",
"label": "%s",
"config": {
"type": "%s"
}
}`, writableDs, description, label, configType),
user: adminUser,
})
require.Equal(t, http.StatusBadRequest, res.StatusCode)
responseBody, err := io.ReadAll(res.Body)
require.NoError(t, err)
var response errorResponseBody
err = json.Unmarshal(responseBody, &response)
require.NoError(t, err)
require.Contains(t, response.Message, "bad request data")
require.Contains(t, response.Error, correlations.ErrInvalidConfigType.Error())
require.Contains(t, response.Error, configType)
require.NoError(t, res.Body.Close())
})
}
@@ -159,7 +159,7 @@ func TestIntegrationDeleteCorrelation(t *testing.T) {
t.Run("deleting a correlation pointing to a read-only data source should work", func(t *testing.T) {
correlation := ctx.createCorrelation(correlations.CreateCorrelationCommand{
SourceUID: writableDs,
TargetUID: writableDs,
TargetUID: &writableDs,
OrgId: writableDsOrgId,
})
@@ -191,7 +191,7 @@ func TestIntegrationDeleteCorrelation(t *testing.T) {
t.Run("should correctly delete a correlation", func(t *testing.T) {
correlation := ctx.createCorrelation(correlations.CreateCorrelationCommand{
SourceUID: writableDs,
TargetUID: readOnlyDS,
TargetUID: &readOnlyDS,
OrgId: writableDsOrgId,
})
@@ -73,9 +73,10 @@ func TestIntegrationReadCorrelation(t *testing.T) {
dsWithCorrelations := createDsCommand.Result
correlation := ctx.createCorrelation(correlations.CreateCorrelationCommand{
SourceUID: dsWithCorrelations.Uid,
TargetUID: dsWithCorrelations.Uid,
TargetUID: &dsWithCorrelations.Uid,
OrgId: dsWithCorrelations.OrgId,
Config: correlations.CorrelationConfig{
Type: correlations.ConfigTypeQuery,
Field: "foo",
Target: map[string]interface{}{},
},
@@ -92,17 +93,18 @@ func TestIntegrationReadCorrelation(t *testing.T) {
// This creates 2 records in the correlation table that should never be returned by the API.
// Given all tests in this file work on the assumption that only a single correlation exists,
// this covers the case where bad data exists in the database.
nonExistingDsUID := "THIS-DOES-NOT_EXIST"
err := ctx.env.SQLStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
created, err := sess.InsertMulti(&[]correlations.Correlation{
{
UID: "uid-1",
SourceUID: dsWithoutCorrelations.Uid,
TargetUID: "THIS-DOES-NOT_EXIST",
TargetUID: &nonExistingDsUID,
},
{
UID: "uid-2",
SourceUID: "THIS-DOES-NOT_EXIST",
TargetUID: dsWithoutCorrelations.Uid,
TargetUID: &dsWithoutCorrelations.Uid,
},
})
require.Equal(t, int64(2), created)
@@ -165,7 +165,7 @@ func TestIntegrationUpdateCorrelation(t *testing.T) {
t.Run("updating a without data should result in a 400", func(t *testing.T) {
correlation := ctx.createCorrelation(correlations.CreateCorrelationCommand{
SourceUID: writableDs,
TargetUID: writableDs,
TargetUID: &writableDs,
OrgId: writableDsOrgId,
})
@@ -231,7 +231,7 @@ func TestIntegrationUpdateCorrelation(t *testing.T) {
t.Run("updating a correlation pointing to a read-only data source should work", func(t *testing.T) {
correlation := ctx.createCorrelation(correlations.CreateCorrelationCommand{
SourceUID: writableDs,
TargetUID: writableDs,
TargetUID: &writableDs,
OrgId: writableDsOrgId,
Label: "a label",
})
@@ -260,7 +260,7 @@ func TestIntegrationUpdateCorrelation(t *testing.T) {
t.Run("should correctly update correlations", func(t *testing.T) {
correlation := ctx.createCorrelation(correlations.CreateCorrelationCommand{
SourceUID: writableDs,
TargetUID: writableDs,
TargetUID: &writableDs,
OrgId: writableDsOrgId,
Label: "0",
Description: "0",