Skip to content

Conversation

@jmckenzie-dev
Copy link
Contributor

No description provided.

@jmckenzie-dev jmckenzie-dev force-pushed the cassandra-16958 branch 2 times, most recently from afe050f to 50c0199 Compare January 10, 2022 21:10
bdeggleston and others added 2 commits January 11, 2022 12:10
Patch by Blake Eggleston; reviewed by Sam Tunnicliffe, Jason Brown, and xxxx for CASSANDRA-16958

Co-authored by: Blake Eggleston <bdeggleston@gmail.com>
Co-authored by: Josh McKenzie <jmckenzie@apache.org>
private static final Logger logger = LoggerFactory.getLogger(AuthCacheService.class);
public static final AuthCacheService instance = new AuthCacheService();

private final Set<AuthCache<?, ?>> caches = new HashSet<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

A few questions around this caches state and how it's protected...

The first thing I noticed is that warmCaches() isn't synchronized, so we might be left open to a ConcurrentModificationException. Then I started looking at the actual sources of possible concurrent access to caches. It seems like the primary startup pathway isn't really a concern, but the nodetool commands for resuming bootstrap and join might be, since they hit doAuthSetup(). It that's the case, the warmCaches() issue above stands, but also only Roles.init() seems to protect us against double-adding its cache. (For AuthenticatedUser, that would be permissionsCache and networkPermissionsCache.) Then again, registering a few more things to caches on those nodetool commands might no matter, given warmCaches() is only called from CassandraDaemon#setup(). Finally, Roles.init() and PasswordAuthenticator#setup() aren't synchronized, so their cache fields aren't protected.

Copy link
Contributor

Choose a reason for hiding this comment

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

...and as I finished writing that, I see that doAuthSetup() is guarded by authSetupCalled and should only happen once :)

So unless we're going to hit warmCaches() in CassandraDaemon#setup() somehow after a nodetool command, I'm not sure if there's a thread-safety issue at all. If that is possible, just throwing Collections.synchronizedSet() on AuthCacheService#caches would probably be sufficient (without synchronizing any methods here).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we should protect against dupe adding from all 4 sources as well as synchronize on the init and reg call. I'll whip that up and get another commit for that; forgot to come back to this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pushed a commit that hopefully addresses this. Running CI now.

Copy link
Contributor

Choose a reason for hiding this comment

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

AuthCacheService is at least thread-safe now, regardless of whether or not that's strictly necessary. The only thing that's still a bit odd to me is that the nodetool commands (unless I'm misreading something) can register caches that just sort of sit in caches forever, being neither removed nor warmed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That... does not seem like something we want. Let me take a look.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok. Taking a page out of the guard around doAuthSetup to codify the intended usage of the method.

*/
public volatile int validation_preview_purge_head_start_in_sec = 60 * 60;

public boolean auth_cache_warming_enabled = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Did the original Jira description mention making this opt-in?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm. Nope, should be optional. Changed to false and added to cassandra.yaml

roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_A, AuthTestUtils.getLoginRoleOptions());
roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_B, AuthTestUtils.getLoginRoleOptions());
roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_A, AuthTestUtils.getLoginRoleOptions());
roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_B, AuthTestUtils.getLoginRoleOptions());
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to add these roles twice? The test still seems to pass if I remove the duplicates...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not at all. Removed.

CassandraRoleManager crm = new CassandraRoleManager();

assertEquals(CassandraRoleManager.hasExistingRoles(), true);
assertEquals(crm.isClusterReady(), false);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: could use assertTrue() and assertFalse() respectively (although perhaps that's less important than throwing an explicit failure message in there)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fleshed out a bit and swapped to the less tautological options.

public class PasswordAuthenticatorTest extends CQLTester
{

private static PasswordAuthenticator authenticator = new PasswordAuthenticator();
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: could be final

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting. We had a couple PasswordAuthenticator creations in the tests that shadowed the class static variable (ew), some vestigial throws Exception, a whitespace... and this. Tidied that file up.

private final Set<Option> alterableOptions;

// Will be set to true when all nodes in the cluster are on a version which supports roles (i.e. 2.2+)
private volatile boolean isClusterReady = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we just remove isClusterReady altogether? We won't allow upgrading directly from 2.1 -> 4.1 right?

blambov pushed a commit to blambov/cassandra that referenced this pull request Jul 30, 2024
michaelsembwever pushed a commit to thelastpickle/cassandra that referenced this pull request Sep 25, 2024
michaelsembwever pushed a commit to thelastpickle/cassandra that referenced this pull request Jan 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants