From d3bef31116e3ce198a6baeb09d067b4e17bdd2d7 Mon Sep 17 00:00:00 2001 From: Aditya Thebe Date: Tue, 5 May 2026 13:56:38 +0545 Subject: [PATCH 1/2] feat(config): scope property updates by creator Config item property writes previously replaced the whole JSON array, so scraper updates could clobber manual properties or properties from other scrapers. Route scraper property writes through duty's creator-scoped update helper. Scraper updates now replace only their own property slice, preserve other creators and legacy properties, and send empty observed properties to remove stale scraper-owned entries. --- db/config.go | 10 +++- db/models/config_item.go | 50 +++++++++---------- db/update.go | 102 +++++++++++++++++++++++++++++---------- go.mod | 12 +---- go.sum | 18 ------- 5 files changed, 113 insertions(+), 79 deletions(-) diff --git a/db/config.go b/db/config.go index b7ee5724c..66e87a34b 100644 --- a/db/config.go +++ b/db/config.go @@ -147,7 +147,6 @@ func NewConfigItemFromResult(ctx api.ScrapeContext, result v1.ScrapeResult) (*mo Name: &result.Name, Source: &result.Source, Labels: (*types.JSONStringMap)(&result.Labels), - Properties: &result.Properties, Config: &dataStr, Ready: result.Ready, Parents: result.Parents, @@ -160,6 +159,15 @@ func NewConfigItemFromResult(ctx api.ScrapeContext, result v1.ScrapeResult) (*mo ci.ScraperID = nil } + // Scraper-owned config results always express the scraper's current property slice. + // A nil/empty result.Properties therefore means "the scraper now owns zero properties" + // and must remove stale scraper-created properties while preserving user/other-scraper properties. + if ci.ScraperID != nil && *ci.ScraperID != uuid.Nil { + ci.Properties = lo.ToPtr(dutyModels.NewOwnedProperties(result.Properties)) + } else if result.Properties != nil { + ci.Properties = lo.ToPtr(dutyModels.NewOwnedProperties(result.Properties)) + } + ci.Tags = types.JSONStringMap(result.Tags) // If the config result hasn't specified an id for the config, // we try to use the external id as the primary key of the config item. diff --git a/db/models/config_item.go b/db/models/config_item.go index ff189818a..bac39da1a 100644 --- a/db/models/config_item.go +++ b/db/models/config_item.go @@ -17,31 +17,31 @@ import ( // ConfigItem represents the config item database table // Deprecated: Use models.ConfigItem from duty. type ConfigItem struct { - ID string `gorm:"primaryKey;unique_index;not null;column:id;default:generate_ulid()" json:"id" ` - ScraperID *uuid.UUID `gorm:"column:scraper_id;default:null" json:"scraper_id,omitempty"` - ConfigClass string `gorm:"column:config_class;default:''" json:"config_class" ` - ExternalID pq.StringArray `gorm:"column:external_id;type:[]text" json:"external_id,omitempty" ` - Type string `gorm:"column:type" json:"type,omitempty" ` - Status *string `gorm:"column:status;default:null" json:"status,omitempty" ` - Ready bool `json:"ready,omitempty" ` - Health *models.Health `json:"health,omitempty"` - Name *string `gorm:"column:name;default:null" json:"name,omitempty" ` - Description *string `gorm:"column:description;default:null" json:"description,omitempty" ` - Config *string `gorm:"column:config;default:null" json:"config,omitempty" ` - Source *string `gorm:"column:source;default:null" json:"source,omitempty" ` - ParentID *string `gorm:"column:parent_id;default:null" json:"parent_id,omitempty"` - Path string `gorm:"column:path;default:null" json:"path,omitempty"` - CostPerMinute float64 `gorm:"column:cost_per_minute;default:null" json:"cost_per_minute,omitempty"` - CostTotal1d float64 `gorm:"column:cost_total_1d;default:null" json:"cost_total_1d,omitempty"` - CostTotal7d float64 `gorm:"column:cost_total_7d;default:null" json:"cost_total_7d,omitempty"` - CostTotal30d float64 `gorm:"column:cost_total_30d;default:null" json:"cost_total_30d,omitempty"` - Labels *types.JSONStringMap `gorm:"column:labels;default:null" json:"labels,omitempty"` - Tags types.JSONStringMap `gorm:"column:tags;default:null" json:"tags,omitempty"` - Properties *types.Properties `gorm:"column:properties;default:null" json:"properties,omitempty"` - CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` - UpdatedAt *time.Time `gorm:"column:updated_at;autoUpdateTime:false;<-:update" json:"updated_at"` - DeletedAt *time.Time `gorm:"column:deleted_at" json:"deleted_at"` - DeleteReason v1.ConfigDeleteReason `gorm:"column:delete_reason" json:"delete_reason"` + ID string `gorm:"primaryKey;unique_index;not null;column:id;default:generate_ulid()" json:"id" ` + ScraperID *uuid.UUID `gorm:"column:scraper_id;default:null" json:"scraper_id,omitempty"` + ConfigClass string `gorm:"column:config_class;default:''" json:"config_class" ` + ExternalID pq.StringArray `gorm:"column:external_id;type:[]text" json:"external_id,omitempty" ` + Type string `gorm:"column:type" json:"type,omitempty" ` + Status *string `gorm:"column:status;default:null" json:"status,omitempty" ` + Ready bool `json:"ready,omitempty" ` + Health *models.Health `json:"health,omitempty"` + Name *string `gorm:"column:name;default:null" json:"name,omitempty" ` + Description *string `gorm:"column:description;default:null" json:"description,omitempty" ` + Config *string `gorm:"column:config;default:null" json:"config,omitempty" ` + Source *string `gorm:"column:source;default:null" json:"source,omitempty" ` + ParentID *string `gorm:"column:parent_id;default:null" json:"parent_id,omitempty"` + Path string `gorm:"column:path;default:null" json:"path,omitempty"` + CostPerMinute float64 `gorm:"column:cost_per_minute;default:null" json:"cost_per_minute,omitempty"` + CostTotal1d float64 `gorm:"column:cost_total_1d;default:null" json:"cost_total_1d,omitempty"` + CostTotal7d float64 `gorm:"column:cost_total_7d;default:null" json:"cost_total_7d,omitempty"` + CostTotal30d float64 `gorm:"column:cost_total_30d;default:null" json:"cost_total_30d,omitempty"` + Labels *types.JSONStringMap `gorm:"column:labels;default:null" json:"labels,omitempty"` + Tags types.JSONStringMap `gorm:"column:tags;default:null" json:"tags,omitempty"` + Properties *models.OwnedProperties `gorm:"column:properties;default:null" json:"properties,omitempty"` + CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` + UpdatedAt *time.Time `gorm:"column:updated_at;autoUpdateTime:false;<-:update" json:"updated_at"` + DeletedAt *time.Time `gorm:"column:deleted_at" json:"deleted_at"` + DeleteReason v1.ConfigDeleteReason `gorm:"column:delete_reason" json:"delete_reason"` Parents []v1.ConfigExternalKey `gorm:"-" json:"parents,omitempty"` Children []v1.ConfigExternalKey `gorm:"-" json:"children,omitempty"` diff --git a/db/update.go b/db/update.go index 8155c259b..d964bd058 100644 --- a/db/update.go +++ b/db/update.go @@ -109,18 +109,6 @@ func mapStringEqual(a, b map[string]string) bool { return true } -func mapEqual(a, b map[string]any) bool { - if len(a) != len(b) { - return false - } - for k, v := range a { - if b[k] != v { - return false - } - } - return true -} - func updateCI(ctx api.ScrapeContext, summary *v1.ScrapeSummary, result *v1.ScrapeResult, ci, existing *models.ConfigItem) (bool, []*models.ConfigChange, error) { ci.ID = existing.ID updates := make(map[string]any) @@ -221,16 +209,51 @@ func updateCI(ctx api.ScrapeContext, summary *v1.ScrapeSummary, result *v1.Scrap summary.AddWarning(ci.Type, fmt.Sprintf("updated scraper_id of config[%s] from %s to %s", ci, existing.ScraperID, ci.ScraperID)) } - if ci.Properties != nil && len(*ci.Properties) > 0 && (existing.Properties == nil || !mapEqual(ci.Properties.AsMap(), existing.Properties.AsMap())) { - updates["properties"] = *ci.Properties - } + // nil properties mean "not observed / no opinion". + // empty properties mean "observed and now owns zero properties", so remove this creator's slice. + propertyUpdateNeeded := ci.Properties != nil - if len(updates) == 0 { + if len(updates) == 0 && !propertyUpdateNeeded { return false, changes, nil } - if err := ctx.DutyContext().DB().Model(ci).Updates(updates).Error; err != nil { - return false, nil, errors.Wrapf(dutydb.ErrorDetails(err), "unable to update config item: %s", ci) + fieldsChanged := len(updates) > 0 + propertyChanged := false + if err := ctx.DutyContext().DB().Transaction(func(tx *gorm.DB) error { + if len(updates) > 0 { + if err := tx.Model(ci).Updates(updates).Error; err != nil { + return dutydb.ErrorDetails(err) + } + } + + if propertyUpdateNeeded { + createdBy := ctx.ScraperID() + if ci.ScraperID != nil && *ci.ScraperID != uuid.Nil { + createdBy = ci.ScraperID.String() + } + if createdBy == "" { + return nil + } + + configID, err := uuid.Parse(ci.ID) + if err != nil { + return fmt.Errorf("invalid config id %q: %w", ci.ID, err) + } + createdByID, err := uuid.Parse(createdBy) + if err != nil { + return fmt.Errorf("invalid property creator id %q: %w", createdBy, err) + } + + result, err := dutyModels.UpdateConfigItemProperties(tx, configID, dutyModels.PropertyCreatorTypeScraper, createdByID, ci.Properties.AsProperties()) + if err != nil { + return dutydb.ErrorDetails(err) + } + ci.Properties = &result.Properties + propertyChanged = result.Changed + } + return nil + }); err != nil { + return false, nil, errors.Wrapf(err, "unable to update config item: %s", ci) } if isDeleted { @@ -241,7 +264,7 @@ func updateCI(ctx api.ScrapeContext, summary *v1.ScrapeSummary, result *v1.Scrap ).Add(1) } - return true, changes, nil + return fieldsChanged || propertyChanged, changes, nil } func shouldExcludeChange(ctx api.ScrapeContext, result *v1.ScrapeResult, changeResult v1.ChangeResult) (bool, error) { @@ -576,13 +599,42 @@ func saveResults(ctx api.ScrapeContext, results []v1.ScrapeResult) (v1.ScrapeSum summary.AddChangeSummary(configType, cs) } - // NOTE: On duplicate primary key do nothing - // because an incremental scraper might have already inserted the config item. - if err := ctx.DB(). - Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "id"}}, DoNothing: true}). - CreateInBatches(extractResult.newConfigs, configItemsBulkInsertSize).Error; err != nil { - return summary, ctx.Oops().Wrapf(dutydb.ErrorDetails(err), "failed to create config items") + newConfigProperties := map[string]dutyModels.OwnedProperties{} + for _, config := range extractResult.newConfigs { + if config.Properties != nil && scraperID != nil && *scraperID != uuid.Nil { + newConfigProperties[config.ID] = *config.Properties + config.Properties = nil + } } + + if err := ctx.DB().Transaction(func(tx *gorm.DB) error { + // NOTE: On duplicate primary key do nothing + // because an incremental scraper might have already inserted the config item. + if err := tx. + Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "id"}}, DoNothing: true}). + CreateInBatches(extractResult.newConfigs, configItemsBulkInsertSize).Error; err != nil { + return dutydb.ErrorDetails(err) + } + + for _, config := range extractResult.newConfigs { + if props, ok := newConfigProperties[config.ID]; ok { + configID, err := uuid.Parse(config.ID) + if err != nil { + return fmt.Errorf("invalid config id %q: %w", config.ID, err) + } + + result, err := dutyModels.UpdateConfigItemProperties(tx, configID, dutyModels.PropertyCreatorTypeScraper, *scraperID, props.AsProperties()) + if err != nil { + return dutydb.ErrorDetails(err) + } + config.Properties = &result.Properties + } + } + return nil + }); err != nil { + return summary, ctx.Oops().Wrapf(err, "failed to create config items") + } + for _, config := range extractResult.newConfigs { summary.AddInserted(config.Type) ctx.TempCache().Insert(*config) diff --git a/go.mod b/go.mod index 958ff2ad6..04f43fa95 100644 --- a/go.mod +++ b/go.mod @@ -163,12 +163,10 @@ require ( github.com/aws/aws-sdk-go-v2/service/kms v1.49.5 // indirect github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect - github.com/buger/jsonparser v1.1.2 // indirect github.com/casbin/casbin/v2 v2.135.0 // indirect github.com/casbin/casbin/v3 v3.8.1 // indirect github.com/casbin/gorm-adapter/v3 v3.41.0 // indirect @@ -270,7 +268,6 @@ require ( github.com/hashicorp/hcl/v2 v2.24.0 // indirect github.com/henvic/httpretty v0.1.4 // indirect github.com/hirochachacha/go-smb2 v1.1.0 // indirect - github.com/invopop/jsonschema v0.13.0 // indirect github.com/itchyny/gojq v0.12.19 // indirect github.com/itchyny/timefmt-go v0.1.8 // indirect github.com/jackc/pgerrcode v0.0.0-20250907135507-afb5586c32a6 // indirect @@ -295,7 +292,6 @@ require ( github.com/lrita/cmap v0.0.0-20231108122212-cb084a67f554 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect - github.com/mailru/easyjson v0.9.1 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/microsoft/kiota-abstractions-go v1.9.4 // indirect github.com/microsoft/kiota-authentication-azure-go v1.3.1 // indirect @@ -360,12 +356,8 @@ require ( github.com/vadimi/go-http-ntlm v1.0.3 // indirect github.com/vadimi/go-http-ntlm/v2 v2.5.0 // indirect github.com/vadimi/go-ntlm v1.2.1 // indirect - github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xuri/efp v0.0.1 // indirect @@ -523,11 +515,11 @@ require ( // replace github.com/flanksource/clicky => ../clicky // replace github.com/flanksource/commons => ../commons // replace github.com/flanksource/deps => ../deps -// replace github.com/flanksource/duty => ../duty - // replace github.com/flanksource/gomplate/v3 => ../gomplate // replace github.com/flanksource/ketall => ../ketall // replace github.com/flanksource/postq => ../postq // replace github.com/flanksource/is-healthy => ../is-healthy +replace github.com/flanksource/duty => ../duty + replace github.com/glebarez/sqlite => github.com/clarkmcc/gorm-sqlite v0.0.0-20240426202654-00ed082c0311 diff --git a/go.sum b/go.sum index e11f76a14..0777ef457 100644 --- a/go.sum +++ b/go.sum @@ -339,8 +339,6 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.3.1 h1:LV+qyBQ2pqe0u42ZsUEtPiCaUoqgA9gYRDs3vj1nolY= github.com/aymanbagabas/go-udiff v0.3.1/go.mod h1:G0fsKmG+P6ylD0r6N/KgQD/nWzgfnl8ZBcNLgcbrw8E= -github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= -github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -357,8 +355,6 @@ github.com/bmatcuk/doublestar/v4 v4.10.0 h1:zU9WiOla1YA122oLM6i4EXvGW62DvKZVxIe6 github.com/bmatcuk/doublestar/v4 v4.10.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk= -github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/cactus/go-statsd-client/statsd v0.0.0-20200423205355-cb0885a1018c/go.mod h1:l/bIBLeOl9eX+wxJAzxS4TveKRtAqlyDpHjhkfO0MEI= github.com/casbin/casbin/v2 v2.135.0 h1:6BLkMQiGotYyS5yYeWgW19vxqugUlvHFkFiLnLR/bxk= github.com/casbin/casbin/v2 v2.135.0/go.mod h1:FmcfntdXLTcYXv/hxgNntcRPqAbwOG9xsism0yXT+18= @@ -506,8 +502,6 @@ github.com/flanksource/commons v1.51.4 h1:ys3O4g0exWoz/viKf9vwTUItTkP/RgP1jORooh github.com/flanksource/commons v1.51.4/go.mod h1:XXLA39QGuFUyqIK19W5oDCIZDinLzFyFcGj83ZkyOfo= github.com/flanksource/deps v1.0.28 h1:mm7l7WjzLbkj2aFrgnlMaRizp+j+0x22TvtwXzRlFtE= github.com/flanksource/deps v1.0.28/go.mod h1:2YRfP32WZrMxGVMYV51RlVHZfgerxf8DT3TqSgjzmTQ= -github.com/flanksource/duty v1.0.1301 h1:RfuBlJ5G+NMLR0erw4Y/axAzjM4Rr7YM151tljmWs3s= -github.com/flanksource/duty v1.0.1301/go.mod h1:aH4xdGF3brwBiOKUEFsspgu8U7tBiJOZDXrEqB3OMtc= github.com/flanksource/gomplate/v3 v3.24.79 h1:T5Ls0tjsnDhcV/dQWjrm2UpHiwOhytDLmYDSF0O6p3Q= github.com/flanksource/gomplate/v3 v3.24.79/go.mod h1:RzIg+YwNQI0eUV61LtqmhNN2Qw8ebm1cGa6IhNQmkWE= github.com/flanksource/is-healthy v1.0.87 h1:wSK9wI9tu//gdKO9JxyZe8ZQ5H7MCpwG17KdbWaiMeM= @@ -818,8 +812,6 @@ github.com/hirochachacha/go-smb2 v1.1.0/go.mod h1:8F1A4d5EZzrGu5R7PU163UcMRDJQl4 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= -github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/itchyny/gojq v0.12.19 h1:ttXA0XCLEMoaLOz5lSeFOZ6u6Q3QxmG46vfgI4O0DEs= github.com/itchyny/gojq v0.12.19/go.mod h1:5galtVPDywX8SPSOrqjGxkBeDhSxEW1gSxoy7tn1iZY= github.com/itchyny/timefmt-go v0.1.8 h1:1YEo1JvfXeAHKdjelbYr/uCuhkybaHCeTkH8Bo791OI= @@ -932,8 +924,6 @@ github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIi github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= -github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= @@ -1240,8 +1230,6 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= -github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= @@ -1249,12 +1237,6 @@ github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= From 82d8b7e39c34312be56f450f53fb90d8e16686f0 Mon Sep 17 00:00:00 2001 From: Aditya Thebe Date: Thu, 30 Apr 2026 11:27:41 +0545 Subject: [PATCH 2/2] update benchmark --- bench/config_items_save_results_bench_test.go | 18 ++++++++++++++++++ go.mod | 4 ++-- go.sum | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/bench/config_items_save_results_bench_test.go b/bench/config_items_save_results_bench_test.go index f822adb08..652c60b64 100644 --- a/bench/config_items_save_results_bench_test.go +++ b/bench/config_items_save_results_bench_test.go @@ -11,6 +11,7 @@ import ( v1 "github.com/flanksource/config-db/api/v1" "github.com/flanksource/config-db/db" dutyModels "github.com/flanksource/duty/models" + "github.com/flanksource/duty/types" "github.com/google/uuid" ) @@ -202,12 +203,29 @@ func buildScrapeResults(size int, dataset string, revision int) []v1.ScrapeResul "port": 8080, }, }, + Properties: buildScrapeResultProperties(revision), }) } return results } +func buildScrapeResultProperties(revision int) types.Properties { + payload := strings.Repeat("x", 16*1024) + properties := make(types.Properties, 0, 6) + for i := range 6 { + properties = append(properties, &types.Property{ + Name: fmt.Sprintf("bench-property-%d", i), + Label: fmt.Sprintf("Bench Property %d", i), + Type: "text", + Text: fmt.Sprintf("%s-%d-%d", payload, revision, i), + Tooltip: fmt.Sprintf("bench property tooltip %d", i), + Order: i, + }) + } + return properties +} + func cleanupBenchRows(tb testing.TB, scraperID uuid.UUID) { tb.Helper() diff --git a/go.mod b/go.mod index 04f43fa95..67a9c0f28 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/flanksource/clicky v1.21.8 github.com/flanksource/commons v1.51.4 github.com/flanksource/deps v1.0.28 - github.com/flanksource/duty v1.0.1301 + github.com/flanksource/duty v1.0.1302-0.20260505080647-4f6025d97824 github.com/flanksource/gomplate/v3 v3.24.79 github.com/flanksource/is-healthy v1.0.87 github.com/flanksource/ketall v1.1.9 @@ -520,6 +520,6 @@ require ( // replace github.com/flanksource/postq => ../postq // replace github.com/flanksource/is-healthy => ../is-healthy -replace github.com/flanksource/duty => ../duty +// replace github.com/flanksource/duty => ../duty replace github.com/glebarez/sqlite => github.com/clarkmcc/gorm-sqlite v0.0.0-20240426202654-00ed082c0311 diff --git a/go.sum b/go.sum index 0777ef457..9d33514aa 100644 --- a/go.sum +++ b/go.sum @@ -502,6 +502,8 @@ github.com/flanksource/commons v1.51.4 h1:ys3O4g0exWoz/viKf9vwTUItTkP/RgP1jORooh github.com/flanksource/commons v1.51.4/go.mod h1:XXLA39QGuFUyqIK19W5oDCIZDinLzFyFcGj83ZkyOfo= github.com/flanksource/deps v1.0.28 h1:mm7l7WjzLbkj2aFrgnlMaRizp+j+0x22TvtwXzRlFtE= github.com/flanksource/deps v1.0.28/go.mod h1:2YRfP32WZrMxGVMYV51RlVHZfgerxf8DT3TqSgjzmTQ= +github.com/flanksource/duty v1.0.1302-0.20260505080647-4f6025d97824 h1:mtV+NQPUvg1rNx5GftWDfFuMGXqBp6o1j09pPGTakwQ= +github.com/flanksource/duty v1.0.1302-0.20260505080647-4f6025d97824/go.mod h1:aH4xdGF3brwBiOKUEFsspgu8U7tBiJOZDXrEqB3OMtc= github.com/flanksource/gomplate/v3 v3.24.79 h1:T5Ls0tjsnDhcV/dQWjrm2UpHiwOhytDLmYDSF0O6p3Q= github.com/flanksource/gomplate/v3 v3.24.79/go.mod h1:RzIg+YwNQI0eUV61LtqmhNN2Qw8ebm1cGa6IhNQmkWE= github.com/flanksource/is-healthy v1.0.87 h1:wSK9wI9tu//gdKO9JxyZe8ZQ5H7MCpwG17KdbWaiMeM=