-
Notifications
You must be signed in to change notification settings - Fork 2.8k
[Zeppelin 2367] Hive JDBC proxy user option should be available even without kerberos #2229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
8999d93
ee8a6b5
40489c8
01b18b9
d51e770
4c382ee
a751674
3fa2b1e
513987a
1802b45
c180f5c
e2bdbb2
a348e96
9fee9d2
45c90a8
84b5e55
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -169,10 +169,6 @@ There are more JDBC interpreter properties you can specify like below. | |
| <td>zeppelin.jdbc.keytab.location</td> | ||
| <td>The path to the keytab file</td> | ||
| </tr> | ||
| <tr> | ||
| <td>zeppelin.jdbc.auth.kerberos.proxy.enable</td> | ||
| <td>When auth type is Kerberos, enable/disable Kerberos proxy with the login user to get the connection. Default value is true.</td> | ||
| </tr> | ||
| <tr> | ||
| <td>default.jceks.file</td> | ||
| <td>jceks store path (e.g: jceks://file/tmp/zeppelin.jceks)</td> | ||
|
|
@@ -202,7 +198,7 @@ To bind the interpreters created in the interpreter setting page, click the gear | |
|
|
||
| <img src="../assets/themes/zeppelin/img/docs-img/click_interpreter_binding_button.png" width="600px" /> | ||
|
|
||
| Select(blue) or deselect(white) the interpreter buttons depending on your use cases. | ||
| Select(blue) or deselect(white) the interpreter buttons depending on your use cases. | ||
| If you need to use more than one interpreter in the notebook, activate several buttons. | ||
| Don't forget to click `Save` button, or you will face `Interpreter *** is not found` error. | ||
|
|
||
|
|
@@ -285,7 +281,7 @@ An example settings of interpreter for the two data sources, each of which has i | |
| </table> | ||
|
|
||
| ##### Usage | ||
| Test of execution *precode* for each data source. | ||
| Test of execution *precode* for each data source. | ||
|
|
||
| ```sql | ||
| %jdbc | ||
|
|
@@ -480,7 +476,7 @@ Here are some examples you can refer to. Including the below connectors, you can | |
|
|
||
| [Maven Repository: com.amazonaws:aws-java-sdk-redshift](https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-redshift) | ||
|
|
||
| ### Apache Hive | ||
| ### Apache Hive | ||
|
|
||
| <img src="../assets/themes/zeppelin/img/docs-img/hive_setting.png" width="600px" /> | ||
|
|
||
|
|
@@ -507,8 +503,9 @@ Here are some examples you can refer to. Including the below connectors, you can | |
| <td>hive_password</td> | ||
| </tr> | ||
| <tr> | ||
| <td>hive.proxy.user</td> | ||
| <td>true or false</td> | ||
| <td>default.proxy.user.property</td> | ||
| <td>hive.server2.proxy.user</td> | ||
| </tr> | ||
| </table> | ||
|
|
||
| Connection to Hive JDBC with a proxy user can be disabled with `hive.proxy.user` property (set to true by default) | ||
|
|
@@ -534,6 +531,14 @@ Connection to Hive JDBC with a proxy user can be disabled with `hive.proxy.user` | |
|
|
||
| [Maven Repository : org.apache.hive:hive-jdbc](https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc) | ||
|
|
||
| ##### Impersonation | ||
| When Zeppelin server is running with authentication enabled, then the interpreter can utilize Hive's user proxy feature i.e. send extra parameter for creating and running a session ("hive.server2.proxy.user=": "${loggedInUser}"). This is particularly useful when multiple users are sharing a notebooks. | ||
|
|
||
| To enable this set following: | ||
| - `zeppelin.jdbc.auth.type` as `SIMPLE` or `KERBEROS` (if required) in the interpreter setting. | ||
| - `default.proxy.user.property` as `hive.server2.proxy.user` | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we clarify,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, let me change this to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for reviewing this. Have handled your review comments. |
||
|
|
||
|
|
||
| ### Apache Phoenix | ||
|
|
||
| Phoenix supports `thick` and `thin` connection types: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,7 +26,6 @@ | |
| import java.util.HashMap; | ||
| import java.util.HashSet; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Properties; | ||
| import java.util.Set; | ||
|
|
||
|
|
@@ -179,10 +178,6 @@ public void open() { | |
| } | ||
| logger.debug("JDBC PropretiesMap: {}", basePropretiesMap); | ||
|
|
||
| if (!isEmpty(property.getProperty("zeppelin.jdbc.auth.type"))) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is also removed?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah ok, doc change?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since it's just a removal of extra call, so no doc change required. |
||
| JDBCSecurityImpl.createSecureConfiguration(property); | ||
| } | ||
|
|
||
| setMaxLineResults(); | ||
| } | ||
|
|
||
|
|
@@ -358,65 +353,70 @@ public Connection getConnection(String propertyKey, InterpreterContext interpret | |
| } else { | ||
| UserGroupInformation.AuthenticationMethod authType = JDBCSecurityImpl.getAuthtype(property); | ||
|
|
||
| final String connectionUrl = appendProxyUserToURL(url, user, propertyKey); | ||
|
|
||
| JDBCSecurityImpl.createSecureConfiguration(property, authType); | ||
| switch (authType) { | ||
| case KERBEROS: | ||
| if (user == null || "false".equalsIgnoreCase( | ||
| property.getProperty("zeppelin.jdbc.auth.kerberos.proxy.enable"))) { | ||
| connection = getConnectionFromPool(url, user, propertyKey, properties); | ||
| if (url.trim().startsWith("jdbc:hive")) { | ||
| connection = getConnectionFromPool(connectionUrl, user, propertyKey, properties); | ||
| } else { | ||
| if (url.trim().startsWith("jdbc:hive")) { | ||
| StringBuilder connectionUrl = new StringBuilder(url); | ||
| Integer lastIndexOfUrl = connectionUrl.indexOf("?"); | ||
| if (lastIndexOfUrl == -1) { | ||
| lastIndexOfUrl = connectionUrl.length(); | ||
| } | ||
| boolean hasProxyUser = property.containsKey("hive.proxy.user"); | ||
| if (!hasProxyUser || !property.getProperty("hive.proxy.user").equals("false")){ | ||
| logger.debug("Using hive proxy user"); | ||
| connectionUrl.insert(lastIndexOfUrl, ";hive.server2.proxy.user=" + user + ";"); | ||
| } | ||
| connection = getConnectionFromPool(connectionUrl.toString(), | ||
| user, propertyKey, properties); | ||
| } else { | ||
| UserGroupInformation ugi = null; | ||
| try { | ||
| ugi = UserGroupInformation.createProxyUser( | ||
| user, UserGroupInformation.getCurrentUser()); | ||
| } catch (Exception e) { | ||
| logger.error("Error in getCurrentUser", e); | ||
| StringBuilder stringBuilder = new StringBuilder(); | ||
| stringBuilder.append(e.getMessage()).append("\n"); | ||
| stringBuilder.append(e.getCause()); | ||
| throw new InterpreterException(stringBuilder.toString()); | ||
| } | ||
|
|
||
| final String poolKey = propertyKey; | ||
| try { | ||
| connection = ugi.doAs(new PrivilegedExceptionAction<Connection>() { | ||
| @Override | ||
| public Connection run() throws Exception { | ||
| return getConnectionFromPool(url, user, poolKey, properties); | ||
| } | ||
| }); | ||
| } catch (Exception e) { | ||
| logger.error("Error in doAs", e); | ||
| StringBuilder stringBuilder = new StringBuilder(); | ||
| stringBuilder.append(e.getMessage()).append("\n"); | ||
| stringBuilder.append(e.getCause()); | ||
| throw new InterpreterException(stringBuilder.toString()); | ||
| } | ||
| UserGroupInformation ugi = null; | ||
| try { | ||
| ugi = UserGroupInformation.createProxyUser( | ||
| user, UserGroupInformation.getCurrentUser()); | ||
| } catch (Exception e) { | ||
| logger.error("Error in getCurrentUser", e); | ||
| StringBuilder stringBuilder = new StringBuilder(); | ||
| stringBuilder.append(e.getMessage()).append("\n"); | ||
| stringBuilder.append(e.getCause()); | ||
| throw new InterpreterException(stringBuilder.toString()); | ||
| } | ||
|
|
||
| final String poolKey = propertyKey; | ||
| try { | ||
| connection = ugi.doAs(new PrivilegedExceptionAction<Connection>() { | ||
| @Override | ||
| public Connection run() throws Exception { | ||
| return getConnectionFromPool(connectionUrl, user, poolKey, properties); | ||
| } | ||
| }); | ||
| } catch (Exception e) { | ||
| logger.error("Error in doAs", e); | ||
| StringBuilder stringBuilder = new StringBuilder(); | ||
| stringBuilder.append(e.getMessage()).append("\n"); | ||
| stringBuilder.append(e.getCause()); | ||
| throw new InterpreterException(stringBuilder.toString()); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not just include e as inner exception like
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure just did it, thank you for the hint. |
||
| } | ||
| } | ||
| break; | ||
|
|
||
| default: | ||
| connection = getConnectionFromPool(url, user, propertyKey, properties); | ||
| connection = getConnectionFromPool(connectionUrl, user, propertyKey, properties); | ||
| } | ||
| } | ||
|
|
||
| return connection; | ||
| } | ||
|
|
||
| private String appendProxyUserToURL(String url, String user, String propertyKey) { | ||
| StringBuilder connectionUrl = new StringBuilder(url); | ||
|
|
||
| if (user != null && !user.equals("anonymous") && | ||
| basePropretiesMap.get(propertyKey).containsKey("proxy.user.property")) { | ||
|
|
||
| Integer lastIndexOfUrl = connectionUrl.indexOf("?"); | ||
| if (lastIndexOfUrl == -1) { | ||
| lastIndexOfUrl = connectionUrl.length(); | ||
| } | ||
| logger.info("Using hive proxy user as :" + user); | ||
| connectionUrl.insert(lastIndexOfUrl, ";" + | ||
| basePropretiesMap.get(propertyKey).getProperty("proxy.user.property") + "=" + user + ";"); | ||
| } | ||
|
|
||
| return connectionUrl.toString(); | ||
| } | ||
|
|
||
| private String getPassword(Properties properties) throws IOException { | ||
| if (isNotEmpty(properties.getProperty(PASSWORD_KEY))) { | ||
| return properties.getProperty(PASSWORD_KEY); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is
hive.proxy.userremoved then? do we need to doc to explain the migration?also you have this line here still with
hive.proxy.user property (set to true by default)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the preference would be to have a way to migrate existing users and config by having it automatically converted, add a log warning etc.
but it's your call in the specific case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I meant in above line was the key is
default.proxy.user.propertywith an example valuehive.server2.proxy.user; fair point, let me tweak this documentation.Yes, adding a log (logger.warn) does make sense, let me do it right away.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was looking at http://zeppelin.apache.org/docs/0.7.1/interpreter/jdbc.html#apache-hive,
hive.proxy.userhasn't made it to the doc section, so I think in this case no need to add migration steps. However, I have addedlogger.warnas well.