diff --git a/frontend/src/container/NewDashboard/DashboardDescription/index.tsx b/frontend/src/container/NewDashboard/DashboardDescription/index.tsx index 996c508da4..c916ec7501 100644 --- a/frontend/src/container/NewDashboard/DashboardDescription/index.tsx +++ b/frontend/src/container/NewDashboard/DashboardDescription/index.tsx @@ -23,7 +23,12 @@ function DashboardDescription(): JSX.Element { handleDashboardLockToggle, } = useDashboard(); - const selectedData = selectedDashboard?.data || ({} as DashboardData); + const selectedData = selectedDashboard + ? { + ...selectedDashboard.data, + uuid: selectedDashboard.uuid, + } + : ({} as DashboardData); const { title = '', tags, description } = selectedData || {}; diff --git a/frontend/src/types/api/dashboard/getAll.ts b/frontend/src/types/api/dashboard/getAll.ts index e616ee28ea..ba23e55186 100644 --- a/frontend/src/types/api/dashboard/getAll.ts +++ b/frontend/src/types/api/dashboard/getAll.ts @@ -55,6 +55,7 @@ export interface Dashboard { } export interface DashboardData { + uuid?: string; description?: string; tags?: string[]; name?: string; diff --git a/pkg/query-service/app/dashboards/model.go b/pkg/query-service/app/dashboards/model.go index 698b697279..6e777f49c9 100644 --- a/pkg/query-service/app/dashboards/model.go +++ b/pkg/query-service/app/dashboards/model.go @@ -25,12 +25,14 @@ import ( var db *sqlx.DB // User for mapping job,instance from grafana -var instanceEQRE = regexp.MustCompile("instance(?s)=(?s)\\\"{{.instance}}\\\"") -var nodeEQRE = regexp.MustCompile("instance(?s)=(?s)\\\"{{.node}}\\\"") -var jobEQRE = regexp.MustCompile("job(?s)=(?s)\\\"{{.job}}\\\"") -var instanceRERE = regexp.MustCompile("instance(?s)=~(?s)\\\"{{.instance}}\\\"") -var nodeRERE = regexp.MustCompile("instance(?s)=~(?s)\\\"{{.node}}\\\"") -var jobRERE = regexp.MustCompile("job(?s)=~(?s)\\\"{{.job}}\\\"") +var ( + instanceEQRE = regexp.MustCompile("instance(?s)=(?s)\\\"{{.instance}}\\\"") + nodeEQRE = regexp.MustCompile("instance(?s)=(?s)\\\"{{.node}}\\\"") + jobEQRE = regexp.MustCompile("job(?s)=(?s)\\\"{{.job}}\\\"") + instanceRERE = regexp.MustCompile("instance(?s)=~(?s)\\\"{{.instance}}\\\"") + nodeRERE = regexp.MustCompile("instance(?s)=~(?s)\\\"{{.node}}\\\"") + jobRERE = regexp.MustCompile("job(?s)=~(?s)\\\"{{.job}}\\\"") +) // InitDB sets up setting up the connection pool global variable. func InitDB(dataSourceName string) (*sqlx.DB, error) { @@ -188,6 +190,9 @@ func CreateDashboard(ctx context.Context, data map[string]interface{}, fm interf dash.UpdateBy = &userEmail dash.UpdateSlug() dash.Uuid = uuid.New().String() + if data["uuid"] != nil { + dash.Uuid = data["uuid"].(string) + } mapData, err := json.Marshal(dash.Data) if err != nil { @@ -211,7 +216,6 @@ func CreateDashboard(ctx context.Context, data map[string]interface{}, fm interf return nil, &model.ApiError{Typ: model.ErrorExec, Err: err} } lastInsertId, err := result.LastInsertId() - if err != nil { return nil, &model.ApiError{Typ: model.ErrorExec, Err: err} } @@ -255,7 +259,6 @@ func DeleteDashboard(ctx context.Context, uuid string, fm interfaces.FeatureLook query := `DELETE FROM dashboards WHERE uuid=?` result, err := db.Exec(query, uuid) - if err != nil { return &model.ApiError{Typ: model.ErrorExec, Err: err} } @@ -419,7 +422,6 @@ func (d *Dashboard) UpdateSlug() { } func IsPostDataSane(data *map[string]interface{}) error { - val, ok := (*data)["title"] if !ok || val == nil { return fmt.Errorf("title not found in post data") diff --git a/pkg/query-service/app/dashboards/provision.go b/pkg/query-service/app/dashboards/provision.go index 6f60dc50fe..049ae42e72 100644 --- a/pkg/query-service/app/dashboards/provision.go +++ b/pkg/query-service/app/dashboards/provision.go @@ -10,6 +10,7 @@ import ( "go.signoz.io/signoz/pkg/query-service/constants" "go.signoz.io/signoz/pkg/query-service/interfaces" + "go.signoz.io/signoz/pkg/query-service/model" ) func readCurrentDir(dir string, fm interfaces.FeatureLookup) error { @@ -43,22 +44,36 @@ func readCurrentDir(dir string, fm interfaces.FeatureLookup) error { continue } - _, apiErr := GetDashboard(context.Background(), data["uuid"].(string)) - if apiErr == nil { - zap.S().Infof("Creating Dashboards: Error in file: %s\t%s", filename, "Dashboard already present in database") + id := data["uuid"] + if id == nil { + _, apiErr := CreateDashboard(context.Background(), data, fm) + if apiErr != nil { + zap.S().Errorf("Creating Dashboards: Error in file: %s\t%s", filename, apiErr.Err) + } continue } - _, apiErr = CreateDashboard(context.Background(), data, fm) + apiErr := upsertDashboard(id.(string), data, filename, fm) if apiErr != nil { - zap.S().Errorf("Creating Dashboards: Error in file: %s\t%s", filename, apiErr.Err) - continue + zap.S().Errorf("Creating Dashboards: Error upserting dashboard: %s\t%s", filename, apiErr.Err) } - } return nil } +func upsertDashboard(uuid string, data map[string]interface{}, filename string, fm interfaces.FeatureLookup) *model.ApiError { + _, apiErr := GetDashboard(context.Background(), uuid) + if apiErr == nil { + zap.S().Infof("Creating Dashboards: Already exists: %s\t%s", filename, "Dashboard already present in database, Updating dashboard") + _, apiErr := UpdateDashboard(context.Background(), uuid, data, fm) + return apiErr + } + + zap.S().Infof("Creating Dashboards: UUID not found: %s\t%s", filename, "Dashboard not present in database, Creating dashboard") + _, apiErr = CreateDashboard(context.Background(), data, fm) + return apiErr +} + func LoadDashboardFiles(fm interfaces.FeatureLookup) error { dashboardsPath := constants.GetOrDefaultEnv("DASHBOARDS_PATH", "./config/dashboards") return readCurrentDir(dashboardsPath, fm)