HBASE-14122 Client API for determining if server side supports cell level security

This commit is contained in:
Andrew Purtell 2015-08-12 13:26:55 -07:00
parent beb1f1d358
commit 5e5bcceb53
20 changed files with 1545 additions and 129 deletions

View File

@ -18,7 +18,6 @@
*/
package org.apache.hadoop.hbase.client;
import java.io.Closeable;
import java.io.IOException;
import java.util.List;
@ -39,6 +38,7 @@ import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.TableNotFoundException;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.classification.InterfaceStability;
import org.apache.hadoop.hbase.client.security.SecurityCapability;
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
@ -1546,4 +1546,11 @@ public interface Admin extends Abortable, Closeable {
*/
AdminProtos.GetRegionInfoResponse.CompactionState getMobCompactionState(final TableName tableName)
throws IOException;
/**
* Return the set of supported security capabilities.
* @throws IOException
* @throws UnsupportedOperationException
*/
List<SecurityCapability> getSecurityCapabilities() throws IOException;
}

View File

@ -296,4 +296,5 @@ public interface ClusterConnection extends HConnection {
* @return the configured client backoff policy
*/
ClientBackoffPolicy getBackoffPolicy();
}

View File

@ -56,6 +56,8 @@ import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesResponse;
import org.apache.hadoop.hbase.quotas.ThrottlingException;
import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;
import org.apache.hadoop.hbase.security.User;
@ -71,6 +73,7 @@ import org.apache.hadoop.ipc.RemoteException;
import org.apache.zookeeper.KeeperException;
import javax.annotation.Nullable;
import java.io.Closeable;
import java.io.IOException;
import java.io.InterruptedIOException;
@ -1728,6 +1731,12 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
IsBalancerEnabledRequest request) throws ServiceException {
return stub.isBalancerEnabled(controller, request);
}
@Override
public SecurityCapabilitiesResponse getSecurityCapabilities(RpcController controller,
SecurityCapabilitiesRequest request) throws ServiceException {
return stub.getSecurityCapabilities(controller, request);
}
};
}

View File

@ -62,6 +62,7 @@ import org.apache.hadoop.hbase.UnknownRegionException;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.classification.InterfaceStability;
import org.apache.hadoop.hbase.client.security.SecurityCapability;
import org.apache.hadoop.hbase.exceptions.DeserializationException;
import org.apache.hadoop.hbase.exceptions.TimeoutIOException;
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
@ -132,6 +133,7 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyTableRespon
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ShutdownRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SnapshotRequest;
@ -4623,4 +4625,23 @@ public class HBaseAdmin implements Admin {
+ " regions are online; retries exhausted.");
}
}
@Override
public List<SecurityCapability> getSecurityCapabilities() throws IOException {
try {
return executeCallable(new MasterCallable<List<SecurityCapability>>(getConnection()) {
@Override
public List<SecurityCapability> call(int callTimeout) throws ServiceException {
SecurityCapabilitiesRequest req = SecurityCapabilitiesRequest.newBuilder().build();
return ProtobufUtil.toSecurityCapabilityList(
master.getSecurityCapabilities(null, req).getCapabilitiesList());
}
});
} catch (IOException e) {
if (e instanceof RemoteException) {
e = ((RemoteException)e).unwrapRemoteException();
}
throw e;
}
}
}

View File

@ -0,0 +1,63 @@
/**
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.client.security;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.classification.InterfaceStability;
/**
* Available security capabilities
*/
@InterfaceAudience.Public
@InterfaceStability.Evolving
public enum SecurityCapability {
// Note to implementors: These must match the numbering of Capability values in MasterProtos
SIMPLE_AUTHENTICATION(0),
SECURE_AUTHENTICATION(1),
AUTHORIZATION(2),
CELL_AUTHORIZATION(3),
CELL_VISIBILITY(4);
private int value;
public int getValue() {
return value;
}
public String getName() {
return toString();
}
private SecurityCapability(int value) {
this.value = value;
}
public static SecurityCapability valueOf(int value) {
switch (value) {
case 0: return SIMPLE_AUTHENTICATION;
case 1: return SECURE_AUTHENTICATION;
case 2: return AUTHORIZATION;
case 3: return CELL_AUTHORIZATION;
case 4: return CELL_VISIBILITY;
default:
throw new IllegalArgumentException("Unknown SecurityCapability value " + value);
}
}
};

View File

@ -65,6 +65,7 @@ import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.metrics.ScanMetrics;
import org.apache.hadoop.hbase.client.security.SecurityCapability;
import org.apache.hadoop.hbase.exceptions.DeserializationException;
import org.apache.hadoop.hbase.filter.ByteArrayComparable;
import org.apache.hadoop.hbase.filter.Filter;
@ -115,6 +116,7 @@ import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionInfo;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
import org.apache.hadoop.hbase.protobuf.generated.MapReduceProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateTableRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MasterService;
@ -3136,4 +3138,23 @@ public final class ProtobufUtil {
builder.setSrcChecksum(VersionInfo.getSrcChecksum());
return builder.build();
}
/**
* Convert SecurityCapabilitiesResponse.Capability to SecurityCapability
* @param caps capabilities returned in the SecurityCapabilitiesResponse message
* @return the converted list of SecurityCapability elements
*/
public static List<SecurityCapability> toSecurityCapabilityList(
List<MasterProtos.SecurityCapabilitiesResponse.Capability> capabilities) {
List<SecurityCapability> scList = new ArrayList<>(capabilities.size());
for (MasterProtos.SecurityCapabilitiesResponse.Capability c: capabilities) {
try {
scList.add(SecurityCapability.valueOf(c.getNumber()));
} catch (IllegalArgumentException e) {
// Unknown capability, just ignore it. We don't understand the new capability
// but don't care since by definition we cannot take advantage of it.
}
}
return scList;
}
}

View File

@ -33,6 +33,7 @@ import org.apache.hadoop.hbase.classification.InterfaceStability;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.security.SecurityCapability;
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
@ -48,6 +49,28 @@ public class AccessControlClient {
public static final TableName ACL_TABLE_NAME =
TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "acl");
/**
* Return true if authorization is supported and enabled
* @param connection The connection to use
* @return true if authorization is supported and enabled, false otherwise
* @throws IOException
*/
public static boolean isAuthorizationEnabled(Connection connection) throws IOException {
return connection.getAdmin().getSecurityCapabilities()
.contains(SecurityCapability.AUTHORIZATION);
}
/**
* Return true if cell authorization is supported and enabled
* @param connection The connection to use
* @return true if cell authorization is supported and enabled, false otherwise
* @throws IOException
*/
public static boolean isCellAuthorizationEnabled(Connection connection) throws IOException {
return connection.getAdmin().getSecurityCapabilities()
.contains(SecurityCapability.CELL_AUTHORIZATION);
}
private static BlockingInterface getAccessControlServiceStub(Table ht)
throws IOException {
CoprocessorRpcChannel service = ht.coprocessorService(HConstants.EMPTY_START_ROW);

View File

@ -31,6 +31,7 @@ import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.coprocessor.Batch;
import org.apache.hadoop.hbase.client.security.SecurityCapability;
import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
import org.apache.hadoop.hbase.ipc.ServerRpcController;
import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsRequest;
@ -54,6 +55,17 @@ import com.google.protobuf.ServiceException;
@InterfaceStability.Evolving
public class VisibilityClient {
/**
* Return true if cell visibility features are supported and enabled
* @param connection The connection to use
* @return true if cell visibility features are supported and enabled, false otherwise
* @throws IOException
*/
public static boolean isCellVisibilityEnabled(Connection connection) throws IOException {
return connection.getAdmin().getSecurityCapabilities()
.contains(SecurityCapability.CELL_VISIBILITY);
}
/**
* Utility method for adding label to the system.
*

View File

@ -450,6 +450,21 @@ message MajorCompactionTimestampResponse {
required int64 compaction_timestamp = 1;
}
message SecurityCapabilitiesRequest {
}
message SecurityCapabilitiesResponse {
enum Capability {
SIMPLE_AUTHENTICATION = 0;
SECURE_AUTHENTICATION = 1;
AUTHORIZATION = 2;
CELL_AUTHORIZATION = 3;
CELL_VISIBILITY = 4;
}
repeated Capability capabilities = 1;
}
service MasterService {
/** Used by the client to get the number of regions that have received the updated schema */
rpc GetSchemaAlterStatus(GetSchemaAlterStatusRequest)
@ -681,4 +696,8 @@ service MasterService {
rpc getProcedureResult(GetProcedureResultRequest)
returns(GetProcedureResultResponse);
/** Returns the security capabilities in effect on the cluster */
rpc getSecurityCapabilities(SecurityCapabilitiesRequest)
returns(SecurityCapabilitiesResponse);
}

View File

@ -21,7 +21,9 @@ package org.apache.hadoop.hbase.master;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -140,6 +142,9 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotRe
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesResponse.Capability;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetQuotaRequest;
@ -167,6 +172,9 @@ import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.Repor
import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionRequest;
import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionResponse;
import org.apache.hadoop.hbase.regionserver.RSRpcServices;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.security.access.AccessController;
import org.apache.hadoop.hbase.security.visibility.VisibilityController;
import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
import org.apache.hadoop.hbase.util.Bytes;
@ -1506,4 +1514,44 @@ public class MasterRpcServices extends RSRpcServices
response.setEnabled(master.isBalancerOn());
return response.build();
}
/**
* Returns the security capabilities in effect on the cluster
*/
@Override
public SecurityCapabilitiesResponse getSecurityCapabilities(RpcController controller,
SecurityCapabilitiesRequest request) throws ServiceException {
SecurityCapabilitiesResponse.Builder response = SecurityCapabilitiesResponse.newBuilder();
try {
master.checkInitialized();
Set<Capability> capabilities = new HashSet<>();
// Authentication
if (User.isHBaseSecurityEnabled(master.getConfiguration())) {
capabilities.add(Capability.SECURE_AUTHENTICATION);
} else {
capabilities.add(Capability.SIMPLE_AUTHENTICATION);
}
// The AccessController can provide AUTHORIZATION and CELL_AUTHORIZATION
if (master.cpHost != null &&
master.cpHost.findCoprocessor(AccessController.class.getName()) != null) {
if (AccessController.isAuthorizationSupported(master.getConfiguration())) {
capabilities.add(Capability.AUTHORIZATION);
}
if (AccessController.isCellAuthorizationSupported(master.getConfiguration())) {
capabilities.add(Capability.CELL_AUTHORIZATION);
}
}
// The VisibilityController can provide CELL_VISIBILITY
if (master.cpHost != null &&
master.cpHost.findCoprocessor(VisibilityController.class.getName()) != null) {
if (VisibilityController.isCellAuthorizationSupported(master.getConfiguration())) {
capabilities.add(Capability.CELL_VISIBILITY);
}
}
response.addAllCapabilities(capabilities);
} catch (IOException e) {
throw new ServiceException(e);
}
return response.build();
}
}

View File

@ -208,6 +208,15 @@ public class AccessController extends BaseMasterAndRegionObserver
/** if the ACL table is available, only relevant in the master */
private volatile boolean aclTabAvailable = false;
public static boolean isAuthorizationSupported(Configuration conf) {
return conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
}
public static boolean isCellAuthorizationSupported(Configuration conf) {
return isAuthorizationSupported(conf) &&
(HFile.getFormatVersion(conf) >= HFile.MIN_FORMAT_VERSION_WITH_TAGS);
}
public Region getRegion() {
return regionEnv != null ? regionEnv.getRegion() : null;
}
@ -923,7 +932,7 @@ public class AccessController extends BaseMasterAndRegionObserver
CompoundConfiguration conf = new CompoundConfiguration();
conf.add(env.getConfiguration());
authorizationEnabled = conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
authorizationEnabled = isAuthorizationSupported(conf);
if (!authorizationEnabled) {
LOG.warn("The AccessController has been loaded with authorization checks disabled.");
}
@ -931,7 +940,7 @@ public class AccessController extends BaseMasterAndRegionObserver
shouldCheckExecPermission = conf.getBoolean(AccessControlConstants.EXEC_PERMISSION_CHECKS_KEY,
AccessControlConstants.DEFAULT_EXEC_PERMISSION_CHECKS);
cellFeaturesEnabled = HFile.getFormatVersion(conf) >= HFile.MIN_FORMAT_VERSION_WITH_TAGS;
cellFeaturesEnabled = (HFile.getFormatVersion(conf) >= HFile.MIN_FORMAT_VERSION_WITH_TAGS);
if (!cellFeaturesEnabled) {
LOG.info("A minimum HFile version of " + HFile.MIN_FORMAT_VERSION_WITH_TAGS
+ " is required to persist cell ACLs. Consider setting " + HFile.FORMAT_VERSION_KEY

View File

@ -148,11 +148,19 @@ public class VisibilityController extends BaseMasterAndRegionObserver implements
RESERVED_VIS_TAG_TYPES.add(TagType.STRING_VIS_TAG_TYPE);
}
public static boolean isAuthorizationSupported(Configuration conf) {
return conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
}
public static boolean isCellAuthorizationSupported(Configuration conf) {
return isAuthorizationSupported(conf);
}
@Override
public void start(CoprocessorEnvironment env) throws IOException {
this.conf = env.getConfiguration();
authorizationEnabled = conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
authorizationEnabled = isAuthorizationSupported(conf);
if (!authorizationEnabled) {
LOG.warn("The VisibilityController has been loaded with authorization checks disabled.");
}

View File

@ -67,6 +67,7 @@ import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.security.SecurityCapability;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.coprocessor.CoprocessorService;
import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
@ -317,6 +318,16 @@ public class TestAccessController extends SecureTestUtil {
TEST_TABLE.getNamespaceAsString()).size());
}
@Test
public void testSecurityCapabilities() throws Exception {
List<SecurityCapability> capabilities = TEST_UTIL.getConnection().getAdmin()
.getSecurityCapabilities();
assertTrue("AUTHORIZATION capability is missing",
capabilities.contains(SecurityCapability.AUTHORIZATION));
assertTrue("CELL_AUTHORIZATION capability is missing",
capabilities.contains(SecurityCapability.CELL_AUTHORIZATION));
}
@Test
public void testTableCreate() throws Exception {
AccessTestAction createTable = new AccessTestAction() {

View File

@ -55,6 +55,7 @@ import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.RowMutations;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.security.SecurityCapability;
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionActionResult;
import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsResponse;
import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
@ -116,6 +117,14 @@ public abstract class TestVisibilityLabels {
killedRS = false;
}
@Test
public void testSecurityCapabilities() throws Exception {
List<SecurityCapability> capabilities = TEST_UTIL.getConnection().getAdmin()
.getSecurityCapabilities();
assertTrue("CELL_VISIBILITY capability is missing",
capabilities.contains(SecurityCapability.CELL_VISIBILITY));
}
@Test
public void testSimpleVisibilityLabels() throws Exception {
TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());

View File

@ -1031,5 +1031,10 @@ module Hbase
end
end
#----------------------------------------------------------------------------------------------
# Get security capabilities
def get_security_capabilities
@admin.getSecurityCapabilities
end
end
end

View File

@ -182,10 +182,23 @@ module Hbase
end
end
# Make sure that security tables are available
# Make sure that security features are available
def security_available?()
raise(ArgumentError, "DISABLED: Security features are not available") \
unless exists?(org.apache.hadoop.hbase.security.access.AccessControlLists::ACL_TABLE_NAME)
caps = []
begin
# Try the getSecurityCapabilities API where supported.
# We only need to look at AUTHORIZATION, the AccessController doesn't support
# CELL_AUTHORIZATION without AUTHORIZATION also available.
caps = @admin.getSecurityCapabilities
rescue
# If we are unable to use getSecurityCapabilities, fall back with a check for
# deployment of the ACL table
raise(ArgumentError, "DISABLED: Security features are not available") unless \
exists?(org.apache.hadoop.hbase.security.access.AccessControlLists::ACL_TABLE_NAME)
return
end
raise(ArgumentError, "DISABLED: Security features are not available") unless \
caps.include? org.apache.hadoop.hbase.client.security.SecurityCapability::AUTHORIZATION
end
end
end

View File

@ -35,7 +35,7 @@ module Hbase
end
def add_labels(*args)
lables_table_available?
visibility_feature_available?
# Normalize args
if args.kind_of?(Array)
labels = [ args ].flatten.compact
@ -63,7 +63,7 @@ module Hbase
end
def set_auths(user, *args)
lables_table_available?
visibility_feature_available?
# Normalize args
if args.kind_of?(Array)
auths = [ args ].flatten.compact
@ -88,7 +88,7 @@ module Hbase
end
def get_auths(user)
lables_table_available?
visibility_feature_available?
begin
response = VisibilityClient.getAuths(@connection, user)
if response.nil?
@ -102,7 +102,7 @@ module Hbase
end
def list_labels(regex = ".*")
lables_table_available?
visibility_feature_available?
begin
response = VisibilityClient.listLabels(@connection, regex)
if response.nil?
@ -116,7 +116,7 @@ module Hbase
end
def clear_auths(user, *args)
lables_table_available?
visibility_feature_available?
# Normalize args
if args.kind_of?(Array)
auths = [ args ].flatten.compact
@ -141,9 +141,20 @@ module Hbase
end
# Make sure that lables table is available
def lables_table_available?()
raise(ArgumentError, "DISABLED: Visibility labels feature is not available") \
unless exists?(VisibilityConstants::LABELS_TABLE_NAME)
def visibility_feature_available?()
caps = []
begin
# Try the getSecurityCapabilities API where supported.
caps = @admin.getSecurityCapabilities
rescue
# If we are unable to use getSecurityCapabilities, fall back with a check for
# deployment of the labels table
raise(ArgumentError, "DISABLED: Visibility labels feature is not available") unless \
exists?(VisibilityConstants::LABELS_TABLE_NAME)
return
end
raise(ArgumentError, "DISABLED: Visibility labels feature is not available") unless \
caps.include? org.apache.hadoop.hbase.client.security.SecurityCapability::CELL_VISIBILITY
end
# Does table exist?

View File

@ -396,6 +396,7 @@ Shell.load_command_group(
:full_name => 'SECURITY TOOLS',
:comment => "NOTE: Above commands are only applicable if running with the AccessController coprocessor",
:commands => %w[
list_security_capabilities
grant
revoke
user_permission

View File

@ -0,0 +1,47 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
module Shell
module Commands
class ListSecurityCapabilities < Command
def help
return <<-EOF
List supported security capabilities
Example:
hbase> list_security_capabilities
EOF
end
def command()
begin
list = admin.get_security_capabilities
list.each do |s|
puts s.getName
end
return list.map { |s| s.getName() }
rescue Exception => e
if e.to_s.include? "UnsupportedOperationException"
puts "ERROR: Master does not support getSecurityCapabilities"
return []
end
raise e
end
end
end
end
end