mirror of https://github.com/apache/cassandra
Merge branch 'cassandra-4.0' into cassandra-4.1
This commit is contained in:
commit
72fc04d238
|
|
@ -6,6 +6,7 @@
|
|||
* Fix COPY ... TO STDOUT behavior in cqlsh (CASSANDRA-18353)
|
||||
* Remove six and Py2SaferScanner merge cruft (CASSANDRA-18354)
|
||||
Merged from 4.0:
|
||||
* Improve nodetool enable{audit,fullquery}log (CASSANDRA-18550)
|
||||
* Report network cache info in nodetool (CASSANDRa-18400)
|
||||
* Partial compaction can resurrect deleted data (CASSANDRA-18507)
|
||||
* Allow internal address to change with reconnecting snitches (CASSANDRA-16718)
|
||||
|
|
|
|||
|
|
@ -1588,6 +1588,8 @@ audit_logging_options:
|
|||
# max_log_size: 17179869184 # 16 GiB
|
||||
## archive command is "/path/to/script.sh %path" where %path is replaced with the file being rolled:
|
||||
# archive_command:
|
||||
## note that enabling this allows anyone with JMX/nodetool access to run local shell commands as the user running cassandra
|
||||
# allow_nodetool_archive_command: false
|
||||
# max_archive_retries: 10
|
||||
|
||||
# validate tombstones on reads and compaction
|
||||
|
|
|
|||
|
|
@ -3706,6 +3706,11 @@ public class DatabaseDescriptor
|
|||
return conf.full_query_logging_options;
|
||||
}
|
||||
|
||||
public static void setFullQueryLogOptions(FullQueryLoggerOptions options)
|
||||
{
|
||||
conf.full_query_logging_options = options;
|
||||
}
|
||||
|
||||
public static boolean getBlockForPeersInRemoteDatacenters()
|
||||
{
|
||||
return conf.block_for_peers_in_remote_dcs;
|
||||
|
|
|
|||
|
|
@ -6398,7 +6398,11 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
|||
String includedUsers, String excludedUsers, Integer maxArchiveRetries, Boolean block, String rollCycle,
|
||||
Long maxLogSize, Integer maxQueueWeight, String archiveCommand) throws IllegalStateException
|
||||
{
|
||||
final AuditLogOptions options = new AuditLogOptions.Builder(DatabaseDescriptor.getAuditLoggingOptions())
|
||||
AuditLogOptions auditOptions = DatabaseDescriptor.getAuditLoggingOptions();
|
||||
if (archiveCommand != null && !auditOptions.allow_nodetool_archive_command)
|
||||
throw new ConfigurationException("Can't enable audit log archiving via nodetool unless audit_logging_options.allow_nodetool_archive_command is set to true");
|
||||
|
||||
final AuditLogOptions options = new AuditLogOptions.Builder(auditOptions)
|
||||
.withEnabled(true)
|
||||
.withLogger(loggerName, parameters)
|
||||
.withIncludedKeyspaces(includedKeyspaces)
|
||||
|
|
@ -6501,6 +6505,8 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
|||
blocking = blocking != null ? blocking : fqlOptions.block;
|
||||
maxQueueWeight = maxQueueWeight != Integer.MIN_VALUE ? maxQueueWeight : fqlOptions.max_queue_weight;
|
||||
maxLogSize = maxLogSize != Long.MIN_VALUE ? maxLogSize : fqlOptions.max_log_size;
|
||||
if (archiveCommand != null && !fqlOptions.allow_nodetool_archive_command)
|
||||
throw new ConfigurationException("Can't enable full query log archiving via nodetool unless full_query_logging_options.allow_nodetool_archive_command is set to true");
|
||||
archiveCommand = archiveCommand != null ? archiveCommand : fqlOptions.archive_command;
|
||||
maxArchiveRetries = maxArchiveRetries != Integer.MIN_VALUE ? maxArchiveRetries : fqlOptions.max_archive_retries;
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ public class EnableAuditLog extends NodeToolCmd
|
|||
private long maxLogSize = Long.MIN_VALUE;
|
||||
|
||||
@Option(title = "archive_command", name = {"--archive-command"}, description = "Command that will handle archiving rolled audit log files." +
|
||||
" Format is \"/path/to/script.sh %path\" where %path will be replaced with the file to archive")
|
||||
" Format is \"/path/to/script.sh %path\" where %path will be replaced with the file to archive" +
|
||||
" Enable this by setting the audit_logging_options.allow_nodetool_archive_command: true in the config.")
|
||||
|
||||
private String archiveCommand = null;
|
||||
|
||||
@Option(title = "archive_retries", name = {"--max-archive-retries"}, description = "Max number of archive retries.")
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ public class EnableFullQueryLog extends NodeToolCmd
|
|||
private String path = null;
|
||||
|
||||
@Option(title = "archive_command", name = {"--archive-command"}, description = "Command that will handle archiving rolled full query log files." +
|
||||
" Format is \"/path/to/script.sh %path\" where %path will be replaced with the file to archive")
|
||||
" Format is \"/path/to/script.sh %path\" where %path will be replaced with the file to archive" +
|
||||
" Enable this by setting the full_query_logging_options.allow_nodetool_archive_command: true in the config.")
|
||||
private String archiveCommand = null;
|
||||
|
||||
@Option(title = "archive_retries", name = {"--max-archive-retries"}, description = "Max number of archive retries.")
|
||||
|
|
|
|||
|
|
@ -23,6 +23,13 @@ import org.apache.commons.lang3.StringUtils;
|
|||
public class BinLogOptions
|
||||
{
|
||||
public String archive_command = StringUtils.EMPTY;
|
||||
|
||||
/**
|
||||
* enable if a user should be able to set the archive command via nodetool/jmx
|
||||
*
|
||||
* do not make this a hotprop.
|
||||
*/
|
||||
public boolean allow_nodetool_archive_command = false;
|
||||
/**
|
||||
* How often to roll BinLog segments so they can potentially be reclaimed. Available options are:
|
||||
* MINUTELY, HOURLY, DAILY, LARGE_DAILY, XLARGE_DAILY, HUGE_DAILY.
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.junit.After;
|
|||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
|
@ -716,6 +717,34 @@ public class AuditLoggerTest extends CQLTester
|
|||
assertEquals(0, AuthEvents.instance.listenerCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJMXArchiveCommand()
|
||||
{
|
||||
disableAuditLogOptions();
|
||||
AuditLogOptions options = new AuditLogOptions();
|
||||
|
||||
try
|
||||
{
|
||||
StorageService.instance.enableAuditLog("BinAuditLogger", Collections.emptyMap(), "", "", "", "",
|
||||
"", "", 10, true, options.roll_cycle,
|
||||
1000L, 1000, "/xyz/not/null");
|
||||
fail("not allowed");
|
||||
}
|
||||
catch (ConfigurationException e)
|
||||
{
|
||||
assertTrue(e.getMessage().contains("Can't enable audit log archiving via nodetool"));
|
||||
}
|
||||
|
||||
options.archive_command = "/xyz/not/null";
|
||||
options.audit_logs_dir = "/tmp/abc";
|
||||
DatabaseDescriptor.setAuditLoggingOptions(options);
|
||||
StorageService.instance.enableAuditLog("BinAuditLogger", Collections.emptyMap(), "", "", "", "",
|
||||
"", "", 10, true, options.roll_cycle,
|
||||
1000L, 1000, null);
|
||||
assertTrue(AuditLogManager.instance.isEnabled());
|
||||
assertEquals("/xyz/not/null", AuditLogManager.instance.getAuditLogOptions().archive_command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper methods for Audit Log CQL Testing
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -43,15 +43,18 @@ import net.openhft.chronicle.queue.RollCycles;
|
|||
import net.openhft.chronicle.wire.ValueIn;
|
||||
import net.openhft.chronicle.wire.WireOut;
|
||||
import org.apache.cassandra.Util;
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.cql3.CQLTester;
|
||||
import org.apache.cassandra.cql3.QueryOptions;
|
||||
import org.apache.cassandra.cql3.statements.BatchStatement;
|
||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.cassandra.fql.FullQueryLogger.Query;
|
||||
import org.apache.cassandra.fql.FullQueryLogger.Batch;
|
||||
import org.apache.cassandra.cql3.statements.BatchStatement.Type;
|
||||
import org.apache.cassandra.io.util.FileUtils;
|
||||
import org.apache.cassandra.service.ClientState;
|
||||
import org.apache.cassandra.service.QueryState;
|
||||
import org.apache.cassandra.service.StorageService;
|
||||
import org.apache.cassandra.transport.ProtocolVersion;
|
||||
import org.apache.cassandra.utils.ObjectSizes;
|
||||
import org.apache.cassandra.utils.binlog.BinLogTest;
|
||||
|
|
@ -73,6 +76,7 @@ import static org.apache.cassandra.fql.FullQueryLogger.SINGLE_QUERY;
|
|||
import static org.apache.cassandra.fql.FullQueryLogger.TYPE;
|
||||
import static org.apache.cassandra.fql.FullQueryLogger.VALUES;
|
||||
import static org.apache.cassandra.fql.FullQueryLogger.VERSION;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class FullQueryLoggerTest extends CQLTester
|
||||
{
|
||||
|
|
@ -669,6 +673,29 @@ public class FullQueryLoggerTest extends CQLTester
|
|||
logQuery("", QueryOptions.DEFAULT, queryState(), -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJMXArchiveCommand()
|
||||
{
|
||||
FullQueryLoggerOptions options = new FullQueryLoggerOptions();
|
||||
|
||||
try
|
||||
{
|
||||
StorageService.instance.enableFullQueryLogger(options.log_dir, options.roll_cycle, false, 1000, 1000, "/xyz/not/null", 0);
|
||||
fail("not allowed");
|
||||
}
|
||||
catch (ConfigurationException e)
|
||||
{
|
||||
assertTrue(e.getMessage().contains("Can't enable full query log archiving via nodetool"));
|
||||
}
|
||||
|
||||
options.archive_command = "/xyz/not/null";
|
||||
options.log_dir = "/tmp/abc";
|
||||
DatabaseDescriptor.setFullQueryLogOptions(options);
|
||||
StorageService.instance.enableFullQueryLogger(options.log_dir, options.roll_cycle, false, 1000, 1000, null, 0);
|
||||
assertTrue(FullQueryLogger.instance.isEnabled());
|
||||
assertEquals("/xyz/not/null", FullQueryLogger.instance.getFullQueryLoggerOptions().archive_command);
|
||||
}
|
||||
|
||||
private static void compareQueryOptions(QueryOptions a, QueryOptions b)
|
||||
{
|
||||
assertEquals(a.getClass(), b.getClass());
|
||||
|
|
|
|||
Loading…
Reference in New Issue