mirror of
https://github.com/grafana/grafana.git
synced 2024-11-30 20:54:22 -06:00
227c8403b5
[As code] Correct trim apply defaults when import/export dashboards
145 lines
3.4 KiB
Go
145 lines
3.4 KiB
Go
package schemaloader
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/grafana/grafana"
|
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
|
"github.com/grafana/grafana/pkg/schema"
|
|
"github.com/grafana/grafana/pkg/schema/load"
|
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
)
|
|
|
|
const ServiceName = "SchemaLoader"
|
|
|
|
var baseLoadPath load.BaseLoadPaths = load.BaseLoadPaths{
|
|
BaseCueFS: grafana.CoreSchema,
|
|
DistPluginCueFS: grafana.PluginSchema,
|
|
}
|
|
|
|
type RenderUser struct {
|
|
OrgID int64
|
|
UserID int64
|
|
OrgRole string
|
|
}
|
|
|
|
func ProvideService(cfg *setting.Cfg) (*SchemaLoaderService, error) {
|
|
dashFam, err := load.BaseDashboardFamily(baseLoadPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to load dashboard cue schema from path %q: %w", baseLoadPath, err)
|
|
}
|
|
s := &SchemaLoaderService{
|
|
Cfg: cfg,
|
|
DashFamily: dashFam,
|
|
log: log.New("schemaloader"),
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
type SchemaLoaderService struct {
|
|
log log.Logger
|
|
DashFamily schema.VersionedCueSchema
|
|
Cfg *setting.Cfg
|
|
}
|
|
|
|
func (rs *SchemaLoaderService) IsDisabled() bool {
|
|
if rs.Cfg == nil {
|
|
return true
|
|
}
|
|
return !rs.Cfg.IsTrimDefaultsEnabled()
|
|
}
|
|
|
|
func (rs *SchemaLoaderService) DashboardApplyDefaults(input *simplejson.Json) (*simplejson.Json, error) {
|
|
val, _ := input.Map()
|
|
val = removeNils(val)
|
|
data, _ := json.Marshal(val)
|
|
dsSchema := schema.Find(rs.DashFamily, schema.Latest())
|
|
result, err := schema.ApplyDefaults(schema.Resource{Value: data}, dsSchema.CUE())
|
|
if err != nil {
|
|
return input, err
|
|
}
|
|
output, err := simplejson.NewJson([]byte(result.Value.(string)))
|
|
if err != nil {
|
|
return input, err
|
|
}
|
|
return output, nil
|
|
}
|
|
|
|
func (rs *SchemaLoaderService) DashboardTrimDefaults(input simplejson.Json) (simplejson.Json, error) {
|
|
val, _ := input.Map()
|
|
val = removeNils(val)
|
|
data, _ := json.Marshal(val)
|
|
|
|
dsSchema, err := schema.SearchAndValidate(rs.DashFamily, string(data))
|
|
if err != nil {
|
|
return input, err
|
|
}
|
|
|
|
result, err := schema.TrimDefaults(schema.Resource{Value: data}, dsSchema.CUE())
|
|
if err != nil {
|
|
return input, err
|
|
}
|
|
output, err := simplejson.NewJson([]byte(result.Value.(string)))
|
|
if err != nil {
|
|
return input, err
|
|
}
|
|
return *output, nil
|
|
}
|
|
|
|
func removeNils(initialMap map[string]interface{}) map[string]interface{} {
|
|
withoutNils := map[string]interface{}{}
|
|
for key, value := range initialMap {
|
|
_, ok := value.(map[string]interface{})
|
|
if ok {
|
|
value = removeNils(value.(map[string]interface{}))
|
|
withoutNils[key] = value
|
|
continue
|
|
}
|
|
_, ok = value.([]interface{})
|
|
if ok {
|
|
value = removeNilArray(value.([]interface{}))
|
|
withoutNils[key] = value
|
|
continue
|
|
}
|
|
if value != nil {
|
|
if val, ok := value.(string); ok {
|
|
if val == "" {
|
|
continue
|
|
}
|
|
}
|
|
withoutNils[key] = value
|
|
}
|
|
}
|
|
return withoutNils
|
|
}
|
|
|
|
func removeNilArray(initialArray []interface{}) []interface{} {
|
|
withoutNils := []interface{}{}
|
|
for _, value := range initialArray {
|
|
_, ok := value.(map[string]interface{})
|
|
if ok {
|
|
value = removeNils(value.(map[string]interface{}))
|
|
withoutNils = append(withoutNils, value)
|
|
continue
|
|
}
|
|
_, ok = value.([]interface{})
|
|
if ok {
|
|
value = removeNilArray(value.([]interface{}))
|
|
withoutNils = append(withoutNils, value)
|
|
continue
|
|
}
|
|
if value != nil {
|
|
if val, ok := value.(string); ok {
|
|
if val == "" {
|
|
continue
|
|
}
|
|
}
|
|
withoutNils = append(withoutNils, value)
|
|
}
|
|
}
|
|
return withoutNils
|
|
}
|