Compare commits

..

1 Commits

Author SHA1 Message Date
nityanandagohain
ef748e9ce2 fix: add userauditable to ttl setting 2026-05-11 10:28:38 +05:30
20 changed files with 130 additions and 364 deletions

View File

@@ -2223,8 +2223,6 @@ components:
type: boolean
org_id:
type: string
source:
type: string
updatedAt:
format: date-time
type: string

View File

@@ -138,11 +138,6 @@ func (module *module) Delete(ctx context.Context, orgID valuer.UUID, id valuer.U
return err
}
// Do not delete system dashboard, we can only reset system dashbard to default.
if dashboard.Source != "" {
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot delete system dashboard with source %s, use reset instead", dashboard.Source)
}
if dashboard.Locked {
return errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "dashboard is locked, please unlock the dashboard to be delete it")
}
@@ -218,14 +213,6 @@ func (module *module) Update(ctx context.Context, orgID valuer.UUID, id valuer.U
return module.pkgDashboardModule.Update(ctx, orgID, id, updatedBy, data, diff)
}
func (module *module) Reset(ctx context.Context, orgID valuer.UUID, source dashboardtypes.Source, updatedBy string) (*dashboardtypes.Dashboard, error) {
return module.pkgDashboardModule.Reset(ctx, orgID, source, updatedBy)
}
func (module *module) SetDefaultConfig(ctx context.Context, orgID valuer.UUID) error {
return module.pkgDashboardModule.SetDefaultConfig(ctx, orgID)
}
func (module *module) LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, isAdmin bool, lock bool) error {
return module.pkgDashboardModule.LockUnlock(ctx, orgID, id, updatedBy, isAdmin, lock)
}

View File

@@ -4186,10 +4186,6 @@ export interface DashboardtypesDashboardDTO {
* @type string
*/
org_id?: string;
/**
* @type string
*/
source?: string;
/**
* @type string
* @format date-time

View File

@@ -42,11 +42,6 @@ type Module interface {
Update(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, data dashboardtypes.UpdatableDashboard, diff int) (*dashboardtypes.Dashboard, error)
// Reset puts back default value for system dashboard.
Reset(ctx context.Context, orgID valuer.UUID, source dashboardtypes.Source, updatedBy string) (*dashboardtypes.Dashboard, error)
SetDefaultConfig(ctx context.Context, orgID valuer.UUID) error
LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, isAdmin bool, lock bool) error
Delete(ctx context.Context, orgID valuer.UUID, id valuer.UUID) error
@@ -76,6 +71,4 @@ type Handler interface {
LockUnlock(http.ResponseWriter, *http.Request)
Delete(http.ResponseWriter, *http.Request)
Reset(http.ResponseWriter, *http.Request)
}

View File

@@ -185,49 +185,6 @@ func (handler *handler) LockUnlock(rw http.ResponseWriter, r *http.Request) {
}
// Reset only resets system dashboard (source != "") to default values.
func (handler *handler) Reset(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
id, err := valuer.NewUUID(mux.Vars(r)["id"])
if err != nil {
render.Error(rw, err)
return
}
dashboard, err := handler.module.Get(ctx, orgID, id)
if err != nil {
render.Error(rw, err)
return
}
if dashboard.Source == "" {
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "dashboard with id %s is not a system dashboard, reset is unsupported", id))
return
}
resetDashboard, err := handler.module.Reset(ctx, orgID, dashboardtypes.Source(dashboard.Source), claims.Email)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, resetDashboard)
}
func (handler *handler) Delete(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()

View File

@@ -38,7 +38,7 @@ func NewModule(store dashboardtypes.Store, settings factory.ProviderSettings, an
}
func (module *module) Create(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, postableDashboard dashboardtypes.PostableDashboard) (*dashboardtypes.Dashboard, error) {
dashboard, err := dashboardtypes.NewDashboard(orgID, createdBy, postableDashboard, "")
dashboard, err := dashboardtypes.NewDashboard(orgID, createdBy, postableDashboard)
if err != nil {
return nil, err
}
@@ -66,15 +66,6 @@ func (module *module) Get(ctx context.Context, orgID valuer.UUID, id valuer.UUID
return dashboardtypes.NewDashboardFromStorableDashboard(storableDashboard), nil
}
func (module *module) GetBySource(ctx context.Context, orgID valuer.UUID, source dashboardtypes.Source) (*dashboardtypes.Dashboard, error) {
storableDashboard, err := module.store.GetBySource(ctx, orgID, string(source))
if err != nil {
return nil, err
}
return dashboardtypes.NewDashboardFromStorableDashboard(storableDashboard), nil
}
func (module *module) List(ctx context.Context, orgID valuer.UUID) ([]*dashboardtypes.Dashboard, error) {
storableDashboards, err := module.store.List(ctx, orgID)
if err != nil {
@@ -90,12 +81,9 @@ func (module *module) Update(ctx context.Context, orgID valuer.UUID, id valuer.U
return nil, err
}
if dashboard.Source != "" {
dashboard.OverwriteData(updatableDashboard, updatedBy)
} else {
if err := dashboard.Update(ctx, updatableDashboard, updatedBy, diff); err != nil {
return nil, err
}
err = dashboard.Update(ctx, updatableDashboard, updatedBy, diff)
if err != nil {
return nil, err
}
storableDashboard, err := dashboardtypes.NewStorableDashboardFromDashboard(dashboard)
@@ -103,84 +91,14 @@ func (module *module) Update(ctx context.Context, orgID valuer.UUID, id valuer.U
return nil, err
}
if err := module.store.Update(ctx, orgID, storableDashboard); err != nil {
err = module.store.Update(ctx, orgID, storableDashboard)
if err != nil {
return nil, err
}
return dashboard, nil
}
func (module *module) Reset(ctx context.Context, orgID valuer.UUID, source dashboardtypes.Source, updatedBy string) (*dashboardtypes.Dashboard, error) {
defaultDashboard, err := dashboardtypes.NewDefaultSystemDashboard(orgID, source)
if err != nil {
return nil, err
}
existing, err := module.GetBySource(ctx, orgID, source)
if err != nil && !errors.Ast(err, errors.TypeNotFound) {
return nil, err
}
if existing == nil {
defaultDashboard.CreatedBy = updatedBy
defaultDashboard.UpdatedBy = updatedBy
storable, err := dashboardtypes.NewStorableDashboardFromDashboard(defaultDashboard)
if err != nil {
return nil, err
}
if err := module.store.Create(ctx, storable); err != nil {
return nil, err
}
return defaultDashboard, nil
}
existing.OverwriteData(defaultDashboard.Data, updatedBy)
storable, err := dashboardtypes.NewStorableDashboardFromDashboard(existing)
if err != nil {
return nil, err
}
if err := module.store.Update(ctx, orgID, storable); err != nil {
return nil, err
}
return existing, nil
}
// SetDefaultConfig seeds default values for system dashboards for newly created orgs.
func (module *module) SetDefaultConfig(ctx context.Context, orgID valuer.UUID) error {
for _, source := range dashboardtypes.SystemSources {
existing, err := module.GetBySource(ctx, orgID, source)
if err != nil && !errors.Ast(err, errors.TypeNotFound) {
return err
}
if existing != nil {
continue
}
dashboard, err := dashboardtypes.NewDefaultSystemDashboard(orgID, source)
if err != nil {
// No defaults set for the source skipping will pupulate in default overview followup pr.
if errors.Ast(err, errors.TypeInvalidInput) {
continue
}
return err
}
storable, err := dashboardtypes.NewStorableDashboardFromDashboard(dashboard)
if err != nil {
return err
}
if err := module.store.Create(ctx, storable); err != nil {
return err
}
}
return nil
}
func (module *module) LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, isAdmin bool, lock bool) error {
dashboard, err := module.Get(ctx, orgID, id)
if err != nil {
@@ -210,11 +128,6 @@ func (module *module) Delete(ctx context.Context, orgID valuer.UUID, id valuer.U
return err
}
// Can not delete system dashboard.
if dashboard.Source != "" {
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot delete system dashboard with source %s, use reset instead", dashboard.Source)
}
if dashboard.Locked {
return errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "dashboard is locked, please unlock the dashboard to be delete it")
}

View File

@@ -21,7 +21,7 @@ func NewStore(sqlstore sqlstore.SQLStore) dashboardtypes.Store {
func (store *store) Create(ctx context.Context, storabledashboard *dashboardtypes.StorableDashboard) error {
_, err := store.
sqlstore.
BunDBCtx(ctx).
BunDB().
NewInsert().
Model(storabledashboard).
Exec(ctx)
@@ -63,23 +63,6 @@ func (store *store) Get(ctx context.Context, orgID valuer.UUID, id valuer.UUID)
return storableDashboard, nil
}
func (store *store) GetBySource(ctx context.Context, orgID valuer.UUID, source string) (*dashboardtypes.StorableDashboard, error) {
storableDashboard := new(dashboardtypes.StorableDashboard)
err := store.
sqlstore.
BunDBCtx(ctx).
NewSelect().
Model(storableDashboard).
Where("org_id = ?", orgID).
Where("source = ?", source).
Scan(ctx)
if err != nil {
return nil, store.sqlstore.WrapNotFoundErrf(err, errors.CodeNotFound, "system dashboard with source %s doesn't exist", source)
}
return storableDashboard, nil
}
func (store *store) GetPublic(ctx context.Context, dashboardID string) (*dashboardtypes.StorablePublicDashboard, error) {
storable := new(dashboardtypes.StorablePublicDashboard)
err := store.
@@ -141,7 +124,6 @@ func (store *store) List(ctx context.Context, orgID valuer.UUID) ([]*dashboardty
NewSelect().
Model(&storableDashboards).
Where("org_id = ?", orgID).
Where("source = ?", "").
Scan(ctx)
if err != nil {
return nil, err
@@ -171,7 +153,7 @@ func (store *store) ListPublic(ctx context.Context, orgID valuer.UUID) ([]*dashb
func (store *store) Update(ctx context.Context, orgID valuer.UUID, storableDashboard *dashboardtypes.StorableDashboard) error {
_, err := store.
sqlstore.
BunDBCtx(ctx).
BunDB().
NewUpdate().
Model(storableDashboard).
WherePK().

View File

@@ -4,7 +4,6 @@ import (
"context"
"github.com/SigNoz/signoz/pkg/alertmanager"
"github.com/SigNoz/signoz/pkg/modules/dashboard"
"github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/modules/quickfilter"
"github.com/SigNoz/signoz/pkg/types"
@@ -15,11 +14,10 @@ type setter struct {
store types.OrganizationStore
alertmanager alertmanager.Alertmanager
quickfilter quickfilter.Module
dashboard dashboard.Module
}
func NewSetter(store types.OrganizationStore, alertmanager alertmanager.Alertmanager, quickfilter quickfilter.Module, dashboard dashboard.Module) organization.Setter {
return &setter{store: store, alertmanager: alertmanager, quickfilter: quickfilter, dashboard: dashboard}
func NewSetter(store types.OrganizationStore, alertmanager alertmanager.Alertmanager, quickfilter quickfilter.Module) organization.Setter {
return &setter{store: store, alertmanager: alertmanager, quickfilter: quickfilter}
}
func (module *setter) Create(ctx context.Context, organization *types.Organization, createManagedRoles func(context.Context, valuer.UUID) error) error {
@@ -35,10 +33,6 @@ func (module *setter) Create(ctx context.Context, organization *types.Organizati
return err
}
if err := module.dashboard.SetDefaultConfig(ctx, organization.ID); err != nil {
return err
}
if err := createManagedRoles(ctx, organization.ID); err != nil {
return err
}

View File

@@ -1343,7 +1343,7 @@ func getLocalTableName(tableName string) string {
}
func (r *ClickHouseReader) setTTLLogs(ctx context.Context, orgID string, params *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError) {
func (r *ClickHouseReader) setTTLLogs(ctx context.Context, orgID string, userID string, params *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError) {
ctx = ctxtypes.NewContextWithCommentVals(ctx, map[string]string{
instrumentationtypes.TelemetrySignal: telemetrytypes.SignalLogs.StringValue(),
instrumentationtypes.CodeNamespace: "clickhouse-reader",
@@ -1434,6 +1434,10 @@ func (r *ClickHouseReader) setTTLLogs(ctx context.Context, orgID string, params
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
UserAuditable: types.UserAuditable{
CreatedBy: userID,
UpdatedBy: userID,
},
TransactionID: uuid,
TableName: tableName,
TTL: int(params.DelDuration),
@@ -1511,7 +1515,7 @@ func (r *ClickHouseReader) setTTLLogs(ctx context.Context, orgID string, params
return &model.SetTTLResponseItem{Message: "move ttl has been successfully set up"}, nil
}
func (r *ClickHouseReader) setTTLTraces(ctx context.Context, orgID string, params *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError) {
func (r *ClickHouseReader) setTTLTraces(ctx context.Context, orgID string, userID string, params *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError) {
ctx = ctxtypes.NewContextWithCommentVals(ctx, map[string]string{
instrumentationtypes.TelemetrySignal: telemetrytypes.SignalTraces.StringValue(),
instrumentationtypes.CodeNamespace: "clickhouse-reader",
@@ -1572,6 +1576,10 @@ func (r *ClickHouseReader) setTTLTraces(ctx context.Context, orgID string, param
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
UserAuditable: types.UserAuditable{
CreatedBy: userID,
UpdatedBy: userID,
},
TransactionID: uuid,
TableName: tableName,
TTL: int(params.DelDuration),
@@ -1687,7 +1695,7 @@ func (r *ClickHouseReader) hasCustomRetentionColumn(ctx context.Context) (bool,
return true, nil
}
func (r *ClickHouseReader) SetTTLV2(ctx context.Context, orgID string, params *model.CustomRetentionTTLParams) (*model.CustomRetentionTTLResponse, error) {
func (r *ClickHouseReader) SetTTLV2(ctx context.Context, orgID string, userID string, params *model.CustomRetentionTTLParams) (*model.CustomRetentionTTLResponse, error) {
ctx = ctxtypes.NewContextWithCommentVals(ctx, map[string]string{
instrumentationtypes.TelemetrySignal: telemetrytypes.SignalLogs.StringValue(),
@@ -1718,7 +1726,7 @@ func (r *ClickHouseReader) SetTTLV2(ctx context.Context, orgID string, params *m
ttlParams.ToColdStorageDuration = 0
}
ttlResult, apiErr := r.SetTTL(ctx, orgID, ttlParams)
ttlResult, apiErr := r.SetTTL(ctx, orgID, userID, ttlParams)
if apiErr != nil {
return nil, errorsV2.Wrapf(apiErr.Err, errorsV2.TypeInternal, errorsV2.CodeInternal, "failed to set standard TTL")
}
@@ -1847,6 +1855,10 @@ func (r *ClickHouseReader) SetTTLV2(ctx context.Context, orgID string, params *m
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
UserAuditable: types.UserAuditable{
CreatedBy: userID,
UpdatedBy: userID,
},
TransactionID: uuid,
TableName: tableName,
TTL: params.DefaultTTLDays,
@@ -2185,24 +2197,24 @@ func (r *ClickHouseReader) validateTTLConditions(ctx context.Context, ttlConditi
// SetTTL sets the TTL for traces or metrics or logs tables.
// This is an async API which creates goroutines to set TTL.
// Status of TTL update is tracked with ttl_status table in sqlite db.
func (r *ClickHouseReader) SetTTL(ctx context.Context, orgID string, params *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError) {
func (r *ClickHouseReader) SetTTL(ctx context.Context, orgID string, userID string, params *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError) {
// Keep only latest 100 transactions/requests
r.deleteTtlTransactions(ctx, orgID, 100)
switch params.Type {
case constants.TraceTTL:
return r.setTTLTraces(ctx, orgID, params)
return r.setTTLTraces(ctx, orgID, userID, params)
case constants.MetricsTTL:
return r.setTTLMetrics(ctx, orgID, params)
return r.setTTLMetrics(ctx, orgID, userID, params)
case constants.LogsTTL:
return r.setTTLLogs(ctx, orgID, params)
return r.setTTLLogs(ctx, orgID, userID, params)
default:
return nil, &model.ApiError{Typ: model.ErrorExec, Err: fmt.Errorf("error while setting ttl. ttl type should be <metrics|traces>, got %v", params.Type)}
}
}
func (r *ClickHouseReader) setTTLMetrics(ctx context.Context, orgID string, params *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError) {
func (r *ClickHouseReader) setTTLMetrics(ctx context.Context, orgID string, userID string, params *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError) {
ctx = ctxtypes.NewContextWithCommentVals(ctx, map[string]string{
instrumentationtypes.TelemetrySignal: telemetrytypes.SignalMetrics.StringValue(),
instrumentationtypes.CodeNamespace: "clickhouse-reader",
@@ -2244,6 +2256,10 @@ func (r *ClickHouseReader) setTTLMetrics(ctx context.Context, orgID string, para
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
UserAuditable: types.UserAuditable{
CreatedBy: userID,
UpdatedBy: userID,
},
TransactionID: uuid,
TableName: tableName,
TTL: int(params.DelDuration),

View File

@@ -511,7 +511,6 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router, am *middleware.AuthZ) {
router.HandleFunc("/api/v1/dashboards/{id}", am.EditAccess(aH.Signoz.Handlers.Dashboard.Update)).Methods(http.MethodPut)
router.HandleFunc("/api/v1/dashboards/{id}", am.EditAccess(aH.Signoz.Handlers.Dashboard.Delete)).Methods(http.MethodDelete)
router.HandleFunc("/api/v1/dashboards/{id}/lock", am.EditAccess(aH.Signoz.Handlers.Dashboard.LockUnlock)).Methods(http.MethodPut)
router.HandleFunc("/api/v1/dashboards/{id}/reset", am.AdminAccess(aH.Signoz.Handlers.Dashboard.Reset)).Methods(http.MethodPost)
router.HandleFunc("/api/v2/variables/query", am.ViewAccess(aH.queryDashboardVarsV2)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/explorer/views", am.ViewAccess(aH.Signoz.Handlers.SavedView.List)).Methods(http.MethodGet)
@@ -1656,7 +1655,7 @@ func (aH *APIHandler) setTTL(w http.ResponseWriter, r *http.Request) {
}
// Context is not used here as TTL is long duration DB operation
result, apiErr := aH.reader.SetTTL(context.Background(), claims.OrgID, ttlParams)
result, apiErr := aH.reader.SetTTL(context.Background(), claims.OrgID, claims.UserID, ttlParams)
if apiErr != nil {
if apiErr.Typ == model.ErrorConflict {
aH.HandleError(w, apiErr.Err, http.StatusConflict)
@@ -1685,7 +1684,7 @@ func (aH *APIHandler) setCustomRetentionTTL(w http.ResponseWriter, r *http.Reque
}
// Context is not used here as TTL is long duration DB operation
result, apiErr := aH.reader.SetTTLV2(context.Background(), claims.OrgID, &params)
result, apiErr := aH.reader.SetTTLV2(context.Background(), claims.OrgID, claims.UserID, &params)
if apiErr != nil {
render.Error(w, errorsV2.New(errorsV2.TypeInvalidInput, errorsV2.CodeInternal, apiErr.Error()))
return

View File

@@ -46,8 +46,8 @@ type Reader interface {
GetFlamegraphSpansForTrace(ctx context.Context, orgID valuer.UUID, traceID string, req *model.GetFlamegraphSpansForTraceParams) (*model.GetFlamegraphSpansForTraceResponse, error)
// Setter Interfaces
SetTTL(ctx context.Context, orgID string, ttlParams *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError)
SetTTLV2(ctx context.Context, orgID string, params *model.CustomRetentionTTLParams) (*model.CustomRetentionTTLResponse, error)
SetTTL(ctx context.Context, orgID string, userID string, ttlParams *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError)
SetTTLV2(ctx context.Context, orgID string, userID string, params *model.CustomRetentionTTLParams) (*model.CustomRetentionTTLResponse, error)
FetchTemporality(ctx context.Context, orgID valuer.UUID, metricNames []string) (map[string]map[v3.Temporality]bool, error)
GetMetricAggregateAttributes(ctx context.Context, orgID valuer.UUID, req *v3.AggregateAttributeRequest, skipSignozMetrics bool) (*v3.AggregateAttributeResponse, error)

View File

@@ -106,7 +106,7 @@ func NewModules(
fl flagger.Flagger,
) Modules {
quickfilter := implquickfilter.NewModule(implquickfilter.NewStore(sqlstore))
orgSetter := implorganization.NewSetter(implorganization.NewStore(sqlstore), alertmanager, quickfilter, dashboard)
orgSetter := implorganization.NewSetter(implorganization.NewStore(sqlstore), alertmanager, quickfilter)
userSetter := impluser.NewSetter(impluser.NewStore(sqlstore, providerSettings), tokenizer, emailing, providerSettings, orgSetter, authz, analytics, config.User, userRoleStore, userGetter)
ruleStore := sqlrulestore.NewRuleStore(sqlstore, queryParser, providerSettings)

View File

@@ -196,7 +196,7 @@ func NewSQLMigrationProviderFactories(
sqlmigration.NewDropUserDeletedAtFactory(sqlstore, sqlschema),
sqlmigration.NewMigrateAWSAllRegionsFactory(sqlstore),
sqlmigration.NewAddServiceAccountManagedRoleTransactionsFactory(sqlstore),
sqlmigration.NewAddSystemDashboardFactory(sqlstore, sqlschema),
sqlmigration.NewUpdateTTLSettingUserAuditFactory(sqlstore, sqlschema),
)
}

View File

@@ -1,124 +0,0 @@
package sqlmigration
import (
"context"
"github.com/uptrace/bun"
"github.com/uptrace/bun/migrate"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/sqlschema"
"github.com/SigNoz/signoz/pkg/sqlstore"
)
type addSystemDashboard struct {
sqlstore sqlstore.SQLStore
sqlschema sqlschema.SQLSchema
}
func NewAddSystemDashboardFactory(sqlstore sqlstore.SQLStore, sqlschema sqlschema.SQLSchema) factory.ProviderFactory[SQLMigration, Config] {
return factory.NewProviderFactory(factory.MustNewName("add_system_dashboard"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return &addSystemDashboard{sqlstore: sqlstore, sqlschema: sqlschema}, nil
})
}
func (migration *addSystemDashboard) Register(migrations *migrate.Migrations) error {
if err := migrations.Register(migration.Up, migration.Down); err != nil {
return err
}
return nil
}
func (migration *addSystemDashboard) Up(ctx context.Context, db *bun.DB) error {
// Disable foreign keys for the duration of the migration.
// pattern is used in migration 029_drop_groups.
if err := migration.sqlstore.Dialect().ToggleForeignKeyConstraint(ctx, db, false); err != nil {
return err
}
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer func() {
_ = tx.Rollback()
}()
table, uniqueConstraints, err := migration.sqlschema.GetTable(ctx, "dashboard")
if err != nil {
return err
}
column := &sqlschema.Column{
Name: sqlschema.ColumnName("source"),
DataType: sqlschema.DataTypeText,
Nullable: false,
}
sqls := migration.sqlschema.Operator().AddColumn(table, uniqueConstraints, column, "")
for _, sql := range sqls {
if _, err := tx.ExecContext(ctx, string(sql)); err != nil {
return err
}
}
// We activate this part of code once we add default value for the overview page.
// add source column to the dashboard table.
// do not iterate over orgs.
// var orgIDs []string
// if err := tx.NewSelect().Model((*types.Organization)(nil)).Column("id").Scan(ctx, &orgIDs); err != nil {
// return err
// }
//
// for _, rawOrgID := range orgIDs {
// orgID, err := valuer.NewUUID(rawOrgID)
// if err != nil {
// return err
// }
//
// for _, source := range dashboardtypes.SystemSources {
// count, err := tx.NewSelect().
// Model((*dashboardtypes.StorableDashboard)(nil)).
// Where("org_id = ?", orgID).
// Where("source = ?", string(source)).
// Count(ctx)
// if err != nil {
// return err
// }
// if count > 0 {
// continue
// }
//
// dashboard, err := dashboardtypes.NewDefaultSystemDashboard(orgID, source)
// if err != nil {
// return err
// }
//
// storable, err := dashboardtypes.NewStorableDashboardFromDashboard(dashboard)
// if err != nil {
// return err
// }
//
// if _, err := tx.NewInsert().Model(storable).Exec(ctx); err != nil {
// return err
// }
// }
// }
if err := tx.Commit(); err != nil {
return err
}
// Re-enable foreign keys.
if err := migration.sqlstore.Dialect().ToggleForeignKeyConstraint(ctx, db, true); err != nil {
return err
}
return nil
}
func (migration *addSystemDashboard) Down(context.Context, *bun.DB) error {
return nil
}

View File

@@ -0,0 +1,84 @@
package sqlmigration
import (
"context"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/sqlschema"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/uptrace/bun"
"github.com/uptrace/bun/migrate"
)
type updateTTLSettingUserAudit struct {
sqlstore sqlstore.SQLStore
sqlschema sqlschema.SQLSchema
}
func NewUpdateTTLSettingUserAuditFactory(sqlstore sqlstore.SQLStore, sqlschema sqlschema.SQLSchema) factory.ProviderFactory[SQLMigration, Config] {
return factory.NewProviderFactory(factory.MustNewName("update_ttl_setting_user_audit"), func(ctx context.Context, providerSettings factory.ProviderSettings, config Config) (SQLMigration, error) {
return newUpdateTTLSettingUserAudit(ctx, providerSettings, config, sqlstore, sqlschema)
})
}
func newUpdateTTLSettingUserAudit(_ context.Context, _ factory.ProviderSettings, _ Config, sqlstore sqlstore.SQLStore, sqlschema sqlschema.SQLSchema) (SQLMigration, error) {
return &updateTTLSettingUserAudit{
sqlstore: sqlstore,
sqlschema: sqlschema,
}, nil
}
func (migration *updateTTLSettingUserAudit) Register(migrations *migrate.Migrations) error {
if err := migrations.Register(migration.Up, migration.Down); err != nil {
return err
}
return nil
}
func (migration *updateTTLSettingUserAudit) Up(ctx context.Context, db *bun.DB) error {
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer func() {
_ = tx.Rollback()
}()
table, uniqueConstraints, err := migration.sqlschema.GetTable(ctx, sqlschema.TableName("ttl_setting"))
if err != nil {
return err
}
columns := []*sqlschema.Column{
{
Name: sqlschema.ColumnName("created_by"),
DataType: sqlschema.DataTypeText,
Nullable: true,
},
{
Name: sqlschema.ColumnName("updated_by"),
DataType: sqlschema.DataTypeText,
Nullable: true,
},
}
for _, column := range columns {
sqls := migration.sqlschema.Operator().AddColumn(table, uniqueConstraints, column, nil)
for _, sql := range sqls {
if _, err := tx.ExecContext(ctx, string(sql)); err != nil {
return err
}
}
}
if err := tx.Commit(); err != nil {
return err
}
return nil
}
func (migration *updateTTLSettingUserAudit) Down(ctx context.Context, db *bun.DB) error {
return nil
}

View File

@@ -30,7 +30,6 @@ type StorableDashboard struct {
Data StorableDashboardData `bun:"data,type:text,notnull"`
Locked bool `bun:"locked,notnull,default:false"`
OrgID valuer.UUID `bun:"org_id,notnull"`
Source string `bun:"source,type:text,notnull"`
}
type Dashboard struct {
@@ -41,7 +40,6 @@ type Dashboard struct {
Data StorableDashboardData `json:"data"`
Locked bool `json:"locked"`
OrgID valuer.UUID `json:"org_id"`
Source string `json:"source"`
}
type LockUnlockDashboard struct {
@@ -81,11 +79,10 @@ func NewStorableDashboardFromDashboard(dashboard *Dashboard) (*StorableDashboard
OrgID: dashboard.OrgID,
Data: dashboard.Data,
Locked: dashboard.Locked,
Source: dashboard.Source,
}, nil
}
func NewDashboard(orgID valuer.UUID, createdBy string, data StorableDashboardData, source Source) (*Dashboard, error) {
func NewDashboard(orgID valuer.UUID, createdBy string, storableDashboardData StorableDashboardData) (*Dashboard, error) {
currentTime := time.Now()
return &Dashboard{
@@ -99,8 +96,8 @@ func NewDashboard(orgID valuer.UUID, createdBy string, data StorableDashboardDat
UpdatedBy: createdBy,
},
OrgID: orgID,
Data: data,
Source: string(source),
Data: storableDashboardData,
Locked: false,
}, nil
}
@@ -118,7 +115,6 @@ func NewDashboardFromStorableDashboard(storableDashboard *StorableDashboard) *Da
OrgID: storableDashboard.OrgID,
Data: storableDashboard.Data,
Locked: storableDashboard.Locked,
Source: storableDashboard.Source,
}
}
@@ -151,7 +147,6 @@ func NewGettableDashboardFromDashboard(dashboard *Dashboard) (*GettableDashboard
OrgID: dashboard.OrgID,
Data: dashboard.Data,
Locked: dashboard.Locked,
Source: dashboard.Source,
}, nil
}
@@ -283,12 +278,6 @@ func (dashboard *Dashboard) Update(ctx context.Context, updatableDashboard Updat
return nil
}
func (dashboard *Dashboard) OverwriteData(updatableDashboard UpdatableDashboard, updatedBy string) {
dashboard.UpdatedBy = updatedBy
dashboard.UpdatedAt = time.Now()
dashboard.Data = updatableDashboard
}
func (dashboard *Dashboard) CanLockUnlock(isAdmin bool, updatedBy string) error {
if dashboard.CreatedBy != updatedBy && !isAdmin {
return errors.Newf(errors.TypeForbidden, errors.CodeForbidden, "you are not authorized to lock/unlock this dashboard")

View File

@@ -66,7 +66,7 @@ func TestCanUpdate_MultipleDeletions_ByDiff(t *testing.T) {
initial := StorableDashboardData{
"widgets": makeTestWidgets("a", "b", "c"),
}
d, err := NewDashboard(orgID, "tester", initial, "")
d, err := NewDashboard(orgID, "tester", initial)
assert.NoError(t, err)
updated := StorableDashboardData{

View File

@@ -1,17 +0,0 @@
package dashboardtypes
import (
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/valuer"
)
type Source string
var SystemSources = []Source{}
// This will be fixed with upcoming pr of dashboard default value.
// No issue with migration or org creation; if reset endpoint is called we get a 400
// invalid_input response and no action is taken on dashboard.data.
func NewDefaultSystemDashboard(orgID valuer.UUID, source Source) (*Dashboard, error) {
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "no defaults registered for system dashboard source %s", source)
}

View File

@@ -13,8 +13,6 @@ type Store interface {
Get(context.Context, valuer.UUID, valuer.UUID) (*StorableDashboard, error)
GetBySource(context.Context, valuer.UUID, string) (*StorableDashboard, error)
GetPublic(context.Context, string) (*StorablePublicDashboard, error)
GetDashboardByOrgsAndPublicID(context.Context, []string, string) (*StorableDashboard, error)

View File

@@ -9,6 +9,7 @@ type TTLSetting struct {
bun.BaseModel `bun:"table:ttl_setting"`
types.Identifiable
types.TimeAuditable
types.UserAuditable
TransactionID string `bun:"transaction_id,type:text,notnull"`
TableName string `bun:"table_name,type:text,notnull"`
TTL int `bun:"ttl,notnull,default:0"`