mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Correlations: Make correlations work with provisioning
This commit is contained in:
parent
14b3043c28
commit
eb9affc7e3
@ -247,6 +247,13 @@ datasources:
|
||||
access: proxy
|
||||
url: http://localhost:3100
|
||||
editable: false
|
||||
correlations:
|
||||
- targetUid: gdev-jaeger
|
||||
label: "Jaeger traces"
|
||||
description: "Related traces stored in Jaeger"
|
||||
- targetUid: gdev-zipkin
|
||||
label: "Zipkin traces"
|
||||
description: "Related traces stored in Zipkin"
|
||||
jsonData:
|
||||
manageAlerts: false
|
||||
derivedFields:
|
||||
|
@ -101,6 +101,7 @@ type AddDataSourceCommand struct {
|
||||
BasicAuthUser string `json:"basicAuthUser"`
|
||||
WithCredentials bool `json:"withCredentials"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Correlations []Correlation `json:"-"`
|
||||
JsonData *simplejson.Json `json:"jsonData"`
|
||||
SecureJsonData map[string]string `json:"secureJsonData"`
|
||||
Uid string `json:"uid"`
|
||||
@ -126,6 +127,7 @@ type UpdateDataSourceCommand struct {
|
||||
BasicAuthUser string `json:"basicAuthUser"`
|
||||
WithCredentials bool `json:"withCredentials"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Correlations []Correlation `json:"correlations"`
|
||||
JsonData *simplejson.Json `json:"jsonData"`
|
||||
SecureJsonData map[string]string `json:"secureJsonData"`
|
||||
Version int `json:"version"`
|
||||
|
@ -42,6 +42,7 @@ type upsertDataSourceFromConfig struct {
|
||||
BasicAuthUser string
|
||||
WithCredentials bool
|
||||
IsDefault bool
|
||||
Correlations []datasources.Correlation
|
||||
JSONData map[string]interface{}
|
||||
SecureJSONData map[string]string
|
||||
Editable bool
|
||||
@ -86,6 +87,7 @@ type upsertDataSourceFromConfigV0 struct {
|
||||
BasicAuthUser string `json:"basic_auth_user" yaml:"basic_auth_user"`
|
||||
WithCredentials bool `json:"with_credentials" yaml:"with_credentials"`
|
||||
IsDefault bool `json:"is_default" yaml:"is_default"`
|
||||
Correlations []interface{} `json:"correlations" yaml:"correlations"`
|
||||
JSONData map[string]interface{} `json:"json_data" yaml:"json_data"`
|
||||
SecureJSONData map[string]string `json:"secure_json_data" yaml:"secure_json_data"`
|
||||
Editable bool `json:"editable" yaml:"editable"`
|
||||
@ -104,6 +106,7 @@ type upsertDataSourceFromConfigV1 struct {
|
||||
BasicAuthUser values.StringValue `json:"basicAuthUser" yaml:"basicAuthUser"`
|
||||
WithCredentials values.BoolValue `json:"withCredentials" yaml:"withCredentials"`
|
||||
IsDefault values.BoolValue `json:"isDefault" yaml:"isDefault"`
|
||||
Correlations values.JSONSliceValue `json:"correlations" yaml:"correlations"`
|
||||
JSONData values.JSONValue `json:"jsonData" yaml:"jsonData"`
|
||||
SecureJSONData values.StringMapValue `json:"secureJsonData" yaml:"secureJsonData"`
|
||||
Editable values.BoolValue `json:"editable" yaml:"editable"`
|
||||
@ -120,6 +123,19 @@ func (cfg *configsV1) mapToDatasourceFromConfig(apiVersion int64) *configs {
|
||||
}
|
||||
|
||||
for _, ds := range cfg.Datasources {
|
||||
correlations := make([]datasources.Correlation, 0)
|
||||
for _, v := range ds.Correlations.Value() {
|
||||
field, ok := v.(map[string]interface{})
|
||||
|
||||
if ok {
|
||||
correlations = append(correlations, datasources.Correlation{
|
||||
Target: field["targetUid"].(string),
|
||||
Description: field["description"].(string),
|
||||
Label: field["label"].(string),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
r.Datasources = append(r.Datasources, &upsertDataSourceFromConfig{
|
||||
OrgID: ds.OrgID.Value(),
|
||||
Name: ds.Name.Value(),
|
||||
@ -132,6 +148,7 @@ func (cfg *configsV1) mapToDatasourceFromConfig(apiVersion int64) *configs {
|
||||
BasicAuthUser: ds.BasicAuthUser.Value(),
|
||||
WithCredentials: ds.WithCredentials.Value(),
|
||||
IsDefault: ds.IsDefault.Value(),
|
||||
Correlations: correlations,
|
||||
JSONData: ds.JSONData.Value(),
|
||||
SecureJSONData: ds.SecureJSONData.Value(),
|
||||
Editable: ds.Editable.Value(),
|
||||
@ -160,6 +177,19 @@ func (cfg *configsV0) mapToDatasourceFromConfig(apiVersion int64) *configs {
|
||||
}
|
||||
|
||||
for _, ds := range cfg.Datasources {
|
||||
correlations := make([]datasources.Correlation, 0)
|
||||
for _, v := range ds.Correlations {
|
||||
field, ok := v.(map[string]interface{})
|
||||
|
||||
if ok {
|
||||
correlations = append(correlations, datasources.Correlation{
|
||||
Target: field["targetUid"].(string),
|
||||
Description: field["description"].(string),
|
||||
Label: field["label"].(string),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
r.Datasources = append(r.Datasources, &upsertDataSourceFromConfig{
|
||||
OrgID: ds.OrgID,
|
||||
Name: ds.Name,
|
||||
@ -172,6 +202,7 @@ func (cfg *configsV0) mapToDatasourceFromConfig(apiVersion int64) *configs {
|
||||
BasicAuthUser: ds.BasicAuthUser,
|
||||
WithCredentials: ds.WithCredentials,
|
||||
IsDefault: ds.IsDefault,
|
||||
Correlations: correlations,
|
||||
JSONData: ds.JSONData,
|
||||
SecureJSONData: ds.SecureJSONData,
|
||||
Editable: ds.Editable,
|
||||
@ -209,6 +240,7 @@ func createInsertCommand(ds *upsertDataSourceFromConfig) *datasources.AddDataSou
|
||||
BasicAuthUser: ds.BasicAuthUser,
|
||||
WithCredentials: ds.WithCredentials,
|
||||
IsDefault: ds.IsDefault,
|
||||
Correlations: ds.Correlations,
|
||||
JsonData: jsonData,
|
||||
SecureJsonData: ds.SecureJSONData,
|
||||
ReadOnly: !ds.Editable,
|
||||
@ -250,6 +282,7 @@ func createUpdateCommand(ds *upsertDataSourceFromConfig, id int64) *datasources.
|
||||
BasicAuthUser: ds.BasicAuthUser,
|
||||
WithCredentials: ds.WithCredentials,
|
||||
IsDefault: ds.IsDefault,
|
||||
Correlations: ds.Correlations,
|
||||
JsonData: jsonData,
|
||||
SecureJsonData: ds.SecureJSONData,
|
||||
ReadOnly: !ds.Editable,
|
||||
|
@ -188,6 +188,40 @@ func (val *StringMapValue) Value() map[string]string {
|
||||
return val.value
|
||||
}
|
||||
|
||||
// JSONSliceValue represents a slice value in a YAML
|
||||
// config that can be overridden by environment variables
|
||||
|
||||
type JSONSliceValue struct {
|
||||
value []interface{}
|
||||
Raw []interface{}
|
||||
}
|
||||
|
||||
// UnmarshalYAML converts YAML into an *JSONSliceValue
|
||||
func (val *JSONSliceValue) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
unmarshaled := make([]interface{}, 0)
|
||||
err := unmarshal(&unmarshaled)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range unmarshaled {
|
||||
interpolated, raw, err := transformInterface(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.value = append(val.value, interpolated)
|
||||
val.Raw = append(val.Raw, raw)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Value returns the wrapped []interface{} value
|
||||
func (val *JSONSliceValue) Value() []interface{} {
|
||||
return val.value
|
||||
}
|
||||
|
||||
// transformInterface tries to transform any interface type into proper value with env expansion. It traverses maps and
|
||||
// slices and the actual interpolation is done on all simple string values in the structure. It returns a copy of any
|
||||
// map or slice value instead of modifying them in place and also return value without interpolation but with converted
|
||||
|
@ -220,6 +220,55 @@ func TestValues(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("JSONSliceValue", func(t *testing.T) {
|
||||
type Data struct {
|
||||
Val JSONSliceValue `yaml:"val"`
|
||||
}
|
||||
d := &Data{}
|
||||
|
||||
t.Run("Should unmarshal top-level slices and nested structures", func(t *testing.T) {
|
||||
doc := `
|
||||
val:
|
||||
- $STRING
|
||||
- $INT
|
||||
- stringMap:
|
||||
interpolatedString: $STRING
|
||||
interpolatedInt: $INT
|
||||
string: "just a string"
|
||||
sameLevel: $STRING
|
||||
`
|
||||
unmarshalingTest(t, doc, d)
|
||||
|
||||
type stringMap = map[string]interface{}
|
||||
|
||||
require.Equal(t, []interface{}{
|
||||
"test",
|
||||
"1",
|
||||
stringMap{
|
||||
"stringMap": stringMap{
|
||||
"interpolatedString": "test",
|
||||
"interpolatedInt": "1",
|
||||
"string": "just a string",
|
||||
},
|
||||
"sameLevel": "test",
|
||||
},
|
||||
}, d.Val.Value())
|
||||
|
||||
require.Equal(t, []interface{}{
|
||||
"$STRING",
|
||||
"$INT",
|
||||
stringMap{
|
||||
"stringMap": stringMap{
|
||||
"interpolatedString": "$STRING",
|
||||
"interpolatedInt": "$INT",
|
||||
"string": "just a string",
|
||||
},
|
||||
"sameLevel": "$STRING",
|
||||
},
|
||||
}, d.Val.Raw)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("StringMapValue", func(t *testing.T) {
|
||||
type Data struct {
|
||||
Val StringMapValue `yaml:"val"`
|
||||
|
@ -169,6 +169,7 @@ func (ss *SQLStore) AddDataSource(ctx context.Context, cmd *datasources.AddDataS
|
||||
BasicAuth: cmd.BasicAuth,
|
||||
BasicAuthUser: cmd.BasicAuthUser,
|
||||
WithCredentials: cmd.WithCredentials,
|
||||
Correlations: cmd.Correlations,
|
||||
JsonData: cmd.JsonData,
|
||||
SecureJsonData: cmd.EncryptedSecureJsonData,
|
||||
Created: time.Now(),
|
||||
@ -303,7 +304,7 @@ func (ss *SQLStore) UpdateCorrelations(ctx context.Context, cmd *datasources.Upd
|
||||
}
|
||||
|
||||
if affected == 0 {
|
||||
return datasources.ErrDataSourceUpdatingOldVersion
|
||||
return datasources.ErrDataSourceNotFound
|
||||
}
|
||||
|
||||
cmd.Result = cmd.Correlations
|
||||
|
Loading…
Reference in New Issue
Block a user