fix(cache): use key versioning (#10657)

# Which Problems Are Solved

Cached object may have a different schema between Zitadel versions.

# How the Problems Are Solved

Use the curent build version in DB based cache connectors PostgreSQL and
Redis.

# Additional Changes

- Cleanup the ZitadelVersion field from the authz Instance
- Solve potential race condition on global variables in build package.

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/10648
- Obsoletes https://github.com/zitadel/zitadel/pull/10646
- Needs to be back-ported to v4 over
https://github.com/zitadel/zitadel/pull/10645

(cherry picked from commit f6f37d3a31)
This commit is contained in:
Tim Möhlmann
2025-09-15 12:51:54 +03:00
committed by Livio Spring
parent f9b3c1ef50
commit 6e90d4a927
8 changed files with 127 additions and 87 deletions

View File

@@ -68,9 +68,9 @@ func Test_redisCache_set(t *testing.T) {
},
},
assertions: func(t *testing.T, s *miniredis.Miniredis, objectID string) {
s.CheckGet(t, "0:one", objectID)
s.CheckGet(t, "1:foo", objectID)
s.CheckGet(t, "1:bar", objectID)
s.CheckGet(t, "VERSION:0:one", objectID)
s.CheckGet(t, "VERSION:1:foo", objectID)
s.CheckGet(t, "VERSION:1:bar", objectID)
assert.Empty(t, s.HGet(objectID, "expiry"))
assert.JSONEq(t, `{"ID":"one","Name":["foo","bar"]}`, s.HGet(objectID, "object"))
},
@@ -88,9 +88,9 @@ func Test_redisCache_set(t *testing.T) {
},
},
assertions: func(t *testing.T, s *miniredis.Miniredis, objectID string) {
s.CheckGet(t, "0:one", objectID)
s.CheckGet(t, "1:foo", objectID)
s.CheckGet(t, "1:bar", objectID)
s.CheckGet(t, "VERSION:0:one", objectID)
s.CheckGet(t, "VERSION:1:foo", objectID)
s.CheckGet(t, "VERSION:1:bar", objectID)
assert.Empty(t, s.HGet(objectID, "expiry"))
assert.JSONEq(t, `{"ID":"one","Name":["foo","bar"]}`, s.HGet(objectID, "object"))
assert.Positive(t, s.TTL(objectID))
@@ -115,9 +115,9 @@ func Test_redisCache_set(t *testing.T) {
},
},
assertions: func(t *testing.T, s *miniredis.Miniredis, objectID string) {
s.CheckGet(t, "0:one", objectID)
s.CheckGet(t, "1:foo", objectID)
s.CheckGet(t, "1:bar", objectID)
s.CheckGet(t, "VERSION:0:one", objectID)
s.CheckGet(t, "VERSION:1:foo", objectID)
s.CheckGet(t, "VERSION:1:bar", objectID)
assert.NotEmpty(t, s.HGet(objectID, "expiry"))
assert.JSONEq(t, `{"ID":"one","Name":["foo","bar"]}`, s.HGet(objectID, "object"))
assert.Positive(t, s.TTL(objectID))
@@ -141,9 +141,9 @@ func Test_redisCache_set(t *testing.T) {
},
},
assertions: func(t *testing.T, s *miniredis.Miniredis, objectID string) {
s.CheckGet(t, "0:one", objectID)
s.CheckGet(t, "1:foo", objectID)
s.CheckGet(t, "1:bar", objectID)
s.CheckGet(t, "VERSION:0:one", objectID)
s.CheckGet(t, "VERSION:1:foo", objectID)
s.CheckGet(t, "VERSION:1:bar", objectID)
assert.Empty(t, s.HGet(objectID, "expiry"))
assert.JSONEq(t, `{"ID":"one","Name":["foo","bar"]}`, s.HGet(objectID, "object"))
assert.Positive(t, s.TTL(objectID))
@@ -710,7 +710,7 @@ func prepareCache(t *testing.T, conf cache.Config, options ...func(*Config)) (ca
connector.Close()
server.Close()
})
c := NewCache[testIndex, string, *testObject](conf, connector, testDB, testIndices)
c := NewCache[testIndex, string, *testObject](conf, "VERSION", connector, testDB, testIndices)
return c, server
}