[Improvement](auth)(step-1) add ranger authorizer for hms catalog (#17153)

This commit is contained in:
Yulei-Yang
2023-03-03 09:45:08 +08:00
committed by GitHub
parent 227d2b0bf9
commit 449f2953c9
9 changed files with 724 additions and 0 deletions

View File

@ -0,0 +1,23 @@
// 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.doris.catalog.authorizer;
public enum HiveAccessType {
NONE, CREATE, ALTER, DROP, INDEX, LOCK, SELECT, UPDATE, USE, READ, WRITE, ALL, SERVICEADMIN,
TEMPUDFADMIN;
}

View File

@ -0,0 +1,22 @@
// 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.doris.catalog.authorizer;
public enum HiveObjectType {
NONE, DATABASE, TABLE, VIEW, INDEX, COLUMN, FUNCTION;
}

View File

@ -0,0 +1,190 @@
// 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.doris.catalog.authorizer;
import org.apache.doris.analysis.UserIdentity;
import org.apache.doris.common.AuthorizationException;
import org.apache.doris.mysql.privilege.CatalogAccessController;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAccessControlException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class RangerHiveAccessController implements CatalogAccessController {
public static final String CLIENT_TYPE_DORIS = "doris";
private static final Logger LOG = LogManager.getLogger(RangerHiveAccessController.class);
private RangerHivePlugin hivePlugin;
private RangerHiveAuditHandler auditHandler;
public RangerHiveAccessController(Map<String, String> properties) {
String serviceName = properties.get("ranger.service.name");
hivePlugin = new RangerHivePlugin(serviceName);
auditHandler = new RangerHiveAuditHandler(hivePlugin.getConfig());
}
private RangerAccessRequestImpl createRequest(UserIdentity currentUser, HiveAccessType accessType) {
RangerAccessRequestImpl request = new RangerAccessRequestImpl();
request.setUser(currentUser.getQualifiedUser());
request.setUserRoles(currentUser.getRoles());
request.setAction(accessType.name());
if (accessType == HiveAccessType.USE) {
request.setAccessType(RangerPolicyEngine.ANY_ACCESS);
} else {
request.setAccessType(accessType.name().toLowerCase());
}
request.setClientIPAddress(currentUser.getHost());
request.setClientType(CLIENT_TYPE_DORIS);
request.setAccessTime(new Date());
return request;
}
private void checkPrivileges(UserIdentity currentUser, HiveAccessType accessType,
List<RangerHiveResource> hiveResources) throws AuthorizationException {
try {
List<RangerAccessRequest> requests = new ArrayList<>();
for (RangerHiveResource resource : hiveResources) {
RangerAccessRequestImpl request = createRequest(currentUser, accessType);
request.setResource(resource);
requests.add(request);
}
Collection<RangerAccessResult> results = hivePlugin.isAccessAllowed(requests, auditHandler);
for (RangerAccessResult result : results) {
LOG.debug("match policy:" + result.getPolicyId());
if (!result.getIsAllowed()) {
LOG.debug(result.getReason());
throw new AuthorizationException(String.format(
"Permission denied: user [%s] does not have privilege for [%s] command on [%s]",
currentUser.getQualifiedUser(), accessType.name(),
result.getAccessRequest().getResource().getAsString()));
}
}
} finally {
auditHandler.flushAudit();
}
}
private boolean checkPrivilege(UserIdentity currentUser, HiveAccessType accessType,
RangerHiveResource resource) {
RangerAccessRequestImpl request = createRequest(currentUser, accessType);
request.setResource(resource);
RangerAccessResult result = hivePlugin.isAccessAllowed(request, auditHandler);
auditHandler.flushAudit();
if (result == null) {
LOG.warn(String.format("Error getting authorizer result, please check your ranger config. Request: %s",
request));
return false;
}
if (result.getIsAllowed()) {
return true;
} else {
LOG.debug(String.format(
"Permission denied: user [%s] does not have privilege for [%s] command on [%s]",
currentUser.getQualifiedUser(), accessType.name(),
result.getAccessRequest().getResource().getAsString()));
return false;
}
}
public String getFilterExpr(UserIdentity currentUser, HiveAccessType accessType,
RangerHiveResource resource) throws HiveAccessControlException {
RangerAccessRequestImpl request = createRequest(currentUser, accessType);
request.setResource(resource);
RangerAccessResult result = hivePlugin.isAccessAllowed(request, auditHandler);
auditHandler.flushAudit();
return result.getFilterExpr();
}
public void getColumnMask(UserIdentity currentUser, HiveAccessType accessType,
RangerHiveResource resource) {
RangerAccessRequestImpl request = createRequest(currentUser, accessType);
request.setResource(resource);
RangerAccessResult result = hivePlugin.isAccessAllowed(request, auditHandler);
auditHandler.flushAudit();
LOG.debug(String.format("maskType: %s, maskTypeDef: %s, maskedValue: %s", result.getMaskType(),
result.getMaskTypeDef(), result.getMaskedValue()));
}
public HiveAccessType convertToAccessType(PrivPredicate predicate) {
if (predicate == PrivPredicate.SHOW) {
return HiveAccessType.USE;
} else if (predicate == PrivPredicate.ADMIN) {
return HiveAccessType.ALL;
} else if (predicate == PrivPredicate.LOAD) {
return HiveAccessType.UPDATE;
} else if (predicate == PrivPredicate.ALTER) {
return HiveAccessType.ALTER;
} else if (predicate == PrivPredicate.CREATE) {
return HiveAccessType.CREATE;
} else if (predicate == PrivPredicate.DROP) {
return HiveAccessType.DROP;
} else if (predicate == PrivPredicate.SELECT) {
return HiveAccessType.SELECT;
} else {
return HiveAccessType.NONE;
}
}
@Override
public boolean checkCtlPriv(UserIdentity currentUser, String ctl, PrivPredicate wanted) {
return false;
}
@Override
public boolean checkDbPriv(UserIdentity currentUser, String ctl, String db, PrivPredicate wanted) {
RangerHiveResource resource = new RangerHiveResource(HiveObjectType.DATABASE, db);
return checkPrivilege(currentUser, convertToAccessType(wanted), resource);
}
@Override
public boolean checkTblPriv(UserIdentity currentUser, String ctl, String db, String tbl, PrivPredicate wanted) {
RangerHiveResource resource = new RangerHiveResource(HiveObjectType.TABLE, db, tbl);
return checkPrivilege(currentUser, convertToAccessType(wanted), resource);
}
@Override
public void checkColsPriv(UserIdentity currentUser, String ctl, String db, String tbl, Set<String> cols,
PrivPredicate wanted) throws AuthorizationException {
List<RangerHiveResource> resources = new ArrayList<>();
for (String col : cols) {
RangerHiveResource resource = new RangerHiveResource(HiveObjectType.COLUMN, db, tbl, col);
resources.add(resource);
}
checkPrivileges(currentUser, convertToAccessType(wanted), resources);
}
}

View File

@ -0,0 +1,30 @@
// 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.doris.catalog.authorizer;
import org.apache.doris.mysql.privilege.AccessControllerFactory;
import org.apache.doris.mysql.privilege.CatalogAccessController;
import java.util.Map;
public class RangerHiveAccessControllerFactory implements AccessControllerFactory {
@Override
public CatalogAccessController createAccessController(Map<String, String> prop) {
return new RangerHiveAccessController(prop);
}
}

View File

@ -0,0 +1,270 @@
// 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.doris.catalog.authorizer;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType;
import org.apache.ranger.audit.model.AuthzAuditEvent;
import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
public static final String ACCESS_TYPE_ROWFILTER = "ROW_FILTER";
public static final String ACCESS_TYPE_INSERT = "INSERT";
public static final String ACCESS_TYPE_UPDATE = "UPDATE";
public static final String ACCESS_TYPE_DELETE = "DELETE";
public static final String ACCESS_TYPE_TRUNCATE = "TRUNCATE";
public static final String ACTION_TYPE_METADATA_OPERATION = "METADATA OPERATION";
public static final String CONF_AUDIT_QUERY_REQUEST_SIZE = "xasecure.audit.solr.limit.query.req.size";
public static final int DEFAULT_CONF_AUDIT_QUERY_REQUEST_SIZE = Integer.MAX_VALUE;
private static final Logger LOG = LoggerFactory.getLogger(RangerDefaultAuditHandler.class);
private static final Set<String> ROLE_OPS = new HashSet<>();
static {
for (HiveOperationType e : EnumSet.of(HiveOperationType.CREATEROLE, HiveOperationType.DROPROLE,
HiveOperationType.SHOW_ROLES, HiveOperationType.SHOW_ROLE_GRANT, HiveOperationType.SHOW_ROLE_PRINCIPALS,
HiveOperationType.GRANT_ROLE, HiveOperationType.REVOKE_ROLE)) {
ROLE_OPS.add(e.name());
}
}
private final int requestQuerySize;
private final Collection<AuthzAuditEvent> auditEvents = new ArrayList<>();
private boolean deniedExists = false;
public RangerHiveAuditHandler() {
super();
requestQuerySize = DEFAULT_CONF_AUDIT_QUERY_REQUEST_SIZE;
}
public RangerHiveAuditHandler(Configuration config) {
super(config);
int configRequestQuerySize = config.getInt(CONF_AUDIT_QUERY_REQUEST_SIZE,
DEFAULT_CONF_AUDIT_QUERY_REQUEST_SIZE);
requestQuerySize = (configRequestQuerySize < 1) ? DEFAULT_CONF_AUDIT_QUERY_REQUEST_SIZE :
configRequestQuerySize;
}
AuthzAuditEvent createAuditEvent(RangerAccessResult result, String accessType, String resourcePath) {
RangerAccessRequest request = result.getAccessRequest();
RangerAccessResource resource = request.getResource();
String resourceType = resource != null ? resource.getLeafName() : null;
AuthzAuditEvent auditEvent = super.getAuthzEvents(result);
String resourcePathComputed = resourcePath;
if (LOG.isDebugEnabled()) {
LOG.debug("requestQuerySize = " + requestQuerySize);
}
if (StringUtils.isNotBlank(request.getRequestData()) && request.getRequestData().length() > requestQuerySize) {
auditEvent.setRequestData(request.getRequestData().substring(0, requestQuerySize));
} else {
auditEvent.setRequestData(request.getRequestData());
}
auditEvent.setAccessType(accessType);
auditEvent.setResourcePath(resourcePathComputed);
auditEvent.setResourceType("@" + resourceType); // to be consistent with earlier release
if (request instanceof RangerAccessRequestImpl && resource instanceof RangerHiveResource) {
RangerAccessRequestImpl hiveAccessRequest = (RangerAccessRequestImpl) request;
RangerHiveResource hiveResource = (RangerHiveResource) resource;
String hiveAccessType = hiveAccessRequest.getAccessType();
if (HiveAccessType.USE.toString().equalsIgnoreCase(hiveAccessType) && hiveResource.getObjectType()
== HiveObjectType.DATABASE && StringUtils.isBlank(hiveResource.getDatabase())) {
// this should happen only for SHOWDATABASES
auditEvent.setTags(null);
}
}
return auditEvent;
}
AuthzAuditEvent createAuditEvent(RangerAccessResult result) {
final AuthzAuditEvent ret;
RangerAccessRequest request = result.getAccessRequest();
RangerAccessResource resource = request.getResource();
String resourcePath = resource != null ? resource.getAsString() : null;
int policyType = result.getPolicyType();
if (policyType == RangerPolicy.POLICY_TYPE_DATAMASK && result.isMaskEnabled()) {
ret = createAuditEvent(result, result.getMaskType(), resourcePath);
} else if (policyType == RangerPolicy.POLICY_TYPE_ROWFILTER) {
ret = createAuditEvent(result, ACCESS_TYPE_ROWFILTER, resourcePath);
} else if (policyType == RangerPolicy.POLICY_TYPE_ACCESS) {
String accessType = null;
if (request instanceof RangerAccessRequestImpl) {
RangerAccessRequestImpl hiveRequest = (RangerAccessRequestImpl) request;
accessType = hiveRequest.getAccessType();
String action = request.getAction();
if (ACTION_TYPE_METADATA_OPERATION.equals(action)) {
accessType = ACTION_TYPE_METADATA_OPERATION;
} else if (HiveAccessType.UPDATE.toString().equalsIgnoreCase(accessType)) {
String commandStr = request.getRequestData();
if (StringUtils.isNotBlank(commandStr)) {
if (StringUtils.startsWithIgnoreCase(commandStr, ACCESS_TYPE_INSERT)) {
accessType = ACCESS_TYPE_INSERT;
} else if (StringUtils.startsWithIgnoreCase(commandStr, ACCESS_TYPE_UPDATE)) {
accessType = ACCESS_TYPE_UPDATE;
} else if (StringUtils.startsWithIgnoreCase(commandStr, ACCESS_TYPE_DELETE)) {
accessType = ACCESS_TYPE_DELETE;
} else if (StringUtils.startsWithIgnoreCase(commandStr, ACCESS_TYPE_TRUNCATE)) {
accessType = ACCESS_TYPE_TRUNCATE;
}
}
}
}
if (StringUtils.isEmpty(accessType)) {
accessType = request.getAccessType();
}
ret = createAuditEvent(result, accessType, resourcePath);
} else {
ret = null;
}
return ret;
}
List<AuthzAuditEvent> createAuditEvents(Collection<RangerAccessResult> results) {
Map<Long, AuthzAuditEvent> auditEventsMap = new HashMap<>();
Iterator<RangerAccessResult> iterator = results.iterator();
AuthzAuditEvent deniedAuditEvent = null;
while (iterator.hasNext() && deniedAuditEvent == null) {
RangerAccessResult result = iterator.next();
if (result.getIsAudited()) {
if (!result.getIsAllowed()) {
deniedAuditEvent = createAuditEvent(result);
} else {
long policyId = result.getPolicyId();
// add this result to existing event by updating column values
if (auditEventsMap.containsKey(policyId)) {
AuthzAuditEvent auditEvent = auditEventsMap.get(policyId);
RangerAccessRequestImpl request = (RangerAccessRequestImpl) result.getAccessRequest();
RangerHiveResource resource = (RangerHiveResource) request.getResource();
String resourcePath = auditEvent.getResourcePath() + "," + resource.getColumn();
auditEvent.setResourcePath(resourcePath);
Set<String> tags = getTags(request);
if (tags != null) {
auditEvent.getTags().addAll(tags);
}
} else { // new event as this approval was due to a different policy.
AuthzAuditEvent auditEvent = createAuditEvent(result);
if (auditEvent != null) {
auditEventsMap.put(policyId, auditEvent);
}
}
}
}
}
final List<AuthzAuditEvent> result = (deniedAuditEvent == null) ? new ArrayList<>(auditEventsMap.values())
: Collections.singletonList(deniedAuditEvent);
return result;
}
@Override
public void processResult(RangerAccessResult result) {
if (result == null || !result.getIsAudited()) {
return;
}
if (skipFilterOperationAuditing(result)) {
return;
}
AuthzAuditEvent auditEvent = createAuditEvent(result);
if (auditEvent != null) {
addAuthzAuditEvent(auditEvent);
}
}
/**
* This method is expected to be called ONLY to process the results for multiple-columns in a table.
* To ensure this, RangerHiveAccessController should call isAccessAllowed(Collection<requests>) only for this
* condition
*/
@Override
public void processResults(Collection<RangerAccessResult> results) {
List<AuthzAuditEvent> result = createAuditEvents(results);
for (AuthzAuditEvent auditEvent : result) {
addAuthzAuditEvent(auditEvent);
}
}
public void flushAudit() {
for (AuthzAuditEvent auditEvent : auditEvents) {
if (deniedExists && auditEvent.getAccessResult() != 0) { // if deny exists, skip logging for allowed results
continue;
}
super.logAuthzAudit(auditEvent);
}
}
private void addAuthzAuditEvent(AuthzAuditEvent auditEvent) {
if (auditEvent != null) {
auditEvents.add(auditEvent);
if (auditEvent.getAccessResult() == 0) {
deniedExists = true;
}
}
}
private boolean skipFilterOperationAuditing(RangerAccessResult result) {
boolean ret = false;
RangerAccessRequest accessRequest = result.getAccessRequest();
if (accessRequest != null) {
String action = accessRequest.getAction();
if (ACTION_TYPE_METADATA_OPERATION.equals(action) && !result.getIsAllowed()) {
ret = true;
}
}
return ret;
}
}

View File

@ -0,0 +1,49 @@
// 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.doris.catalog.authorizer;
import java.util.Map;
public class RangerHiveAuthorizerProvider {
private static volatile Map<String, RangerHivePlugin> hivePluginMap = null;
/**
* if some catalogs use a same ranger hive service, make them share the same authorizer plugin
*
* @param serviceUrl url of ranger admin
* @param serviceName name of hive service in ranger admin
* @return
*/
public static RangerHivePlugin getHivePlugin(String serviceUrl, String serviceName) {
String id = serviceUrl + serviceName;
if (!hivePluginMap.containsKey(id)) {
synchronized (RangerHiveAuthorizerProvider.class) {
if (!hivePluginMap.containsKey(id)) {
RangerHivePlugin plugin = new RangerHivePlugin(serviceUrl + serviceName);
plugin.init();
hivePluginMap.put(id, plugin);
}
}
}
return hivePluginMap.get(id);
}
}

View File

@ -0,0 +1,27 @@
// 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.doris.catalog.authorizer;
import org.apache.ranger.plugin.service.RangerBasePlugin;
public class RangerHivePlugin extends RangerBasePlugin {
public RangerHivePlugin(String serviceName) {
super(serviceName, null, null);
super.init();
}
}

View File

@ -0,0 +1,96 @@
// 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.doris.catalog.authorizer;
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
public class RangerHiveResource extends RangerAccessResourceImpl {
public static final String KEY_DATABASE = "database";
public static final String KEY_TABLE = "table";
public static final String KEY_UDF = "udf";
public static final String KEY_COLUMN = "column";
private HiveObjectType objectType;
//FirstLevelResource => Database
//SecondLevelResource => Table or UDF
//ThirdLevelResource => column
public RangerHiveResource(HiveObjectType objectType, String firstLevelResource) {
this(objectType, firstLevelResource, null, null);
}
public RangerHiveResource(HiveObjectType objectType, String firstLevelResource, String secondLevelResource) {
this(objectType, firstLevelResource, secondLevelResource, null);
}
public RangerHiveResource(HiveObjectType objectType, String firstLevelResource, String secondLevelResource,
String thirdLevelResource) {
this.objectType = objectType;
// set essential info according to objectType
switch (objectType) {
case DATABASE:
setValue(KEY_DATABASE, firstLevelResource);
break;
case FUNCTION:
if (firstLevelResource == null) {
firstLevelResource = "";
}
setValue(KEY_DATABASE, firstLevelResource);
setValue(KEY_UDF, secondLevelResource);
break;
case COLUMN:
setValue(KEY_DATABASE, firstLevelResource);
setValue(KEY_TABLE, secondLevelResource);
setValue(KEY_COLUMN, thirdLevelResource);
break;
case TABLE:
case VIEW:
case INDEX:
setValue(KEY_DATABASE, firstLevelResource);
setValue(KEY_TABLE, secondLevelResource);
break;
case NONE:
default:
break;
}
}
public HiveObjectType getObjectType() {
return objectType;
}
public String getDatabase() {
return (String) getValue(KEY_DATABASE);
}
public String getTable() {
return (String) getValue(KEY_TABLE);
}
public String getUdf() {
return (String) getValue(KEY_UDF);
}
public String getColumn() {
return (String) getValue(KEY_COLUMN);
}
}