From ed96d839f0415cbeec4015a58a239f8dbec71081 Mon Sep 17 00:00:00 2001 From: Patrik Segedy Date: Wed, 3 Jan 2024 17:36:18 +0100 Subject: [PATCH] RHINENG-6298: avoid modification of data in vmaas cache --- evaluator/evaluate.go | 12 +++++++++-- evaluator/evaluate_test.go | 41 ++++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/evaluator/evaluate.go b/evaluator/evaluate.go index 4a2a72cec..6f40ae7f2 100644 --- a/evaluator/evaluate.go +++ b/evaluator/evaluate.go @@ -17,6 +17,7 @@ import ( "sync" "time" + "github.com/jinzhu/copier" "github.com/pkg/errors" "gorm.io/gorm" "gorm.io/gorm/clause" @@ -312,10 +313,13 @@ func getUpdatesData(ctx context.Context, tx *gorm.DB, system *models.SystemPlatf func getVmaasUpdates(ctx context.Context, tx *gorm.DB, system *models.SystemPlatform) (*vmaas.UpdatesV3Response, error) { + var vmaasDataCopy vmaas.UpdatesV3Response // first check if we have data in cache vmaasData, ok := memoryVmaasCache.Get(system.JSONChecksum) if ok { - return vmaasData, nil + // return copy of vmaasData to avoid modification of cached data e.g. by templates + copier.CopyWithOption(&vmaasDataCopy, vmaasData, copier.Option{DeepCopy: true}) + return &vmaasDataCopy, nil } updatesReq, err := tryGetVmaasRequest(system) if err != nil { @@ -343,7 +347,11 @@ func getVmaasUpdates(ctx context.Context, tx *gorm.DB, return nil, errors.Wrap(err, "vmaas API call failed") } - memoryVmaasCache.Add(system.JSONChecksum, vmaasData) + if memoryVmaasCache.enabled { + // store copy of vmaasData to cache to avoid modification of cached data e.g. by templates + copier.CopyWithOption(&vmaasDataCopy, vmaasData, copier.Option{DeepCopy: true}) + memoryVmaasCache.Add(system.JSONChecksum, &vmaasDataCopy) + } return vmaasData, nil } diff --git a/evaluator/evaluate_test.go b/evaluator/evaluate_test.go index d14a7544f..203bdcf8d 100644 --- a/evaluator/evaluate_test.go +++ b/evaluator/evaluate_test.go @@ -371,3 +371,44 @@ func TestGetUpdatesDataVmaas400(t *testing.T) { assert.Nil(t, err) assert.Nil(t, res) } + +func TestGetVmaasDataCached(t *testing.T) { + utils.SkipWithoutDB(t) + utils.SkipWithoutPlatform(t) + configure() + loadCache() + req := vmaas.UpdatesV3Request{ + PackageList: []string{"firefox-0:76.0.1-1.fc31.x86_64"}, RepositoryList: []string{"repo"}, + } + reqJSON, _ := json.Marshal(req) + reqString := string(reqJSON) + chsum := "123" + sp := models.SystemPlatform{VmaasJSON: &reqString, JSONChecksum: &chsum} + + var assertInstallable = func() (*vmaas.UpdatesV3Response, []vmaas.UpdatesV3ResponseAvailableUpdates) { + vmaasData, _ := getVmaasUpdates(context.Background(), database.Db, &sp) + updates := (*vmaasData.UpdateList)["firefox-0:76.0.1-1.fc31.x86_64"].GetAvailableUpdates() + assert.Equal(t, INSTALLABLE, updates[0].StatusID) + return vmaasData, updates + } + vmaasData, updates := assertInstallable() + + // modify update status id, change data returned by vmaas + var setApplicable = func() { + updates[0].StatusID = APPLICABLE + modifiedUpdateList := vmaas.UpdatesV3ResponseUpdateList{AvailableUpdates: &updates} + (*vmaasData.UpdateList)["firefox-0:76.0.1-1.fc31.x86_64"] = &modifiedUpdateList + updates = (*vmaasData.UpdateList)["firefox-0:76.0.1-1.fc31.x86_64"].GetAvailableUpdates() + assert.Equal(t, APPLICABLE, updates[0].StatusID) + } + setApplicable() + + // cached value mustn't be changed + vmaasData, updates = assertInstallable() + + // modify data again to change data returned from cache + setApplicable() + + // cached value mustn't be changed + assertInstallable() +} diff --git a/go.mod b/go.mod index 5f4449402..a52d23f1b 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a github.com/golang-migrate/migrate/v4 v4.16.2 github.com/hashicorp/golang-lru/v2 v2.0.7 + github.com/jinzhu/copier v0.4.0 github.com/joho/godotenv v1.5.1 github.com/lestrrat-go/backoff v1.0.1 github.com/lib/pq v1.10.9 diff --git a/go.sum b/go.sum index 027c6a124..e76e918ea 100644 --- a/go.sum +++ b/go.sum @@ -124,6 +124,8 @@ github.com/jackc/pgx/v5 v5.5.0 h1:NxstgwndsTRy7eq9/kqYc/BZh5w2hHJV86wjvO+1xPw= github.com/jackc/pgx/v5 v5.5.0/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=