Repository: zeppelin
Updated Branches:
  refs/heads/master 1a2cceddf -> 05bc60c07


[ZEPPELIN-1146] Zeppelin JDBC interpreter should work in a Kerberos environment

### What is this PR for?
Zeppelin JDBC interpreter should work in a Kerberos environment

### What type of PR is it?
[Bug Fix]

### Todos
* [x] - Update doc

### What is the Jira issue?
* [ZEPPELIN-1146](https://issues.apache.org/jira/browse/ZEPPELIN-1146)

### How should this be tested?
In JDBC interpreter setting add following properties

 - zeppelin.jdbc.auth.type = KERBEROS
 - zeppelin.jdbc.principal = principal value
 - zeppelin.jdbc.keytab.location = keytab location

Now try and run any of hive's query (say `show tables`) it should return with 
valid results.

### Questions:
* Does the licenses files need update? no
* Is there breaking changes for older versions? no
* Does this needs documentation? yes

Author: Prabhjyot Singh <[email protected]>

Closes #1157 from prabhjyotsingh/ZEPPELIN-1146 and squashes the following 
commits:

c4add61 [Prabhjyot Singh] make hadoop-common scope as provided
f5fe7db [Prabhjyot Singh] correctin logger name class
b11eef4 [Prabhjyot Singh] add doc for kerberos
c36cd67 [Prabhjyot Singh] ZEPPELIN-1146 Zeppelin JDBC interpreter should work 
in a Kerberos environment


Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/05bc60c0
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/05bc60c0
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/05bc60c0

Branch: refs/heads/master
Commit: 05bc60c07d3a5d69621682183ecdc9e25ce49f75
Parents: 1a2cced
Author: Prabhjyot Singh <[email protected]>
Authored: Tue Jul 12 19:27:21 2016 +0530
Committer: Prabhjyot Singh <[email protected]>
Committed: Thu Jul 14 10:10:49 2016 +0530

----------------------------------------------------------------------
 docs/interpreter/jdbc.md                        | 14 +++-
 jdbc/pom.xml                                    |  7 ++
 .../apache/zeppelin/jdbc/JDBCInterpreter.java   |  4 ++
 .../jdbc/security/JDBCSecurityImpl.java         | 72 ++++++++++++++++++++
 .../src/main/resources/interpreter-setting.json | 18 +++++
 5 files changed, 114 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/05bc60c0/docs/interpreter/jdbc.md
----------------------------------------------------------------------
diff --git a/docs/interpreter/jdbc.md b/docs/interpreter/jdbc.md
index 4615b14..2f49e49 100644
--- a/docs/interpreter/jdbc.md
+++ b/docs/interpreter/jdbc.md
@@ -183,7 +183,19 @@ You can modify the interpreter configuration in the 
`Interpreter` section. The m
    <tr>
      <td>common.max_result</td>
      <td>Max number of SQL result to display to prevent the browser overload. 
This is  common properties for all connections</td>
-   </tr>      
+   </tr>
+   <tr>
+     <td>zeppelin.jdbc.auth.type</td>
+     <td>Types of authentications' methods supported are SIMPLE, and 
KERBEROS</td>
+   </tr>
+   <tr>
+     <td>zeppelin.jdbc.principal</td>
+     <td>The principal name to load from the keytab</td>
+   </tr>
+   <tr>
+     <td>zeppelin.jdbc.keytab.location</td>
+     <td>The path to the keytab file</td>
+   </tr>
  </table>
 
 To develop this functionality use this 
[method](http://docs.oracle.com/javase/7/docs/api/java/sql/DriverManager.html#getConnection%28java.lang.String,%20java.util.Properties%29).
 For example if a connection needs a schema parameter, it would have to add the 
property as follows:

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/05bc60c0/jdbc/pom.xml
----------------------------------------------------------------------
diff --git a/jdbc/pom.xml b/jdbc/pom.xml
index c433e20..de2fe02 100644
--- a/jdbc/pom.xml
+++ b/jdbc/pom.xml
@@ -73,6 +73,13 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <version>2.7.2</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/05bc60c0/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java 
b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java
index 2da39d3..f3ef554 100644
--- a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java
+++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java
@@ -37,6 +37,7 @@ import org.apache.zeppelin.interpreter.InterpreterContext;
 import org.apache.zeppelin.interpreter.InterpreterResult;
 import org.apache.zeppelin.interpreter.InterpreterResult.Code;
 import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
+import org.apache.zeppelin.jdbc.security.JDBCSecurityImpl;
 import org.apache.zeppelin.scheduler.Scheduler;
 import org.apache.zeppelin.scheduler.SchedulerFactory;
 import org.slf4j.Logger;
@@ -171,6 +172,9 @@ public class JDBCInterpreter extends Interpreter {
 
     Connection connection = null;
     SqlCompleter sqlCompleter = null;
+    if 
(!StringUtils.isAnyEmpty(property.getProperty("zeppelin.jdbc.auth.type"))) {
+      JDBCSecurityImpl.createSecureConfiguration(property);
+    }
     for (String propertyKey : propertiesMap.keySet()) {
       try {
         connection = getConnection(propertyKey);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/05bc60c0/jdbc/src/main/java/org/apache/zeppelin/jdbc/security/JDBCSecurityImpl.java
----------------------------------------------------------------------
diff --git 
a/jdbc/src/main/java/org/apache/zeppelin/jdbc/security/JDBCSecurityImpl.java 
b/jdbc/src/main/java/org/apache/zeppelin/jdbc/security/JDBCSecurityImpl.java
new file mode 100644
index 0000000..03d957d
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/security/JDBCSecurityImpl.java
@@ -0,0 +1,72 @@
+/*
+ * 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.zeppelin.jdbc.security;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.zeppelin.jdbc.SqlCompleter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import static 
org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod.KERBEROS;
+import static 
org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod.SIMPLE;
+
+/**
+ * Created for org.apache.zeppelin.jdbc.security on 09/07/16.
+ */
+public class JDBCSecurityImpl {
+
+  private static Logger LOGGER = 
LoggerFactory.getLogger(JDBCSecurityImpl.class);
+
+  /***
+   * @param properties
+   */
+  public static void createSecureConfiguration(Properties properties) {
+    UserGroupInformation.AuthenticationMethod authType;
+    try {
+      authType = UserGroupInformation
+          
.AuthenticationMethod.valueOf(properties.getProperty("zeppelin.jdbc.auth.type")
+              .trim().toUpperCase());
+    } catch (Exception e) {
+      LOGGER.error(String.format("Invalid auth.type detected with value %s, 
defaulting " +
+          "auth.type to SIMPLE", 
properties.getProperty("zeppelin.jdbc.auth.type").trim()));
+      authType = SIMPLE;
+    }
+
+
+    switch (authType) {
+        case KERBEROS:
+          Configuration conf = new
+              org.apache.hadoop.conf.Configuration();
+          conf.set("hadoop.security.authentication", KERBEROS.toString());
+          UserGroupInformation.setConfiguration(conf);
+          try {
+            UserGroupInformation.loginUserFromKeytab(
+                properties.getProperty("zeppelin.jdbc.principal"),
+                properties.getProperty("zeppelin.jdbc.keytab.location")
+            );
+          } catch (IOException e) {
+            LOGGER.error("Failed to get either keytab location or principal 
name in the " +
+                "interpreter", e);
+          }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/05bc60c0/jdbc/src/main/resources/interpreter-setting.json
----------------------------------------------------------------------
diff --git a/jdbc/src/main/resources/interpreter-setting.json 
b/jdbc/src/main/resources/interpreter-setting.json
index 16594eb..289d4f8 100644
--- a/jdbc/src/main/resources/interpreter-setting.json
+++ b/jdbc/src/main/resources/interpreter-setting.json
@@ -34,6 +34,12 @@
         "defaultValue": "1000",
         "description": "Max number of SQL result to display."
       },
+      "zeppelin.jdbc.auth.type": {
+        "envName": null,
+        "propertyName": "zeppelin.jdbc.auth.type",
+        "defaultValue": "",
+        "description": "If auth type is needed, Example: KERBEROS"
+      },
       "zeppelin.jdbc.concurrent.use": {
         "envName": null,
         "propertyName": "zeppelin.jdbc.concurrent.use",
@@ -46,6 +52,18 @@
         "defaultValue": "10",
         "description": "Number of concurrent execution"
       },
+      "zeppelin.jdbc.keytab.location": {
+        "envName": null,
+        "propertyName": "zeppelin.jdbc.keytab.location",
+        "defaultValue": "",
+        "description": "Kerberos keytab location"
+      },
+      "zeppelin.jdbc.principal": {
+        "envName": null,
+        "propertyName": "zeppelin.jdbc.principal",
+        "defaultValue": "",
+        "description": "Kerberos principal"
+      },
       "hive.url": {
         "envName": null,
         "propertyName": "hive.url",

Reply via email to