mirror of https://github.com/apache/cassandra
Simplify auth setup and make system_auth ks alterable
Patch by Aleksey Yeschenko; reviewed by Jonathan Ellis for CASSANDRA-5112
This commit is contained in:
parent
e531be77a4
commit
265964064b
|
|
@ -18,6 +18,7 @@
|
|||
* Implement caching of authorization results (CASSANDRA-4295)
|
||||
* Add support for LZ4 compression (CASSANDRA-5038)
|
||||
* Fix missing columns in wide rows queries (CASSANDRA-5225)
|
||||
* Simplify auth setup and make system_auth ks alterable (CASSANDRA-5112)
|
||||
|
||||
|
||||
1.2.1
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ else:
|
|||
|
||||
debug_completion = bool(os.environ.get('CQLSH_DEBUG_COMPLETION', '') == 'YES')
|
||||
|
||||
SYSTEM_KEYSPACES = ('system', 'system_traces', 'system_auth')
|
||||
SYSTEM_KEYSPACES = ('system', 'system_traces')
|
||||
|
||||
# we want the cql parser to understand our cqlsh-specific commands too
|
||||
my_commands_ending_with_newline = (
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ class UnexpectedTableStructure(UserWarning):
|
|||
return 'Unexpected table structure; may not translate correctly to CQL. ' + self.msg
|
||||
|
||||
SYSTEM_KEYSPACES = ('system', 'system_traces', 'system_auth')
|
||||
NONALTERBALE_KEYSPACES = ('system', 'system_traces')
|
||||
|
||||
class Cql3ParsingRuleSet(CqlParsingRuleSet):
|
||||
keywords = set((
|
||||
|
|
@ -306,6 +307,8 @@ JUNK ::= /([ \t\r\f\v]+|(--|[/][/])[^\n\r]*([\n\r]|$)|[/][*].*?[*][/])/ ;
|
|||
|
||||
<nonSystemKeyspaceName> ::= ksname=<cfOrKsName> ;
|
||||
|
||||
<alterableKeyspaceName> ::= ksname=<cfOrKsName> ;
|
||||
|
||||
<cfOrKsName> ::= <identifier>
|
||||
| <quotedName>
|
||||
| <unreservedKeyword>;
|
||||
|
|
@ -686,6 +689,11 @@ def ks_name_completer(ctxt, cass):
|
|||
ksnames = [n for n in cass.get_keyspace_names() if n not in SYSTEM_KEYSPACES]
|
||||
return map(maybe_escape_name, ksnames)
|
||||
|
||||
@completer_for('alterableKeyspaceName', 'ksname')
|
||||
def ks_name_completer(ctxt, cass):
|
||||
ksnames = [n for n in cass.get_keyspace_names() if n not in NONALTERBALE_KEYSPACES]
|
||||
return map(maybe_escape_name, ksnames)
|
||||
|
||||
@completer_for('columnFamilyName', 'ksname')
|
||||
def cf_ks_name_completer(ctxt, cass):
|
||||
return [maybe_escape_name(ks) + '.' for ks in cass.get_keyspace_names()]
|
||||
|
|
@ -1242,7 +1250,7 @@ def alter_table_col_completer(ctxt, cass):
|
|||
explain_completion('alterInstructions', 'newcol', '<new_column_name>')
|
||||
|
||||
syntax_rules += r'''
|
||||
<alterKeyspaceStatement> ::= "ALTER" ( "KEYSPACE" | "SCHEMA" ) ks=<nonSystemKeyspaceName>
|
||||
<alterKeyspaceStatement> ::= "ALTER" ( "KEYSPACE" | "SCHEMA" ) ks=<alterableKeyspaceName>
|
||||
"WITH" <newPropSpec> ( "AND" <newPropSpec> )*
|
||||
;
|
||||
'''
|
||||
|
|
@ -1295,7 +1303,7 @@ syntax_rules += r'''
|
|||
;
|
||||
|
||||
<dataResource> ::= ( "ALL" "KEYSPACES" )
|
||||
| ( "KEYSPACE" <nonSystemKeyspaceName> )
|
||||
| ( "KEYSPACE" <keyspaceName> )
|
||||
| ( "TABLE"? <columnFamilyName> )
|
||||
;
|
||||
'''
|
||||
|
|
|
|||
|
|
@ -17,15 +17,24 @@
|
|||
*/
|
||||
package org.apache.cassandra.auth;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.config.KSMetaData;
|
||||
import org.apache.cassandra.config.Schema;
|
||||
import org.apache.cassandra.cql3.UntypedResultSet;
|
||||
import org.apache.cassandra.cql3.QueryProcessor;
|
||||
import org.apache.cassandra.db.ConsistencyLevel;
|
||||
import org.apache.cassandra.exceptions.RequestExecutionException;
|
||||
import org.apache.cassandra.locator.SimpleStrategy;
|
||||
import org.apache.cassandra.service.IMigrationListener;
|
||||
import org.apache.cassandra.service.MigrationManager;
|
||||
import org.apache.cassandra.service.StorageService;
|
||||
|
||||
public class Auth
|
||||
{
|
||||
|
|
@ -33,9 +42,20 @@ public class Auth
|
|||
|
||||
public static final String DEFAULT_SUPERUSER_NAME = "cassandra";
|
||||
|
||||
private static final long SUPERUSER_SETUP_DELAY = 10; // seconds.
|
||||
|
||||
public static final String AUTH_KS = "system_auth";
|
||||
public static final String USERS_CF = "users";
|
||||
|
||||
private static final String USERS_CF_SCHEMA = String.format("CREATE TABLE %s.%s ("
|
||||
+ "name text,"
|
||||
+ "super boolean,"
|
||||
+ "PRIMARY KEY(name)"
|
||||
+ ") WITH gc_grace_seconds=%d",
|
||||
AUTH_KS,
|
||||
USERS_CF,
|
||||
90 * 24 * 60 * 60); // 3 months.
|
||||
|
||||
/**
|
||||
* Checks if the username is stored in AUTH_KS.USERS_CF.
|
||||
*
|
||||
|
|
@ -47,7 +67,7 @@ public class Auth
|
|||
String query = String.format("SELECT * FROM %s.%s WHERE name = '%s'", AUTH_KS, USERS_CF, escape(username));
|
||||
try
|
||||
{
|
||||
return !QueryProcessor.process(query).isEmpty();
|
||||
return !QueryProcessor.process(query, ConsistencyLevel.QUORUM).isEmpty();
|
||||
}
|
||||
catch (RequestExecutionException e)
|
||||
{
|
||||
|
|
@ -66,7 +86,7 @@ public class Auth
|
|||
String query = String.format("SELECT super FROM %s.%s WHERE name = '%s'", AUTH_KS, USERS_CF, escape(username));
|
||||
try
|
||||
{
|
||||
UntypedResultSet result = QueryProcessor.process(query);
|
||||
UntypedResultSet result = QueryProcessor.process(query, ConsistencyLevel.QUORUM);
|
||||
return !result.isEmpty() && result.one().getBoolean("super");
|
||||
}
|
||||
catch (RequestExecutionException e)
|
||||
|
|
@ -87,7 +107,8 @@ public class Auth
|
|||
AUTH_KS,
|
||||
USERS_CF,
|
||||
escape(username),
|
||||
isSuper));
|
||||
isSuper),
|
||||
ConsistencyLevel.QUORUM);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -100,7 +121,8 @@ public class Auth
|
|||
QueryProcessor.process(String.format("DELETE FROM %s.%s WHERE name = '%s'",
|
||||
AUTH_KS,
|
||||
USERS_CF,
|
||||
escape(username)));
|
||||
escape(username)),
|
||||
ConsistencyLevel.QUORUM);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -108,23 +130,75 @@ public class Auth
|
|||
*/
|
||||
public static void setup()
|
||||
{
|
||||
authenticator().setup();
|
||||
authorizer().setup();
|
||||
setupAuthKeyspace();
|
||||
setupUsersTable();
|
||||
|
||||
DatabaseDescriptor.getAuthenticator().setup();
|
||||
DatabaseDescriptor.getAuthorizer().setup();
|
||||
|
||||
// register a custom MigrationListener for permissions cleanup after dropped keyspaces/cfs.
|
||||
MigrationManager.instance.register(new MigrationListener());
|
||||
|
||||
// the delay is here to give the node some time to see its peers - to reduce
|
||||
// "Skipping default superuser setup: some nodes are not ready" log spam.
|
||||
// It's the only reason for the delay.
|
||||
StorageService.tasks.schedule(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
setupDefaultSuperuser();
|
||||
}
|
||||
},
|
||||
SUPERUSER_SETUP_DELAY,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up default superuser.
|
||||
*/
|
||||
public static void setupSuperuser()
|
||||
private static void setupAuthKeyspace()
|
||||
{
|
||||
if (Schema.instance.getKSMetaData(AUTH_KS) == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
KSMetaData ksm = KSMetaData.newKeyspace(AUTH_KS, SimpleStrategy.class.getName(), ImmutableMap.of("replication_factor", "1"), true);
|
||||
MigrationManager.announceNewKeyspace(ksm, 0);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new AssertionError(e); // shouldn't ever happen.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setupUsersTable()
|
||||
{
|
||||
if (Schema.instance.getCFMetaData(AUTH_KS, USERS_CF) == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
QueryProcessor.process(USERS_CF_SCHEMA, ConsistencyLevel.ONE);
|
||||
}
|
||||
catch (RequestExecutionException e)
|
||||
{
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setupDefaultSuperuser()
|
||||
{
|
||||
try
|
||||
{
|
||||
// insert a default superuser if AUTH_KS.USERS_CF is empty.
|
||||
if (QueryProcessor.process(String.format("SELECT * FROM %s.%s", AUTH_KS, USERS_CF)).isEmpty())
|
||||
insertUser(DEFAULT_SUPERUSER_NAME, true);
|
||||
if (QueryProcessor.process(String.format("SELECT * FROM %s.%s", AUTH_KS, USERS_CF), ConsistencyLevel.QUORUM).isEmpty())
|
||||
{
|
||||
logger.info("Creating default superuser '{}'", DEFAULT_SUPERUSER_NAME);
|
||||
QueryProcessor.process(String.format("INSERT INTO %s.%s (name, super) VALUES ('%s', %s) USING TIMESTAMP 0",
|
||||
AUTH_KS,
|
||||
USERS_CF,
|
||||
DEFAULT_SUPERUSER_NAME,
|
||||
true),
|
||||
ConsistencyLevel.QUORUM);
|
||||
}
|
||||
}
|
||||
catch (RequestExecutionException e)
|
||||
{
|
||||
|
|
@ -138,13 +212,35 @@ public class Auth
|
|||
return StringUtils.replace(name, "'", "''");
|
||||
}
|
||||
|
||||
private static IAuthenticator authenticator()
|
||||
/**
|
||||
* IMigrationListener implementation that cleans up permissions on dropped resources.
|
||||
*/
|
||||
public static class MigrationListener implements IMigrationListener
|
||||
{
|
||||
return DatabaseDescriptor.getAuthenticator();
|
||||
}
|
||||
public void onDropKeyspace(String ksName)
|
||||
{
|
||||
DatabaseDescriptor.getAuthorizer().revokeAll(DataResource.keyspace(ksName));
|
||||
}
|
||||
|
||||
private static IAuthorizer authorizer()
|
||||
{
|
||||
return DatabaseDescriptor.getAuthorizer();
|
||||
public void onDropColumnFamily(String ksName, String cfName)
|
||||
{
|
||||
DatabaseDescriptor.getAuthorizer().revokeAll(DataResource.columnFamily(ksName, cfName));
|
||||
}
|
||||
|
||||
public void onCreateKeyspace(String ksName)
|
||||
{
|
||||
}
|
||||
|
||||
public void onCreateColumnFamily(String ksName, String cfName)
|
||||
{
|
||||
}
|
||||
|
||||
public void onUpdateKeyspace(String ksName)
|
||||
{
|
||||
}
|
||||
|
||||
public void onUpdateColumnFamily(String ksName, String cfName)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import org.apache.commons.lang.builder.ToStringBuilder;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.apache.cassandra.auth.Auth;
|
||||
import org.apache.cassandra.cql3.CFDefinition;
|
||||
import org.apache.cassandra.cql3.QueryProcessor;
|
||||
import org.apache.cassandra.cql3.UntypedResultSet;
|
||||
|
|
@ -227,12 +226,7 @@ public final class CFMetaData
|
|||
+ "requested_at timestamp"
|
||||
+ ") WITH COMMENT='ranges requested for transfer here'");
|
||||
|
||||
public static final CFMetaData AuthUsersCf = compile(18, "CREATE TABLE " + Auth.USERS_CF + " ("
|
||||
+ "name text PRIMARY KEY,"
|
||||
+ "super boolean"
|
||||
+ ") WITH gc_grace_seconds=864000;", Auth.AUTH_KS);
|
||||
|
||||
public static final CFMetaData CompactionLogCF = compile(19, "CREATE TABLE " + SystemTable.COMPACTION_LOG + " ("
|
||||
public static final CFMetaData CompactionLogCF = compile(18, "CREATE TABLE " + SystemTable.COMPACTION_LOG + " ("
|
||||
+ "id uuid PRIMARY KEY,"
|
||||
+ "keyspace_name text,"
|
||||
+ "columnfamily_name text,"
|
||||
|
|
|
|||
|
|
@ -470,9 +470,7 @@ public class DatabaseDescriptor
|
|||
}
|
||||
|
||||
// Hardcoded system tables
|
||||
List<KSMetaData> systemKeyspaces = Arrays.asList(KSMetaData.systemKeyspace(),
|
||||
KSMetaData.traceKeyspace(),
|
||||
KSMetaData.authKeyspace());
|
||||
List<KSMetaData> systemKeyspaces = Arrays.asList(KSMetaData.systemKeyspace(), KSMetaData.traceKeyspace());
|
||||
assert systemKeyspaces.size() == Schema.systemKeyspaceNames.size();
|
||||
for (KSMetaData ksmd : systemKeyspaces)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import com.google.common.collect.ImmutableMap;
|
|||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import org.apache.cassandra.auth.Auth;
|
||||
import org.apache.cassandra.cql3.QueryProcessor;
|
||||
import org.apache.cassandra.cql3.UntypedResultSet;
|
||||
import org.apache.cassandra.db.*;
|
||||
|
|
@ -104,12 +103,6 @@ public final class KSMetaData
|
|||
return new KSMetaData(Tracing.TRACE_KS, SimpleStrategy.class, ImmutableMap.of("replication_factor", "1"), true, cfDefs);
|
||||
}
|
||||
|
||||
public static KSMetaData authKeyspace()
|
||||
{
|
||||
List<CFMetaData> cfDefs = Arrays.asList(CFMetaData.AuthUsersCf);
|
||||
return new KSMetaData(Auth.AUTH_KS, SimpleStrategy.class, ImmutableMap.of("replication_factor", "1"), true, cfDefs);
|
||||
}
|
||||
|
||||
public static KSMetaData testMetadata(String name, Class<? extends AbstractReplicationStrategy> strategyClass, Map<String, String> strategyOptions, CFMetaData... cfDefs)
|
||||
{
|
||||
return new KSMetaData(name, strategyClass, strategyOptions, true, Arrays.asList(cfDefs));
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import com.google.common.collect.*;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.apache.cassandra.auth.Auth;
|
||||
import org.apache.cassandra.db.*;
|
||||
import org.apache.cassandra.db.Table;
|
||||
import org.apache.cassandra.db.marshal.AbstractType;
|
||||
|
|
@ -67,7 +66,7 @@ public class Schema
|
|||
|
||||
// 59adb24e-f3cd-3e02-97f0-5b395827453f
|
||||
public static final UUID emptyVersion;
|
||||
public static final ImmutableSet<String> systemKeyspaceNames = ImmutableSet.of(Table.SYSTEM_KS, Tracing.TRACE_KS, Auth.AUTH_KS);
|
||||
public static final ImmutableSet<String> systemKeyspaceNames = ImmutableSet.of(Table.SYSTEM_KS, Tracing.TRACE_KS);
|
||||
|
||||
static
|
||||
{
|
||||
|
|
|
|||
|
|
@ -143,12 +143,12 @@ public class QueryProcessor
|
|||
return processStatement(prepared, cl, queryState, Collections.<ByteBuffer>emptyList());
|
||||
}
|
||||
|
||||
public static UntypedResultSet process(String query) throws RequestExecutionException
|
||||
public static UntypedResultSet process(String query, ConsistencyLevel cl) throws RequestExecutionException
|
||||
{
|
||||
try
|
||||
{
|
||||
QueryState state = new QueryState(new ClientState(true));
|
||||
ResultMessage result = process(query, ConsistencyLevel.ONE, state);
|
||||
ResultMessage result = process(query, cl, state);
|
||||
if (result instanceof ResultMessage.Rows)
|
||||
return new UntypedResultSet(((ResultMessage.Rows)result).result);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public class ListUsersStatement extends AuthenticationStatement
|
|||
public ResultMessage execute(ClientState state) throws RequestValidationException, RequestExecutionException
|
||||
{
|
||||
return QueryProcessor.process(String.format("SELECT * FROM %s.%s", Auth.AUTH_KS, Auth.USERS_CF),
|
||||
ConsistencyLevel.ONE,
|
||||
ConsistencyLevel.QUORUM,
|
||||
new QueryState(new ClientState(true)));
|
||||
}
|
||||
}
|
||||
|
|
@ -32,7 +32,6 @@ import org.apache.log4j.PropertyConfigurator;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.apache.cassandra.auth.Auth;
|
||||
import org.apache.cassandra.config.CFMetaData;
|
||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
|
|
@ -195,9 +194,6 @@ public class CassandraDaemon
|
|||
System.exit(100);
|
||||
}
|
||||
|
||||
// setup Authenticator and Authorizer.
|
||||
Auth.setup();
|
||||
|
||||
// clean up debris in the rest of the tables
|
||||
for (String table : Schema.instance.getTables())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ public class ClientState
|
|||
if (internalCall)
|
||||
return;
|
||||
validateLogin();
|
||||
preventSystemKSSchemaModification(keyspace, perm);
|
||||
preventSystemKSSchemaModification(keyspace, resource, perm);
|
||||
if (perm.equals(Permission.SELECT) && READABLE_SYSTEM_RESOURCES.contains(resource))
|
||||
return;
|
||||
if (PROTECTED_AUTH_RESOURCES.contains(resource))
|
||||
|
|
@ -173,10 +173,18 @@ public class ClientState
|
|||
resource));
|
||||
}
|
||||
|
||||
private void preventSystemKSSchemaModification(String keyspace, Permission perm) throws UnauthorizedException
|
||||
private void preventSystemKSSchemaModification(String keyspace, DataResource resource, Permission perm) throws UnauthorizedException
|
||||
{
|
||||
if (Schema.systemKeyspaceNames.contains(keyspace.toLowerCase()) && !(perm.equals(Permission.SELECT) || perm.equals(Permission.MODIFY)))
|
||||
// we only care about schema modification.
|
||||
if (!(perm.equals(Permission.ALTER) || perm.equals(Permission.DROP) || perm.equals(Permission.CREATE)))
|
||||
return;
|
||||
|
||||
if (Schema.systemKeyspaceNames.contains(keyspace.toLowerCase()))
|
||||
throw new UnauthorizedException(keyspace + " keyspace is not user-modifiable.");
|
||||
|
||||
// we want to allow altering AUTH_KS itself.
|
||||
if (keyspace.equals(Auth.AUTH_KS) && !(resource.isKeyspaceLevel() && perm.equals(Permission.ALTER)))
|
||||
throw new UnauthorizedException(String.format("Cannot %s %s", perm, resource));
|
||||
}
|
||||
|
||||
public void validateLogin() throws UnauthorizedException
|
||||
|
|
|
|||
|
|
@ -197,6 +197,11 @@ public class MigrationManager implements IEndpointStateChangeSubscriber
|
|||
}
|
||||
|
||||
public static void announceNewKeyspace(KSMetaData ksm) throws ConfigurationException
|
||||
{
|
||||
announceNewKeyspace(ksm, FBUtilities.timestampMicros());
|
||||
}
|
||||
|
||||
public static void announceNewKeyspace(KSMetaData ksm, long timestamp) throws ConfigurationException
|
||||
{
|
||||
ksm.validate();
|
||||
|
||||
|
|
@ -204,7 +209,7 @@ public class MigrationManager implements IEndpointStateChangeSubscriber
|
|||
throw new AlreadyExistsException(ksm.name);
|
||||
|
||||
logger.info(String.format("Create new Keyspace: %s", ksm));
|
||||
announce(ksm.toSchema(FBUtilities.timestampMicros()));
|
||||
announce(ksm.toSchema(timestamp));
|
||||
}
|
||||
|
||||
public static void announceNewColumnFamily(CFMetaData cfm) throws ConfigurationException
|
||||
|
|
|
|||
|
|
@ -746,8 +746,7 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
|||
logger.info("Startup completed! Now serving reads.");
|
||||
assert tokenMetadata.sortedTokens().size() > 0;
|
||||
|
||||
// setup default superuser (if needed).
|
||||
Auth.setupSuperuser();
|
||||
Auth.setup();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -786,8 +785,7 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
|||
logger.info("Leaving write survey mode and joining ring at operator request");
|
||||
assert tokenMetadata.sortedTokens().size() > 0;
|
||||
|
||||
// setup default superuser (if needed).
|
||||
Auth.setupSuperuser();
|
||||
Auth.setup();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2308,7 +2306,7 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
|||
|
||||
public int forceRepairAsync(final String keyspace, final boolean isSequential, final boolean isLocal, final boolean primaryRange, final String... columnFamilies)
|
||||
{
|
||||
if (Table.SYSTEM_KS.equals(keyspace) || Tracing.TRACE_KS.equals(keyspace) || Auth.AUTH_KS.equals(keyspace))
|
||||
if (Table.SYSTEM_KS.equals(keyspace) || Tracing.TRACE_KS.equals(keyspace))
|
||||
return 0;
|
||||
|
||||
final int cmd = nextRepairCommand.incrementAndGet();
|
||||
|
|
@ -2348,7 +2346,7 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
|||
|
||||
public void forceTableRepairRange(final String tableName, final Collection<Range<Token>> ranges, boolean isSequential, boolean isLocal, final String... columnFamilies) throws IOException
|
||||
{
|
||||
if (Table.SYSTEM_KS.equals(tableName) || Tracing.TRACE_KS.equals(tableName) || Auth.AUTH_KS.equals(tableName))
|
||||
if (Table.SYSTEM_KS.equals(tableName) || Tracing.TRACE_KS.equals(tableName))
|
||||
return;
|
||||
createRepairTask(nextRepairCommand.incrementAndGet(), tableName, ranges, isSequential, isLocal, columnFamilies).run();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue