Skip to content
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

feat: Purge ACP state on DB purge #3363

Merged
merged 8 commits into from
Jan 8, 2025
Merged

feat: Purge ACP state on DB purge #3363

merged 8 commits into from
Jan 8, 2025

Conversation

jsimnz
Copy link
Member

@jsimnz jsimnz commented Jan 8, 2025

Relevant issue(s)

Resolves #3358

Description

Crude implementation to purge the ACP state for LocalACP implementation (SourceHub ACP returns error at the moment). Basically it deletes the entire underlying KVStore and reinitializes it.

Tasks

  • I made sure the code is well commented, particularly hard-to-understand areas.
  • I made sure the repository-held documentation is changed accordingly.
  • I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in tools/configs/chglog/config.yml).
  • I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ...

How has this been tested?

Manually, also added unit tests. No current integration purge tests (afaik)

Specify the platform(s) on which this was tested:

  • (modify the list accordingly)
  • Arch Linux
  • Debian Linux
  • MacOS
  • Windows

@jsimnz jsimnz added feature New feature or request priority/high area/acp Related to the acp (access control) system labels Jan 8, 2025
@jsimnz jsimnz added this to the DefraDB v0.16 milestone Jan 8, 2025
@jsimnz jsimnz force-pushed the jsimnz/feat/acp-purge branch from f56117e to c781935 Compare January 8, 2025 15:59
acp/acp.go Outdated
Comment on lines 46 to 47
// DropAll purges the entire ACP state.
DropAll(ctx context.Context) error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: As mentioned on discord :P prefer ResetState over DropAll

Suggested change
// DropAll purges the entire ACP state.
DropAll(ctx context.Context) error
// ResetState resets the entire ACP state.
ResetState(ctx context.Context) error

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would Reset work, or do you prefer the full ResetState?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reset is fine too

@@ -105,6 +107,40 @@ func (l *ACPLocal) Close() error {
return l.manager.Terminate()
}

func (l *ACPLocal) DropAll(ctx context.Context) error {
err := l.Close()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: l.manager.Terminate() is safe to call close on even if it was already closed before?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea there might be an issue here, thanks for flagging

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved this, can you do another quick review on the last 2 commits. Added a flag to track if we're already closed so we don't duplicate the termination stuff. @shahzadlone

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed. Just left one suggestion

Comment on lines 131 to 214
func Test_LocalACP_InMemory_AddPolicy_CreatingSamePolicyAfterDropAllReturnsSameID(t *testing.T) {
ctx := context.Background()
localACP := NewLocalACP()

localACP.Init(ctx, "")
errStart := localACP.Start(ctx)
require.Nil(t, errStart)

policyID, errAddPolicy := localACP.AddPolicy(
ctx,
identity1,
validPolicy,
)
require.Nil(t, errAddPolicy)

require.Equal(
t,
validPolicyID,
policyID,
)

errDrop := localACP.DropAll(ctx)
require.Nil(t, errDrop)

// Since nothing is persisted should allow adding same policy again with same ID

policyID, errAddPolicy = localACP.AddPolicy(
ctx,
identity1,
validPolicy,
)
require.Nil(t, errAddPolicy)
require.Equal(
t,
validPolicyID,
policyID,
)

errClose := localACP.Close()
require.Nil(t, errClose)
}

func Test_LocalACP_Persistent_AddPolicy_CreatingSamePolicyAfterDropAllReturnsSameID(t *testing.T) {
ctx := context.Background()
localACP := NewLocalACP()

acpPath := t.TempDir()
localACP.Init(ctx, acpPath)
errStart := localACP.Start(ctx)
require.Nil(t, errStart)

policyID, errAddPolicy := localACP.AddPolicy(
ctx,
identity1,
validPolicy,
)
require.Nil(t, errAddPolicy)

require.Equal(
t,
validPolicyID,
policyID,
)

errDrop := localACP.DropAll(ctx)
require.Nil(t, errDrop)

// Since nothing is persisted should allow adding same policy again with same ID

policyID, errAddPolicy = localACP.AddPolicy(
ctx,
identity1,
validPolicy,
)
require.Nil(t, errAddPolicy)
require.Equal(
t,
validPolicyID,
policyID,
)

errClose := localACP.Close()
require.Nil(t, errClose)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Thanks for adding these!

Copy link
Collaborator

@fredcarle fredcarle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

policyID,
)

errDrop := localACP.DropAll(ctx)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Might be interesting to also test if calling this when acp is already closed (not started) is safe or errors/panics.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking this through, should we only allow dropping if it isn't closed yet?

Copy link
Member

@shahzadlone shahzadlone Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we will soon have option to turn acp off (which can be done only by authorized admin), as long as we also plan to (which I believe we do) gate the purge command also with authorized admin (AAC will use it's own separate local acp logic not mixed with this document access control logic), so it makes sense that the purge resets even if it's closed.

However happy to discuss further. We could also have a --force flag with purge that does the behavior of purging on close and otherwise a "safer" one that will error if acp is off (or is closed for whatever reason).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not forget that the purge command is a dev only feature so protecting it with Admin ACP doesn't really make sense.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not forget that the purge command is a dev only feature so protecting it with Admin ACP doesn't really make sense.

Kind of forgot about that. Do we still want dev only features when aac is implemented?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so yes. I would never want purge to be accessible by anyone on a production DB.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking this through, should we only allow dropping if it isn't closed yet?

Following up here. Decided we do want to make sure we're only "resetting" state after the ACP instance is closed, at the very least because it simplifies things, and produces less edge cases to cover compared to if we were resetting the state while the ACP engine is in use.

Copy link
Member

@shahzadlone shahzadlone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I still don't fancy the acp var on the node :P it is a minimal change.
Other nitpick highlighted is the renaming to Reset everywhere that "drop all" is used.

Rest all good :) cheers for sorting quickly

@jsimnz
Copy link
Member Author

jsimnz commented Jan 8, 2025

@shahzadlone

While I still don't fancy the acp var on the node :P it is a minimal change.

Agreed, in the spirit of the velocity experiment, Im going to power through and mark this as a follow up issue, that we can get some more feedback on how we might want to make this change more permanent, but for now its a minor change that can easily be fixed.

Comment on lines +216 to +248
func Test_LocalACP_InMemory_ResetStateAfterClose(t *testing.T) {
ctx := context.Background()
localACP := NewLocalACP()

localACP.Init(ctx, "")
errStart := localACP.Start(ctx)
require.Nil(t, errStart)

errClose := localACP.Close()
require.NoError(t, errClose)

errReset := localACP.ResetState(ctx)
require.NoError(t, errReset)
}

func Test_LocalACP_Persistent_ResetStateAfterClose(t *testing.T) {
acpPath := t.TempDir()
require.NotEqual(t, "", acpPath)

ctx := context.Background()
localACP := NewLocalACP()

localACP.Init(ctx, acpPath)
errStart := localACP.Start(ctx)
require.Nil(t, errStart)

errClose := localACP.Close()
require.NoError(t, errClose)

errReset := localACP.ResetState(ctx)
require.NoError(t, errReset)
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prase: thanks

@jsimnz jsimnz merged commit 43f2863 into develop Jan 8, 2025
41 of 42 checks passed
@jsimnz jsimnz deleted the jsimnz/feat/acp-purge branch January 8, 2025 21:32
Copy link

codecov bot commented Jan 8, 2025

Codecov Report

Attention: Patch coverage is 44.23077% with 29 lines in your changes missing coverage. Please review.

Project coverage is 78.30%. Comparing base (d0f5a54) to head (2abd202).
Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
acp/acp_local.go 42.42% 14 Missing and 5 partials ⚠️
node/node.go 46.67% 6 Missing and 2 partials ⚠️
acp/acp_source_hub.go 0.00% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #3363      +/-   ##
===========================================
- Coverage    78.51%   78.30%   -0.21%     
===========================================
  Files          392      392              
  Lines        35640    35688      +48     
===========================================
- Hits         27982    27943      -39     
- Misses        6033     6095      +62     
- Partials      1625     1650      +25     
Flag Coverage Δ
all-tests 78.30% <44.23%> (-0.21%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
acp/errors.go 90.15% <ø> (ø)
acp/source_hub_client.go 93.99% <100.00%> (+0.04%) ⬆️
acp/acp_source_hub.go 72.91% <0.00%> (-0.59%) ⬇️
node/node.go 55.32% <46.67%> (-2.05%) ⬇️
acp/acp_local.go 90.30% <42.42%> (-7.75%) ⬇️

... and 15 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d0f5a54...2abd202. Read the comment docs.

@shahzadlone
Copy link
Member

Bug bash: works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/acp Related to the acp (access control) system feature New feature or request priority/high
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ACP purge state
3 participants