package com.thinkbiganalytics.datalake.authorization.client; /*- * #%L * thinkbig-sentry-client * %% * Copyright (C) 2017 ThinkBig Analytics * %% * Licensed 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. * #L% */ import com.thinkbiganalytics.datalake.authorization.hdfs.HDFSUtil; import com.thinkbiganalytics.datalake.authorization.model.HadoopAuthorizationGroup; import com.thinkbiganalytics.datalake.authorization.model.SentryGroup; import com.thinkbiganalytics.datalake.authorization.model.SentrySearchPolicy; import com.thinkbiganalytics.datalake.authorization.model.SentrySearchPolicyMapper; import org.apache.hadoop.conf.Configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jdbc.core.JdbcTemplate; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** */ public class SentryClient { private static final Logger log = LoggerFactory.getLogger(SentryClient.class); private SentryClientConfig clientConfig; private JdbcTemplate sentryJdbcTemplate; public SentryClient() { } public SentryClient(SentryClientConfig config) { this.clientConfig = config; this.sentryJdbcTemplate = config.getSentryJdbcTemplate(); try { setDriverClass(config.getDriverName()); } catch (ClassNotFoundException e) { throw new RuntimeException("Unable to set Driver Class " + e.getMessage()); } } public void setDriverClass(String driverName) throws ClassNotFoundException { Class.forName(driverName); } /** * @param roleName : Role name to be created */ public boolean createRole(String roleName) throws SentryClientException { this.sentryJdbcTemplate.execute("create role " + roleName); log.warn("Sentry role " + roleName + " created successfully."); return true; } /** * @param roleName : Role to be deleted. */ public boolean dropRole(String roleName) throws SentryClientException { this.sentryJdbcTemplate.execute("drop role " + roleName); log.info("Role " + roleName + " dropped successfully "); return true; } /** * @param roleName : Sentry Role name * @param groupName : group name to be granted */ public boolean grantRoleToGroup(String roleName, String groupName) throws SentryClientException { String queryString = "GRANT ROLE " + roleName + " TO GROUP " + groupName + ""; this.sentryJdbcTemplate.execute(queryString); log.info("Role " + roleName + " is assigned to group " + groupName + ". "); return true; } /** * @param previledge : ALL/Select * @param objectType : DATABASE/TABLE * @param objectName : Database name or table name * @param roleName : Role name to be granted */ public boolean grantRolePriviledges(String previledge, String objectType, String objectName, String roleName) throws SentryClientException { String dbName[] = objectName.split("\\."); String useDB = "use " + dbName[0] + ""; String queryString = "GRANT " + previledge + " ON " + objectType + " " + objectName + " TO ROLE " + roleName; log.info("Sentry Query Formed --" + queryString); try { this.sentryJdbcTemplate.execute(useDB); this.sentryJdbcTemplate.execute(queryString); log.info("Successfully assigned priviledge " + previledge + " to role " + roleName + " on " + objectName + "."); return true; } catch (ArrayIndexOutOfBoundsException e) { log.error("Failed to obtain database name from " + objectName + ". Routing to failure."); throw new ArrayIndexOutOfBoundsException("Failed to obtain database name from " + objectName + ". Routing to failure." + e.getMessage()); } } /** * @param roleName : Check role if it is already created by Kylo * @return true/false */ public boolean checkIfRoleExists(String roleName) { boolean matchFound = false; String queryString = "SHOW ROLES"; List<SentrySearchPolicy> sentryPolicy = this.sentryJdbcTemplate.query(queryString, new SentrySearchPolicyMapper()); if (sentryPolicy.isEmpty()) { matchFound = false; } else { for (SentrySearchPolicy policyName : sentryPolicy) { if (policyName.getRole().equalsIgnoreCase(roleName)) { matchFound = true; break; } else { matchFound = false; } } } if (matchFound) { /** * Return true of role is present in result set */ log.info("Role " + roleName + " found in Sentry database."); return true; } else { log.info("Role " + roleName + " not found in Sentry database."); return false; } } public boolean revokeRoleFromGroup() { return false; } public boolean revokeRolePriviledges() { return false; } @SuppressWarnings("static-access") public boolean createAcl(String HadoopConfigurationResource, String groups, String allPathForAclCreation, String hdfsPermission) { try { SentryClientConfig sentryConfig = new SentryClientConfig(); HDFSUtil hdfsUtil = new HDFSUtil(); Configuration conf = sentryConfig.getConfig(); conf = hdfsUtil.getConfigurationFromResources(HadoopConfigurationResource); hdfsUtil.splitPathListAndApplyPolicy(allPathForAclCreation, conf, sentryConfig.getFileSystem(), groups, hdfsPermission); return true; } catch (Exception e) { throw new RuntimeException("Unable to create ACL " + e); } } /** * @param HadoopConfigurationResource : Hadoop HDFS Configuraiton Files * @param allPathForAclDeletion : List paths for deleting ACL */ @SuppressWarnings("static-access") public boolean flushACL(String HadoopConfigurationResource, String allPathForAclDeletion) { try { SentryClientConfig sentryConfig = new SentryClientConfig(); HDFSUtil hdfsUtil = new HDFSUtil(); Configuration conf = sentryConfig.getConfig(); conf = hdfsUtil.getConfigurationFromResources(HadoopConfigurationResource); hdfsUtil.splitPathListAndFlushPolicy(allPathForAclDeletion, conf, sentryConfig.getFileSystem()); return true; } catch (IOException e) { throw new RuntimeException("Unable to flush ACL " + e); } } /** * Get default Kylo groups */ public List<HadoopAuthorizationGroup> getAllGroups() { List<HadoopAuthorizationGroup> sentryHadoopAuthorizationGroups = new ArrayList<>(); SentryGroup hadoopAuthorizationGroup = new SentryGroup(); String sentryGroups = this.clientConfig.getSentryGroups(); List<String> sentryGroupsList = new ArrayList<String>(Arrays.asList(sentryGroups.split(","))); int sentryId = 0; String sentryIdPrefix = "kyloGroup"; for (String group : sentryGroupsList) { sentryId = sentryId + 1; sentryIdPrefix = sentryIdPrefix + "_" + sentryId; hadoopAuthorizationGroup.setId(sentryIdPrefix); hadoopAuthorizationGroup.setDescription("This is dummy group generated by Kylo."); hadoopAuthorizationGroup.setName(group); hadoopAuthorizationGroup.setOwner("thinkbig"); sentryHadoopAuthorizationGroups.add(hadoopAuthorizationGroup); sentryIdPrefix = "kyloGroup"; hadoopAuthorizationGroup = new SentryGroup(); } return sentryHadoopAuthorizationGroups; } }