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
|
access: proxy
|
||||||
url: http://localhost:3100
|
url: http://localhost:3100
|
||||||
editable: false
|
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:
|
jsonData:
|
||||||
manageAlerts: false
|
manageAlerts: false
|
||||||
derivedFields:
|
derivedFields:
|
||||||
|
@ -101,6 +101,7 @@ type AddDataSourceCommand struct {
|
|||||||
BasicAuthUser string `json:"basicAuthUser"`
|
BasicAuthUser string `json:"basicAuthUser"`
|
||||||
WithCredentials bool `json:"withCredentials"`
|
WithCredentials bool `json:"withCredentials"`
|
||||||
IsDefault bool `json:"isDefault"`
|
IsDefault bool `json:"isDefault"`
|
||||||
|
Correlations []Correlation `json:"-"`
|
||||||
JsonData *simplejson.Json `json:"jsonData"`
|
JsonData *simplejson.Json `json:"jsonData"`
|
||||||
SecureJsonData map[string]string `json:"secureJsonData"`
|
SecureJsonData map[string]string `json:"secureJsonData"`
|
||||||
Uid string `json:"uid"`
|
Uid string `json:"uid"`
|
||||||
@ -126,6 +127,7 @@ type UpdateDataSourceCommand struct {
|
|||||||
BasicAuthUser string `json:"basicAuthUser"`
|
BasicAuthUser string `json:"basicAuthUser"`
|
||||||
WithCredentials bool `json:"withCredentials"`
|
WithCredentials bool `json:"withCredentials"`
|
||||||
IsDefault bool `json:"isDefault"`
|
IsDefault bool `json:"isDefault"`
|
||||||
|
Correlations []Correlation `json:"correlations"`
|
||||||
JsonData *simplejson.Json `json:"jsonData"`
|
JsonData *simplejson.Json `json:"jsonData"`
|
||||||
SecureJsonData map[string]string `json:"secureJsonData"`
|
SecureJsonData map[string]string `json:"secureJsonData"`
|
||||||
Version int `json:"version"`
|
Version int `json:"version"`
|
||||||
|
@ -42,6 +42,7 @@ type upsertDataSourceFromConfig struct {
|
|||||||
BasicAuthUser string
|
BasicAuthUser string
|
||||||
WithCredentials bool
|
WithCredentials bool
|
||||||
IsDefault bool
|
IsDefault bool
|
||||||
|
Correlations []datasources.Correlation
|
||||||
JSONData map[string]interface{}
|
JSONData map[string]interface{}
|
||||||
SecureJSONData map[string]string
|
SecureJSONData map[string]string
|
||||||
Editable bool
|
Editable bool
|
||||||
@ -86,6 +87,7 @@ type upsertDataSourceFromConfigV0 struct {
|
|||||||
BasicAuthUser string `json:"basic_auth_user" yaml:"basic_auth_user"`
|
BasicAuthUser string `json:"basic_auth_user" yaml:"basic_auth_user"`
|
||||||
WithCredentials bool `json:"with_credentials" yaml:"with_credentials"`
|
WithCredentials bool `json:"with_credentials" yaml:"with_credentials"`
|
||||||
IsDefault bool `json:"is_default" yaml:"is_default"`
|
IsDefault bool `json:"is_default" yaml:"is_default"`
|
||||||
|
Correlations []interface{} `json:"correlations" yaml:"correlations"`
|
||||||
JSONData map[string]interface{} `json:"json_data" yaml:"json_data"`
|
JSONData map[string]interface{} `json:"json_data" yaml:"json_data"`
|
||||||
SecureJSONData map[string]string `json:"secure_json_data" yaml:"secure_json_data"`
|
SecureJSONData map[string]string `json:"secure_json_data" yaml:"secure_json_data"`
|
||||||
Editable bool `json:"editable" yaml:"editable"`
|
Editable bool `json:"editable" yaml:"editable"`
|
||||||
@ -104,6 +106,7 @@ type upsertDataSourceFromConfigV1 struct {
|
|||||||
BasicAuthUser values.StringValue `json:"basicAuthUser" yaml:"basicAuthUser"`
|
BasicAuthUser values.StringValue `json:"basicAuthUser" yaml:"basicAuthUser"`
|
||||||
WithCredentials values.BoolValue `json:"withCredentials" yaml:"withCredentials"`
|
WithCredentials values.BoolValue `json:"withCredentials" yaml:"withCredentials"`
|
||||||
IsDefault values.BoolValue `json:"isDefault" yaml:"isDefault"`
|
IsDefault values.BoolValue `json:"isDefault" yaml:"isDefault"`
|
||||||
|
Correlations values.JSONSliceValue `json:"correlations" yaml:"correlations"`
|
||||||
JSONData values.JSONValue `json:"jsonData" yaml:"jsonData"`
|
JSONData values.JSONValue `json:"jsonData" yaml:"jsonData"`
|
||||||
SecureJSONData values.StringMapValue `json:"secureJsonData" yaml:"secureJsonData"`
|
SecureJSONData values.StringMapValue `json:"secureJsonData" yaml:"secureJsonData"`
|
||||||
Editable values.BoolValue `json:"editable" yaml:"editable"`
|
Editable values.BoolValue `json:"editable" yaml:"editable"`
|
||||||
@ -120,6 +123,19 @@ func (cfg *configsV1) mapToDatasourceFromConfig(apiVersion int64) *configs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, ds := range cfg.Datasources {
|
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{
|
r.Datasources = append(r.Datasources, &upsertDataSourceFromConfig{
|
||||||
OrgID: ds.OrgID.Value(),
|
OrgID: ds.OrgID.Value(),
|
||||||
Name: ds.Name.Value(),
|
Name: ds.Name.Value(),
|
||||||
@ -132,6 +148,7 @@ func (cfg *configsV1) mapToDatasourceFromConfig(apiVersion int64) *configs {
|
|||||||
BasicAuthUser: ds.BasicAuthUser.Value(),
|
BasicAuthUser: ds.BasicAuthUser.Value(),
|
||||||
WithCredentials: ds.WithCredentials.Value(),
|
WithCredentials: ds.WithCredentials.Value(),
|
||||||
IsDefault: ds.IsDefault.Value(),
|
IsDefault: ds.IsDefault.Value(),
|
||||||
|
Correlations: correlations,
|
||||||
JSONData: ds.JSONData.Value(),
|
JSONData: ds.JSONData.Value(),
|
||||||
SecureJSONData: ds.SecureJSONData.Value(),
|
SecureJSONData: ds.SecureJSONData.Value(),
|
||||||
Editable: ds.Editable.Value(),
|
Editable: ds.Editable.Value(),
|
||||||
@ -160,6 +177,19 @@ func (cfg *configsV0) mapToDatasourceFromConfig(apiVersion int64) *configs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, ds := range cfg.Datasources {
|
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{
|
r.Datasources = append(r.Datasources, &upsertDataSourceFromConfig{
|
||||||
OrgID: ds.OrgID,
|
OrgID: ds.OrgID,
|
||||||
Name: ds.Name,
|
Name: ds.Name,
|
||||||
@ -172,6 +202,7 @@ func (cfg *configsV0) mapToDatasourceFromConfig(apiVersion int64) *configs {
|
|||||||
BasicAuthUser: ds.BasicAuthUser,
|
BasicAuthUser: ds.BasicAuthUser,
|
||||||
WithCredentials: ds.WithCredentials,
|
WithCredentials: ds.WithCredentials,
|
||||||
IsDefault: ds.IsDefault,
|
IsDefault: ds.IsDefault,
|
||||||
|
Correlations: correlations,
|
||||||
JSONData: ds.JSONData,
|
JSONData: ds.JSONData,
|
||||||
SecureJSONData: ds.SecureJSONData,
|
SecureJSONData: ds.SecureJSONData,
|
||||||
Editable: ds.Editable,
|
Editable: ds.Editable,
|
||||||
@ -209,6 +240,7 @@ func createInsertCommand(ds *upsertDataSourceFromConfig) *datasources.AddDataSou
|
|||||||
BasicAuthUser: ds.BasicAuthUser,
|
BasicAuthUser: ds.BasicAuthUser,
|
||||||
WithCredentials: ds.WithCredentials,
|
WithCredentials: ds.WithCredentials,
|
||||||
IsDefault: ds.IsDefault,
|
IsDefault: ds.IsDefault,
|
||||||
|
Correlations: ds.Correlations,
|
||||||
JsonData: jsonData,
|
JsonData: jsonData,
|
||||||
SecureJsonData: ds.SecureJSONData,
|
SecureJsonData: ds.SecureJSONData,
|
||||||
ReadOnly: !ds.Editable,
|
ReadOnly: !ds.Editable,
|
||||||
@ -250,6 +282,7 @@ func createUpdateCommand(ds *upsertDataSourceFromConfig, id int64) *datasources.
|
|||||||
BasicAuthUser: ds.BasicAuthUser,
|
BasicAuthUser: ds.BasicAuthUser,
|
||||||
WithCredentials: ds.WithCredentials,
|
WithCredentials: ds.WithCredentials,
|
||||||
IsDefault: ds.IsDefault,
|
IsDefault: ds.IsDefault,
|
||||||
|
Correlations: ds.Correlations,
|
||||||
JsonData: jsonData,
|
JsonData: jsonData,
|
||||||
SecureJsonData: ds.SecureJSONData,
|
SecureJsonData: ds.SecureJSONData,
|
||||||
ReadOnly: !ds.Editable,
|
ReadOnly: !ds.Editable,
|
||||||
|
@ -188,6 +188,40 @@ func (val *StringMapValue) Value() map[string]string {
|
|||||||
return val.value
|
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
|
// 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
|
// 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
|
// 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) {
|
t.Run("StringMapValue", func(t *testing.T) {
|
||||||
type Data struct {
|
type Data struct {
|
||||||
Val StringMapValue `yaml:"val"`
|
Val StringMapValue `yaml:"val"`
|
||||||
|
@ -169,6 +169,7 @@ func (ss *SQLStore) AddDataSource(ctx context.Context, cmd *datasources.AddDataS
|
|||||||
BasicAuth: cmd.BasicAuth,
|
BasicAuth: cmd.BasicAuth,
|
||||||
BasicAuthUser: cmd.BasicAuthUser,
|
BasicAuthUser: cmd.BasicAuthUser,
|
||||||
WithCredentials: cmd.WithCredentials,
|
WithCredentials: cmd.WithCredentials,
|
||||||
|
Correlations: cmd.Correlations,
|
||||||
JsonData: cmd.JsonData,
|
JsonData: cmd.JsonData,
|
||||||
SecureJsonData: cmd.EncryptedSecureJsonData,
|
SecureJsonData: cmd.EncryptedSecureJsonData,
|
||||||
Created: time.Now(),
|
Created: time.Now(),
|
||||||
@ -303,7 +304,7 @@ func (ss *SQLStore) UpdateCorrelations(ctx context.Context, cmd *datasources.Upd
|
|||||||
}
|
}
|
||||||
|
|
||||||
if affected == 0 {
|
if affected == 0 {
|
||||||
return datasources.ErrDataSourceUpdatingOldVersion
|
return datasources.ErrDataSourceNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Result = cmd.Correlations
|
cmd.Result = cmd.Correlations
|
||||||
|
Loading…
Reference in New Issue
Block a user