-
Notifications
You must be signed in to change notification settings - Fork 105
[sql-44] firewalldb: add migration code for privacy mapper from kvdb to SQL #1092
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: kvstores-migration-PR
Are you sure you want to change the base?
[sql-44] firewalldb: add migration code for privacy mapper from kvdb to SQL #1092
Conversation
@ViktorTigerstrom - feel free to push a base branch to upstream & then target that so that this pr can just contain the commits that are relevant |
As the firewalldb migration will include more than just the migration of the kvstore data, we rename the migration tests that only migrate the kvstore data to make it clearer which tests only focus on migrating kv entries.
Currently, the migration tests for firewalldb only migrates the kv stores. In future commits, we will also migrate the privacy mapper and the actions in the firewalldb,. Before this commit, the expected results of the migrations tests could only be kv records, which will not be the case when we also migrate the privacy mapper and the actions. Therefore, we prepare the migration tests to expect more than just kv records. This commit introduces a new type of `expectedResult` type which the prep of the migration tests will use, which can specify more than just one type of expected result.
This commit introduces the migration logic for transitioning the privacy mapper store from kvdb to SQL. Note that as of this commit, the migration is not yet triggered by any production code, i.e. only tests execute the migration logic.
bbe2b90
to
9715313
Compare
Rebased this on the latest version of #1079, as that PR feels good to go, and this PR is therefore close to not being blocked by that PR (and therefore ready to review). |
Requested a review by both of you @ellemouton & @bitromortac, even though #1079 isn't merged yet, just so you know that it is ready for review once that's been merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
really really great work. Very clean 🔥
@@ -34,6 +34,11 @@ var ( | |||
testEntryValue = []byte{1, 2, 3} | |||
) | |||
|
|||
// expectedResult represents the expected result of a migration test. | |||
type expectedResult struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very nice 🙏
privPairs, err := collectPrivacyPairs(ctx, kvStore, sqlTx) | ||
if err != nil { | ||
return fmt.Errorf("error migrating privacy mapper store: %w", | ||
err) | ||
} | ||
|
||
// 2) Insert all collected privacy pairs into the SQL database. | ||
err = insertPrivacyPairs(ctx, sqlTx, privPairs) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we may want to tests the performance of this one as i think unlike the kv-store db, this one could be quite populated.
So for this one it might make sense to migrate on the fly instead of collecting everything in memory first.
_, err := sqlTx.GetPseudoForReal( | ||
ctx, sqlc.GetPseudoForRealParams{ | ||
GroupID: groupID, | ||
RealVal: realVal, | ||
}, | ||
) | ||
if err == nil { | ||
return fmt.Errorf("duplicate privacy pair %s:%s: %w", | ||
realVal, pseudoVal, ErrDuplicatePseudoValue) | ||
} else if !errors.Is(err, sql.ErrNoRows) { | ||
return err | ||
} | ||
|
||
_, err = sqlTx.GetRealForPseudo( | ||
ctx, sqlc.GetRealForPseudoParams{ | ||
GroupID: groupID, | ||
PseudoVal: pseudoVal, | ||
}, | ||
) | ||
if err == nil { | ||
return fmt.Errorf("duplicate privacy pair %s:%s: %w", | ||
realVal, pseudoVal, ErrDuplicatePseudoValue) | ||
} else if !errors.Is(err, sql.ErrNoRows) { | ||
return err | ||
} | ||
|
||
err = sqlTx.InsertPrivacyPair( | ||
ctx, sqlc.InsertPrivacyPairParams{ | ||
GroupID: groupID, | ||
RealVal: realVal, | ||
PseudoVal: pseudoVal, | ||
}, | ||
) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we not potentially do this in one go with a single query that has a conflict rule?
if realBkt := bkt.Bucket(realToPseudoKey); realBkt != nil { | ||
realToPseudoRes, err = collectPairs(realBkt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just checking: do we have a test somewhere that makes sure that things dont fail on an empty kvdb?
kvEntries: fn.Some(insertedEntries), | ||
// No privacy pairs are inserted in this test. | ||
privPairs: fn.None[privacyPairs](), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should have a test that includes both
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Only have a couple of nits 🚀
@@ -34,6 +34,11 @@ var ( | |||
testEntryValue = []byte{1, 2, 3} | |||
) | |||
|
|||
// expectedResult represents the expected result of a migration test. | |||
type expectedResult struct { | |||
kvEntries fn.Option[[]*kvEntry] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it necessary to have an option type here, as an empty []*kvEntry
already signals that, not? (also for the pair data)
@@ -213,6 +218,20 @@ func TestFirewallDBMigration(t *testing.T) { | |||
} | |||
} | |||
|
|||
// The assertMigrationResults function will currently assert that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'd rather not put comments of what will happen in the future, because it may add confusion for somebody who's not involved in the process and it also may never happen, or we forget to update the comment
@@ -87,10 +92,14 @@ func MigrateFirewallDBToSQL(ctx context.Context, kvStore *bbolt.DB, | |||
return err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Note that this migration currently only migrates the kvstores, but will be
// extended in the future to also migrate the privacy mapper and action stores.
this is also an example of a "future" comment, where the comment wasn't updated
} | ||
|
||
// collectPrivacyPairs collects all privacy pairs from the KV store and | ||
// returns them as the privacyPairs type alias. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitty: and returns them as the privacyPairs type alias.
I'd leave that away, as it's obvious from the function signature
_, err := sqlTx.GetPseudoForReal( | ||
ctx, sqlc.GetPseudoForRealParams{ | ||
GroupID: groupID, | ||
RealVal: realVal, | ||
}, | ||
) | ||
if err == nil { | ||
return fmt.Errorf("duplicate privacy pair %s:%s: %w", | ||
realVal, pseudoVal, ErrDuplicatePseudoValue) | ||
} else if !errors.Is(err, sql.ErrNoRows) { | ||
return err | ||
} | ||
|
||
_, err = sqlTx.GetRealForPseudo( | ||
ctx, sqlc.GetRealForPseudoParams{ | ||
GroupID: groupID, | ||
PseudoVal: pseudoVal, | ||
}, | ||
) | ||
if err == nil { | ||
return fmt.Errorf("duplicate privacy pair %s:%s: %w", | ||
realVal, pseudoVal, ErrDuplicatePseudoValue) | ||
} else if !errors.Is(err, sql.ErrNoRows) { | ||
return err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are those checks necessary as they look to be covered by collectGroupPairs
?
|
||
// multiSessionsOnePrivPairs inserts 1 session with 1 privacy pair into the | ||
// boltDB. | ||
func oneSessionAndPrivPair(t *testing.T, ctx context.Context, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: we could use createPrivacyPairs
directly
realKey := fmt.Sprintf("real-%d-%d", i, j) | ||
pseudoKey := fmt.Sprintf("pseudo-%d-%d", i, j) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it add anything if we'd let real/pseudo keys be the same for the sessions, to leave i
away?
Based on the branch of #1079, to only show the relevant commits.
This PR introduces the migration logic for transitioning the privacy mapper from kvdb to SQL.
Note that as of this PR, the migration is not yet triggered by any production code, i.e. only tests execute the migration logic.
I will rebase this on the new version of #1079, once the current feedback has been addressed after we agree on the approach there.
As this PR is heavily dependent on #1079, this is blocked on the dependent PR until it has been merged. This is therefore not ready for review.
Part of #917