Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,13 @@ Listener Component
Evaluator-Upload Component
↓ (calls VMaaS /updates)
↓ (updates system_advisories)
↓ (updates advisory_account_data — legacy table, to be removed)
↓
[platform.remediation-updates.patch] (optional)
[platform.inventory.host-apps] (optional)
[patchman.advisory.update] Kafka Topic (changed advisory IDs)
↓
Aggregator Component
↓ (recounts from system_advisories, writes aggregates to account_advisory — new workspace-scoped table)
↓ (recounts from system_advisories, writes aggregates to account_advisory — a workspace-scoped table)
↓
[platform.notifications.ingress] (optional)
```
Expand Down
67 changes: 0 additions & 67 deletions aggregator/drift_check.go

This file was deleted.

61 changes: 0 additions & 61 deletions aggregator/drift_check_test.go

This file was deleted.

2 changes: 0 additions & 2 deletions aggregator/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ func processAdvisoryBatch(grouped map[int][]int64) {
continue
}

CheckAdvisoryDrift(rhAccountID, advisoryIDs)

if err := publishNewAdvisoryNotification(rhAccountID, advisoryIDs); err != nil {
utils.LogError("err", err, "rh_account_id", rhAccountID, "failed to publish new advisory notification")
}
Expand Down
1 change: 0 additions & 1 deletion aggregator/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ func TestBufferedEventsProcessedOnBatchThreshold(t *testing.T) {
utils.SkipWithoutDB(t)
core.SetupTestEnvironment()

assert.Nil(t, database.DB.Exec("SELECT refresh_advisory_caches(NULL, 1)").Error)
defer database.DeleteAccountAdvisoryByAccount(t, 1)

batchSize = 3
Expand Down
5 changes: 2 additions & 3 deletions aggregator/notifications_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ func TestPublishNewAdvisoryNotificationSuccess(t *testing.T) {
notificationsPublisher = nil
}()

// Backfill to populate account_advisory from system_advisories
assert.Nil(t, database.DB.Exec("SELECT backfill_account_advisory(1)").Error)
// populate account_advisory from system_advisories
assert.Nil(t, database.DB.Exec("SELECT refresh_account_advisory_caches_multi(NULL, 1)").Error)
defer database.DeleteAccountAdvisoryByAccount(t, 1)

// Advisory IDs 1-8 exist for rh_account_id=1 in test data
Expand All @@ -67,7 +67,6 @@ func TestPublishNewAdvisoryNotificationSuccess(t *testing.T) {
var notif ntf.Notification
assert.Nil(t, sonic.Unmarshal(mockWriter.Messages[0].Value, &notif))
assert.Equal(t, "org_1", notif.OrgID)
assert.Nil(t, notif.Context)
assert.NotEmpty(t, notif.Events)

// Verify advisories were marked as notified (count varies by workspace)
Expand Down
23 changes: 0 additions & 23 deletions base/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,3 @@ func OnConflictUpdateMulti(db *gorm.DB, keys []string, updateCols ...string) *go
}
return db.Clauses(onConflict)
}

type UpExpr struct {
Name string
Expr string
}

func OnConflictDoUpdateExpr(db *gorm.DB, keys []string, updateExprs ...UpExpr) *gorm.DB {
updateColsValues := make(map[string]interface{}, len(updateExprs))
for _, v := range updateExprs {
updateColsValues[v.Name] = v.Expr
}
conflictColumns := make([]clause.Column, len(keys))
for i, key := range keys {
conflictColumns[i] = clause.Column{Name: key}
}
if len(updateColsValues) > 0 {
return db.Clauses(clause.OnConflict{
Columns: conflictColumns,
DoUpdates: clause.Assignments(updateColsValues),
})
}
return db
}
139 changes: 0 additions & 139 deletions base/database/testing.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package database

import (
"app/base"
"app/base/models"
"app/base/utils"
"fmt"
Expand All @@ -27,18 +26,6 @@ func TestWorkspace1NamePtr() *string {
return &name
}

func DebugWithCachesCheck(part string, fun func()) {
fun()
validAfter, err := CheckCachesValidRet()
if err != nil {
utils.LogPanic("error", err, "Could not check validity of caches")
}

if !validAfter {
utils.LogPanic("part", part, "Cache mismatch created")
}
}

type key struct {
AccountID int
AdvisoryID int64
Expand All @@ -51,71 +38,6 @@ type advisoryCount struct {
SystemsApplicable int
}

func CheckCachesValidRet() (bool, error) {
valid := true
var aad []models.AdvisoryAccountData

tx := DB.WithContext(base.Context).Begin()
defer tx.Rollback()
err := tx.Set("gorm:query_option", "FOR SHARE OF advisory_account_data").
Order("rh_account_id, advisory_id").Find(&aad).Error
if err != nil {
return false, err
}
var counts []advisoryCount

err = tx.Select("si.rh_account_id, sa.advisory_id," +
"count(*) filter (where sa.status_id = 0) as systems_installable," +
"count(*) as systems_applicable").
Table("system_advisories sa").
Joins("JOIN system_inventory si ON sa.rh_account_id = si.rh_account_id AND sa.system_id = si.id").
Joins("JOIN system_patch spatch ON si.id = spatch.system_id AND si.rh_account_id = spatch.rh_account_id").
Where("si.stale = false AND spatch.last_evaluation IS NOT NULL").
Order("si.rh_account_id, sa.advisory_id").
Group("si.rh_account_id, sa.advisory_id").
Find(&counts).Error
if err != nil {
return false, err
}

cached := make(map[key][]int, len(aad))
calculated := make(map[key][]int, len(counts))

for _, val := range aad {
cached[key{val.RhAccountID, val.AdvisoryID}] = []int{val.SystemsInstallable, val.SystemsApplicable}
}
for _, val := range counts {
calculated[key{val.RhAccountID, val.AdvisoryID}] = []int{val.SystemsInstallable, val.SystemsApplicable}
}

crossCheckCache := func(a, b map[key][]int) {
for key, aCounts := range a {
bCounts := b[key]
if len(bCounts) == 0 {
bCounts = []int{0, 0}
}
for i, msg := range []string{"installable", "applicable"} {
if aCounts[i] != bCounts[i] {
utils.LogError("advisory_id", key.AdvisoryID, "account_id", key.AccountID,
"cached", aCounts[i], "calculated", bCounts[i], fmt.Sprintf("Cached %s counts mismatch", msg))
valid = false
}
}
}
}
crossCheckCache(cached, calculated)
crossCheckCache(calculated, cached)

tx.Commit()
return valid, nil
}

func CheckCachesValid(t *testing.T) {
valid, err := CheckCachesValidRet()
assert.Nil(t, err)
assert.True(t, valid)
}

func CheckAdvisoriesInDB(t *testing.T, advisories []string) []int64 {
var advisoryIDs []int64
err := DB.Model(models.AdvisoryMetadata{}).Where("name IN (?)", advisories).
Expand Down Expand Up @@ -183,43 +105,6 @@ func CheckSystemJustEvaluated(t *testing.T, inventoryID uuid.UUID, nIAll, nIEnh,
assert.Equal(t, thirdParty, patch.ThirdParty)
}

func CheckAdvisoriesAccountData(t *testing.T, rhAccountID int, advisoryIDs []int64, systemsInstallable int) {
var advisoryAccountData []models.AdvisoryAccountData
err := DB.Where("rh_account_id = ? AND advisory_id IN (?)", rhAccountID, advisoryIDs).
Find(&advisoryAccountData).Error
assert.Nil(t, err)

sum := 0
for _, item := range advisoryAccountData {
sum += item.SystemsInstallable
}
// covers both cases, when we have advisory_account_data stored with 0 systems_installable, and when we delete it
assert.Equal(t, systemsInstallable*len(advisoryIDs), sum, "sum of systems_installable does not match")
}

func CheckAdvisoriesAccountDataNotified(t *testing.T, rhAccountID int, advisoryIDs []int64, notified bool) {
var advisoryAccountData []models.AdvisoryAccountData
err := DB.Where("rh_account_id = ? AND advisory_id IN (?)", rhAccountID, advisoryIDs).
Find(&advisoryAccountData).Error
assert.Nil(t, err)

for _, item := range advisoryAccountData {
if notified {
assert.NotNil(t, item.Notified)
} else {
assert.Nil(t, item.Notified)
}
}
}

func CreateReportedAdvisories(reportedAdvisories []string, status []int) map[string]int {
reportedAdvisoriesMap := make(map[string]int, len(reportedAdvisories))
for i, adv := range reportedAdvisories {
reportedAdvisoriesMap[adv] = status[i]
}
return reportedAdvisoriesMap
}

func CreateStoredAdvisories(advisoryPatched []int64) map[string]models.SystemAdvisories {
systemAdvisoriesMap := make(map[string]models.SystemAdvisories, len(advisoryPatched))
for _, advisoryID := range advisoryPatched {
Expand All @@ -238,18 +123,6 @@ func CreateSystemAdvisories(t *testing.T, rhAccountID int, systemID int64, advis
CheckSystemAdvisories(t, systemID, advisoryIDs)
}

func CreateAdvisoryAccountData(t *testing.T, rhAccountID int, advisoryIDs []int64,
systemsInstallable int) {
for _, advisoryID := range advisoryIDs {
err := DB.Create(&models.AdvisoryAccountData{
AdvisoryID: advisoryID, RhAccountID: rhAccountID, SystemsInstallable: systemsInstallable,
// create same number of applicable and installable systems because installable is subset of applicable
SystemsApplicable: systemsInstallable}).Error
assert.Nil(t, err)
}
CheckAdvisoriesAccountData(t, rhAccountID, advisoryIDs, systemsInstallable)
}

func CreateSystemRepos(t *testing.T, rhAccountID int, systemID int64, repoIDs []int64) {
for _, repoID := range repoIDs {
assert.Nil(t, DB.Create(&models.SystemRepo{RhAccountID: int64(rhAccountID),
Expand Down Expand Up @@ -353,16 +226,6 @@ func DeleteAccountAdvisoryByAccount(t *testing.T, rhAccountID int) {
Delete(&models.AccountAdvisory{}).Error)
}

func DeleteAdvisoryAccountData(t *testing.T, rhAccountID int, advisoryIDs []int64) {
query := DB.Model(&models.AdvisoryAccountData{}).Where("rh_account_id = ? AND advisory_id IN (?)",
rhAccountID, advisoryIDs)
assert.Nil(t, query.Delete(&models.AdvisoryAccountData{}).Error)

var cnt int64
assert.Nil(t, query.Count(&cnt).Error)
assert.Equal(t, int64(0), cnt)
}

func DeleteSystemPackages(t *testing.T, accountID int, systemID int64, pkgIDs ...int64) {
query := DB.Model(&models.SystemPackage{}).Where("rh_account_id = ? AND system_id = ?", accountID, systemID)
if len(pkgIDs) > 0 {
Expand Down Expand Up @@ -395,9 +258,7 @@ func DeleteNewlyAddedPackages(t *testing.T) {
func DeleteNewlyAddedAdvisories(t *testing.T) {
query := DB.Model(models.AdvisoryMetadata{}).Where("id >= 100")
querySa := DB.Model(models.SystemAdvisories{}).Where("advisory_id >= 100")
queryAad := DB.Model(models.AdvisoryAccountData{}).Where("advisory_id >= 100")
assert.Nil(t, querySa.Delete(models.SystemAdvisories{}).Error)
assert.Nil(t, queryAad.Delete(models.AdvisoryAccountData{}).Error)
assert.Nil(t, query.Delete(models.AdvisoryMetadata{}).Error)
var cnt int64
assert.Nil(t, query.Count(&cnt).Error)
Expand Down
Loading
Loading