CASSANDRA-20892: Don't allow JMX operations for denylist when denylist is disabled

This commit is contained in:
maoling 2025-09-05 23:13:00 +08:00
parent 176b9b17a4
commit b0a9d24d01
4 changed files with 49 additions and 0 deletions

View File

@ -13,6 +13,13 @@ partition key, the query will be immediately rejected with an `InvalidQueryExcep
== How to denylist a partition key
Denylisting partitions is disabled by default. To use this feature, enable it in the `cassandra.yaml` file.
....
partition_denylist_enabled: true
....
The ``system_distributed.denylisted_partitions`` table can be used to denylist partitions.
There are a couple of ways to interact with and mutate this data. First: directly
via CQL by inserting a record with the following details:

View File

@ -3658,9 +3658,16 @@ public class StorageProxy implements StorageProxyMBean
@Override
public void loadPartitionDenylist()
{
ensurePartitionDenylistEnabled();
partitionDenylist.load();
}
@Override
public boolean getPartitionDenylistEnabled()
{
return DatabaseDescriptor.getPartitionDenylistEnabled();
}
@Override
public int getPartitionDenylistLoadAttempts()
{
@ -3719,6 +3726,7 @@ public class StorageProxy implements StorageProxyMBean
@Override
public boolean denylistKey(String keyspace, String table, String partitionKeyAsString)
{
ensurePartitionDenylistEnabled();
if (!Schema.instance.getKeyspaces().contains(keyspace))
return false;
@ -3740,6 +3748,7 @@ public class StorageProxy implements StorageProxyMBean
@Override
public boolean removeDenylistKey(String keyspace, String table, String partitionKeyAsString)
{
ensurePartitionDenylistEnabled();
if (!Schema.instance.getKeyspaces().contains(keyspace))
return false;
@ -3756,6 +3765,7 @@ public class StorageProxy implements StorageProxyMBean
*/
public boolean isKeyDenylisted(String keyspace, String table, String partitionKeyAsString)
{
ensurePartitionDenylistEnabled();
if (!Schema.instance.getKeyspaces().contains(keyspace))
return false;
@ -3767,6 +3777,12 @@ public class StorageProxy implements StorageProxyMBean
return !partitionDenylist.isKeyPermitted(keyspace, table, bytes);
}
private void ensurePartitionDenylistEnabled()
{
if (!getPartitionDenylistEnabled())
throw new RuntimeException("Denylisting partitions is disabled");
}
@Override
public void logBlockingReadRepairAttemptsForNSeconds(int seconds)
{

View File

@ -70,6 +70,7 @@ public interface StorageProxyMBean
public int getOtcBacklogExpirationInterval();
public void loadPartitionDenylist();
public boolean getPartitionDenylistEnabled();
public int getPartitionDenylistLoadAttempts();
public int getPartitionDenylistLoadSuccesses();
public void setEnablePartitionDenylist(boolean enabled);

View File

@ -448,6 +448,31 @@ public class PartitionDenylistTest
confirmAllowed("table3", Integer.toString(i), Integer.toString(i));
}
@Test
public void testJmxThrowExcepitonWhenDenylistDisable()
{
// Disable denylisting
DatabaseDescriptor.setPartitionDenylistEnabled(false);
// read and write work well
process("SELECT * FROM " + ks_cql + ".table1 WHERE keyone='aaa' and keytwo='bbb'", ConsistencyLevel.ONE);
process("SELECT * FROM " + ks_cql + ".table1 WHERE keyone='bbb' and keytwo='ccc'", ConsistencyLevel.ONE);
process("INSERT INTO " + ks_cql + ".table1 (keyone, keytwo, qux, quz, foo) VALUES ('eee', 'fff', 'ccc', 'ddd', 'v')", ConsistencyLevel.ONE);
process("INSERT INTO " + ks_cql + ".table1 (keyone, keytwo, qux, quz, foo) VALUES ('bbb', 'ccc', 'eee', 'fff', 'w')", ConsistencyLevel.ONE);
// when denylisting is disabled, JMX operation will throw excepiton
assertThatThrownBy(() -> denylist("table1", "foo:bar"))
.isInstanceOf(RuntimeException.class)
.hasMessageContaining("Denylisting partitions is disabled");
assertThatThrownBy(() -> refreshList())
.isInstanceOf(RuntimeException.class)
.hasMessageContaining("Denylisting partitions is disabled");
assertThatThrownBy(() -> removeDenylist(ks_cql, "table1", "foo:bar"))
.isInstanceOf(RuntimeException.class)
.hasMessageContaining("Denylisting partitions is disabled");
assertThatThrownBy(() -> StorageProxy.instance.isKeyDenylisted(ks_cql, "table1", "bbb:ccc"))
.isInstanceOf(RuntimeException.class)
.hasMessageContaining("Denylisting partitions is disabled");
}
private void confirmDenied(String table, String keyOne, String keyTwo)
{
String query = String.format("SELECT * FROM " + ks_cql + "." + table + " WHERE keyone='%s' and keytwo='%s'", keyOne, keyTwo);