Repository: incubator-ranger Updated Branches: refs/heads/master a6b93f0e9 -> acefb0737
RANGER-232 Added support for Jersey 2 Admin-client Signed-off-by: Madhan Neethiraj <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/acefb073 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/acefb073 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/acefb073 Branch: refs/heads/master Commit: acefb0737bc25ad6cf2f23dc0c2fb7002837d84f Parents: a6b93f0 Author: Alok Lal <[email protected]> Authored: Tue Feb 17 10:06:49 2015 -0800 Committer: Madhan Neethiraj <[email protected]> Committed: Mon Feb 23 15:26:55 2015 -0800 ---------------------------------------------------------------------- .../conditionevaluator/RangerIpMatcher.java | 16 +- .../ranger/plugin/service/RangerBasePlugin.java | 19 +- .../ranger/plugin/util/RangerRESTUtils.java | 80 +++++ .../ranger/plugin/util/RangerSslHelper.java | 289 +++++++++++++++++++ .../ranger/plugin/util/ServicePolicies.java | 14 + .../conditionevaluator/RangerIpMatcherTest.java | 27 +- hbase-agent/src/test/resources/log4j.properties | 24 +- .../conf/ranger-knox-security-changes.cfg | 14 +- knox-agent/conf/ranger-knox-security.xml | 2 +- knox-agent/pom.xml | 86 +++--- ...gateway.deploy.ProviderDeploymentContributor | 18 -- .../client/RangerAdminJersey2RESTClient.java | 261 +++++++++++++++++ .../authorization/knox/KnoxRangerPlugin.java | 10 +- ...gateway.deploy.ProviderDeploymentContributor | 18 ++ knox-agent/src/test/resources/log4j.properties | 16 + pom.xml | 11 + 16 files changed, 785 insertions(+), 120 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcher.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcher.java index 37501e9..cb476b5 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcher.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcher.java @@ -44,7 +44,6 @@ public class RangerIpMatcher implements RangerConditionEvaluator { private List<String> _exactIps = new ArrayList<String>(); private List<String> _wildCardIps = new ArrayList<String>(); private boolean _allowAny = false; - public static final String ConditionName = "ip-range"; @Override public void init(final RangerPolicyConditionDef conditionDef, final RangerPolicyItemCondition condition) { @@ -203,17 +202,12 @@ public class RangerIpMatcher implements RangerConditionEvaluator { String ip = null; if (request == null) { - LOG.debug("isMatched: Unexpected: null request. Implicitly matched!"); - } else if (request.getContext() == null) { - LOG.debug("isMatched: Context map of request is null. Ok. Implicitly matched!"); - } else if (CollectionUtils.isEmpty(request.getContext().entrySet())) { - LOG.debug("isMatched: Missing context on request. Ok. Condition isn't applicable. Implicitly matched!"); - } else if (!request.getContext().containsKey(ConditionName)) { - if (LOG.isDebugEnabled()) { - LOG.debug("isMatched: Unexpected: Context did not have data for condition[" + ConditionName + "]. Implicitly matched!"); - } + LOG.debug("isMatched: Unexpected: null request object!"); } else { - ip = (String)request.getContext().get(ConditionName); + ip = request.getClientIPAddress(); + if (ip == null) { + LOG.debug("isMatched: Unexpected: Client ip in request object is null!"); + } } if(LOG.isDebugEnabled()) { http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java index e10c369..feef506 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java @@ -219,11 +219,23 @@ public class RangerBasePlugin { private RangerAdminClient createAdminClient(String propertyPrefix) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAdminRESTClient.createAdminClient(" + propertyPrefix + ")"); + } + RangerAdminClient ret = null; - String policySourceImpl = RangerConfiguration.getInstance().get(propertyPrefix + ".source.impl"); + String propertyName = propertyPrefix + ".policy.source.impl"; + String policySourceImpl = RangerConfiguration.getInstance().get(propertyName); - if(!StringUtils.isEmpty(policySourceImpl)) { + if(StringUtils.isEmpty(policySourceImpl)) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Value for property[%s] was null or empty. Unxpected! Will use policy source of type[%s]", propertyName, RangerAdminRESTClient.class.getName())); + } + } else { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Value for property[%s] was [%s].", propertyName, policySourceImpl)); + } try { @SuppressWarnings("unchecked") Class<RangerAdminClient> adminClass = (Class<RangerAdminClient>)Class.forName(policySourceImpl); @@ -240,6 +252,9 @@ public class RangerBasePlugin { ret.init(propertyPrefix); + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAdminRESTClient.createAdminClient(" + propertyPrefix + "): policySourceImpl=" + policySourceImpl + ", client=" + ret); + } return ret; } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java new file mode 100644 index 0000000..f9b9a3e --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java @@ -0,0 +1,80 @@ +/* + * 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.ranger.plugin.util; + + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; + +/** + * Since this class does not retain any state. It isn't a singleton for testability. + * + */ +public class RangerRESTUtils { + + private static final Log LOG = LogFactory.getLog(RangerRESTUtils.class); + static final String REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED = "/service/plugins/policies/download/"; + static final String REST_URL_SERVICE_GRANT_ACCESS = "/service/plugins/services/grant/"; + static final String REST_URL_SERVICE_REVOKE_ACCESS = "/service/plugins/services/revoke/"; + + public String getPolicyRestUrl(String propertyPrefix) { + String url = RangerConfiguration.getInstance().get(propertyPrefix + ".policy.rest.url"); + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerRESTUtils.getPolicyRestUrl(" + url + ")"); + } + + return url; + } + + public String getSsslConfigFileName(String propertyPrefix) { + String sslConfigFileName = RangerConfiguration.getInstance().get(propertyPrefix + ".policy.rest.ssl.config.file"); + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerRESTUtils.getSsslConfigFileName(" + sslConfigFileName + ")"); + } + + return sslConfigFileName; + } + + public String getUrlForPolicyUpdate(String baseUrl, String serviceName, long lastKnownVersion) { + String url = baseUrl + REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED + serviceName + "/" + lastKnownVersion; + + return url; + } + + public boolean isSsl(String _baseUrl) { + return StringUtils.isEmpty(_baseUrl) ? false : _baseUrl.toLowerCase().startsWith("https"); + } + + public String getUrlForGrantAccess(String baseUrl, String serviceName) { + String url = baseUrl + REST_URL_SERVICE_GRANT_ACCESS + serviceName; + + return url; + } + + public String getUrlForRevokeAccess(String baseUrl, String serviceName) { + String url = baseUrl + REST_URL_SERVICE_REVOKE_ACCESS + serviceName; + + return url; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerSslHelper.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerSslHelper.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerSslHelper.java new file mode 100644 index 0000000..5dfa0be --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerSslHelper.java @@ -0,0 +1,289 @@ +/* + * 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.ranger.plugin.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.ranger.authorization.hadoop.utils.RangerCredentialProvider; +import org.apache.ranger.authorization.utils.StringUtil; + +import com.google.common.base.Objects; + +public class RangerSslHelper { + private static final Log LOG = LogFactory.getLog(RangerSslHelper.class); + + static final String RANGER_POLICYMGR_CLIENT_KEY_FILE = "xasecure.policymgr.clientssl.keystore"; + static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE = "xasecure.policymgr.clientssl.keystore.type"; + static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL = "xasecure.policymgr.clientssl.keystore.credential.file"; + static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL_ALIAS = "sslKeyStore"; + static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE_DEFAULT = "jks"; + + static final String RANGER_POLICYMGR_TRUSTSTORE_FILE = "xasecure.policymgr.clientssl.truststore"; + static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE = "xasecure.policymgr.clientssl.truststore.type"; + static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL = "xasecure.policymgr.clientssl.truststore.credential.file"; + static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL_ALIAS = "sslTrustStore"; + static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE_DEFAULT = "jks"; + + static final String RANGER_SSL_KEYMANAGER_ALGO_TYPE = "SunX509" ; + static final String RANGER_SSL_TRUSTMANAGER_ALGO_TYPE = "SunX509" ; + static final String RANGER_SSL_CONTEXT_ALGO_TYPE = "SSL" ; + + private String mKeyStoreURL = null; + private String mKeyStoreAlias = null; + private String mKeyStoreFile = null; + private String mKeyStoreType = null; + private String mTrustStoreURL = null; + private String mTrustStoreAlias = null; + private String mTrustStoreFile = null; + private String mTrustStoreType = null; + + final static HostnameVerifier _Hv = new HostnameVerifier() { + + @Override + public boolean verify(String urlHostName, SSLSession session) { + return session.getPeerHost().equals(urlHostName); + } + }; + + final String mSslConfigFileName; + + public RangerSslHelper(String sslConfigFileName) { + mSslConfigFileName = sslConfigFileName; + + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerSslHelper(" + mSslConfigFileName + ")"); + } + + } + + public SSLContext createContext() { + readConfig(); + KeyManager[] kmList = getKeyManagers(); + TrustManager[] tmList = getTrustManagers(); + SSLContext sslContext = getSSLContext(kmList, tmList); + return sslContext; + } + + public HostnameVerifier getHostnameVerifier() { + return _Hv; + } + + void readConfig() { + InputStream in = null ; + + try { + Configuration conf = new Configuration() ; + + in = getFileInputStream(mSslConfigFileName) ; + + if (in != null) { + conf.addResource(in); + } + + mKeyStoreURL = conf.get(RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL); + mKeyStoreAlias = RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL_ALIAS; + mKeyStoreType = conf.get(RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE, RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE_DEFAULT); + mKeyStoreFile = conf.get(RANGER_POLICYMGR_CLIENT_KEY_FILE); + + mTrustStoreURL = conf.get(RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL); + mTrustStoreAlias = RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL_ALIAS; + mTrustStoreType = conf.get(RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE, RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE_DEFAULT); + mTrustStoreFile = conf.get(RANGER_POLICYMGR_TRUSTSTORE_FILE); + + if (LOG.isDebugEnabled()) { + LOG.debug(Objects.toStringHelper("RangerSslHelper") + .add("keyStoreAlias", mKeyStoreAlias) + .add("keyStoreFile", mKeyStoreFile) + .add("keyStoreType", mKeyStoreType) + .add("keyStoreURL", mKeyStoreURL) + .add("trustStoreAlias", mTrustStoreAlias) + .add("trustStoreFile", mTrustStoreFile) + .add("trustStoreType", mTrustStoreType) + .add("trustStoreURL", mTrustStoreURL) + .toString()); + } + } + catch(IOException ioe) { + LOG.error("Unable to load SSL Config FileName: [" + mSslConfigFileName + "]", ioe); + } + finally { + close(in, mSslConfigFileName); + } + } + + private KeyManager[] getKeyManagers() { + KeyManager[] kmList = null; + + String keyStoreFilepwd = getCredential(mKeyStoreURL, mKeyStoreAlias); + + if (!StringUtil.isEmpty(mKeyStoreFile) && !StringUtil.isEmpty(keyStoreFilepwd)) { + InputStream in = null ; + + try { + in = getFileInputStream(mKeyStoreFile) ; + + if (in != null) { + KeyStore keyStore = KeyStore.getInstance(mKeyStoreType); + + keyStore.load(in, keyStoreFilepwd.toCharArray()); + + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(RANGER_SSL_KEYMANAGER_ALGO_TYPE); + + keyManagerFactory.init(keyStore, keyStoreFilepwd.toCharArray()); + + kmList = keyManagerFactory.getKeyManagers(); + } else { + LOG.error("Unable to obtain keystore from file [" + mKeyStoreFile + "]"); + } + } catch (KeyStoreException e) { + LOG.error("Unable to obtain from KeyStore", e); + } catch (NoSuchAlgorithmException e) { + LOG.error("SSL algorithm is available in the environment", e); + } catch (CertificateException e) { + LOG.error("Unable to obtain the requested certification ", e); + } catch (FileNotFoundException e) { + LOG.error("Unable to find the necessary SSL Keystore and TrustStore Files", e); + } catch (IOException e) { + LOG.error("Unable to read the necessary SSL Keystore and TrustStore Files", e); + } catch (UnrecoverableKeyException e) { + LOG.error("Unable to recover the key from keystore", e); + } finally { + close(in, mKeyStoreFile); + } + } + + return kmList; + } + + private TrustManager[] getTrustManagers() { + TrustManager[] tmList = null; + + String trustStoreFilepwd = getCredential(mTrustStoreURL, mTrustStoreAlias); + + if (!StringUtil.isEmpty(mTrustStoreFile) && !StringUtil.isEmpty(trustStoreFilepwd)) { + InputStream in = null ; + + try { + in = getFileInputStream(mTrustStoreFile) ; + + if (in != null) { + KeyStore trustStore = KeyStore.getInstance(mTrustStoreType); + + trustStore.load(in, trustStoreFilepwd.toCharArray()); + + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(RANGER_SSL_TRUSTMANAGER_ALGO_TYPE); + + trustManagerFactory.init(trustStore); + + tmList = trustManagerFactory.getTrustManagers(); + } else { + LOG.error("Unable to obtain keystore from file [" + mTrustStoreFile + "]"); + } + } catch (KeyStoreException e) { + LOG.error("Unable to obtain from KeyStore", e); + } catch (NoSuchAlgorithmException e) { + LOG.error("SSL algorithm is available in the environment", e); + } catch (CertificateException e) { + LOG.error("Unable to obtain the requested certification ", e); + } catch (FileNotFoundException e) { + LOG.error("Unable to find the necessary SSL Keystore and TrustStore Files", e); + } catch (IOException e) { + LOG.error("Unable to read the necessary SSL Keystore and TrustStore Files", e); + } finally { + close(in, mTrustStoreFile); + } + } + + return tmList; + } + + private SSLContext getSSLContext(KeyManager[] kmList, TrustManager[] tmList) { + try { + if(kmList != null && tmList != null) { + SSLContext sslContext = SSLContext.getInstance(RANGER_SSL_CONTEXT_ALGO_TYPE); + + sslContext.init(kmList, tmList, new SecureRandom()); + + return sslContext; + } + } catch (NoSuchAlgorithmException e) { + LOG.error("SSL algorithm is available in the environment", e); + } catch (KeyManagementException e) { + LOG.error("Unable to initialize the SSLContext", e); + } + + return null; + } + + private String getCredential(String url, String alias) { + char[] credStr = RangerCredentialProvider.getInstance().getCredentialString(url, alias); + + return credStr == null ? null : new String(credStr); + } + + private InputStream getFileInputStream(String fileName) throws IOException { + InputStream in = null ; + + if(! StringUtil.isEmpty(fileName)) { + File f = new File(fileName) ; + + if (f.exists()) { + in = new FileInputStream(f) ; + } + else { + in = ClassLoader.getSystemResourceAsStream(fileName) ; + } + } + + return in ; + } + + private void close(InputStream str, String filename) { + if (str != null) { + try { + str.close() ; + } catch (IOException excp) { + LOG.error("Error while closing file: [" + filename + "]", excp) ; + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java index 436a91a..015c081 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java @@ -34,6 +34,8 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties; import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.google.common.base.Objects; + @JsonAutoDetect(getterVisibility=Visibility.NONE, setterVisibility=Visibility.NONE, fieldVisibility=Visibility.ANY) @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL ) @JsonIgnoreProperties(ignoreUnknown=true) @@ -122,4 +124,16 @@ public class ServicePolicies implements java.io.Serializable { public void setServiceDef(RangerServiceDef serviceDef) { this.serviceDef = serviceDef; } + + @Override + public String toString() { + return Objects.toStringHelper(this.getClass()) + .add("serviceName", serviceName) + .add("serviceId", serviceId) + .add("policyVersion", policyVersion) + .add("policyUpdateTime", policyUpdateTime) + .add("policies", policies) + .add("serviceDef", serviceDef) + .toString(); + } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcherTest.java ---------------------------------------------------------------------- diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcherTest.java b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcherTest.java index 99443a7..cc69324 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcherTest.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcherTest.java @@ -28,9 +28,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; import org.apache.ranger.plugin.policyengine.RangerAccessRequest; @@ -116,26 +114,11 @@ public class RangerIpMatcherTest { assertNull(matcher.extractIp(null)); RangerAccessRequest request = mock(RangerAccessRequest.class); - when(request.getContext()).thenReturn(null); + when(request.getClientIPAddress()).thenReturn(null); assertNull(matcher.extractIp(request)); - Map<String, Object> context = new HashMap<String, Object>(); - when(request.getContext()).thenReturn(context); - assertNull(matcher.extractIp(request)); - - // context does not contain the condition name we are looking for - context.put("!" + RangerIpMatcher.ConditionName, "value"); - assertNull(matcher.extractIp(request)); - - // value for the condition name itself isnull - context.clear(); - context.put(RangerIpMatcher.ConditionName, null); - assertNull(matcher.extractIp(request)); - - // get back what you put in - context.clear(); - context.put(RangerIpMatcher.ConditionName, "aValue"); - assertEquals("aValue", matcher.extractIp(request)); + when(request.getClientIPAddress()).thenReturn("anIp"); // note ip address is merely a string. It can be any string. + assertEquals("anIp", matcher.extractIp(request)); } @Test @@ -257,10 +240,8 @@ public class RangerIpMatcherTest { } RangerAccessRequest createRequest(String requestIp) { - Map<String, Object> context = new HashMap<String, Object>(); - context.put(RangerIpMatcher.ConditionName, requestIp); RangerAccessRequest request = mock(RangerAccessRequest.class); - when(request.getContext()).thenReturn(context); + when(request.getClientIPAddress()).thenReturn(requestIp); return request; } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/hbase-agent/src/test/resources/log4j.properties ---------------------------------------------------------------------- diff --git a/hbase-agent/src/test/resources/log4j.properties b/hbase-agent/src/test/resources/log4j.properties index a43ef33..12e172b 100644 --- a/hbase-agent/src/test/resources/log4j.properties +++ b/hbase-agent/src/test/resources/log4j.properties @@ -1,5 +1,25 @@ -# Define some default values that can be overridden by system properties -ranger.root.logger=WARN,console +# 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. + +##-- To prevent junits from cluttering the build run by default all test runs send output to null appender +log4j.appender.devnull=org.apache.log4j.varia.NullAppender +log4j.rootLogger=FATAL, devnull + +##-- uncomment the following line during during development/debugging so see debug messages during test run to be emitted to console +# ranger.root.logger=WARN,console + # Define the root logger to the system property "hbase.root.logger". log4j.rootLogger=${ranger.root.logger} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/knox-agent/conf/ranger-knox-security-changes.cfg ---------------------------------------------------------------------- diff --git a/knox-agent/conf/ranger-knox-security-changes.cfg b/knox-agent/conf/ranger-knox-security-changes.cfg index 98e2216..8fb8a7b 100644 --- a/knox-agent/conf/ranger-knox-security-changes.cfg +++ b/knox-agent/conf/ranger-knox-security-changes.cfg @@ -16,11 +16,9 @@ # Change the original policy parameter to work with policy manager based. # # -ranger.plugin.knox.service.name %REPOSITORY_NAME% mod create-if-not-exists - -ranger.plugin.knox.policy.source.impl org.apache.ranger.admin.client.RangerAdminRESTClient mod create-if-not-exists - -ranger.plugin.knox.policy.rest.url %POLICY_MGR_URL% mod create-if-not-exists -ranger.plugin.knox.policy.rest.ssl.config.file /etc/knox/conf/ranger-policymgr-ssl.xml mod create-if-not-exists -ranger.plugin.knox.policy.pollIntervalMs 30000 mod create-if-not-exists -ranger.plugin.knox.policy.cache.dir %POLICY_CACHE_FILE_PATH% mod create-if-not-exists +ranger.plugin.knox.service.name %REPOSITORY_NAME% mod create-if-not-exists +ranger.plugin.knox.policy.source.impl org.apache.ranger.admin.client.RangerAdminJersey2RESTClient mod create-if-not-exists +ranger.plugin.knox.policy.rest.url %POLICY_MGR_URL% mod create-if-not-exists +ranger.plugin.knox.policy.rest.ssl.config.file /etc/knox/conf/ranger-policymgr-ssl.xml mod create-if-not-exists +ranger.plugin.knox.policy.pollIntervalMs 30000 mod create-if-not-exists +ranger.plugin.knox.policy.cache.dir %POLICY_CACHE_FILE_PATH% mod create-if-not-exists http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/knox-agent/conf/ranger-knox-security.xml ---------------------------------------------------------------------- diff --git a/knox-agent/conf/ranger-knox-security.xml b/knox-agent/conf/ranger-knox-security.xml index e7d8490..8e442e9 100644 --- a/knox-agent/conf/ranger-knox-security.xml +++ b/knox-agent/conf/ranger-knox-security.xml @@ -28,7 +28,7 @@ <property> <name>ranger.plugin.knox.policy.source.impl</name> - <value>org.apache.ranger.admin.client.RangerAdminRESTClient</value> + <value>org.apache.ranger.admin.client.RangerAdminJersey2RESTClient</value> <description> Class to retrieve policies </description> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/knox-agent/pom.xml ---------------------------------------------------------------------- diff --git a/knox-agent/pom.xml b/knox-agent/pom.xml index 0fdbfa0..df72032 100644 --- a/knox-agent/pom.xml +++ b/knox-agent/pom.xml @@ -43,73 +43,61 @@ <version>${javax.servlet.version}</version> </dependency> <dependency> - <groupId>org.apache.calcite</groupId> - <artifactId>calcite-core</artifactId> - <version>${calcite.version}</version> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-client</artifactId> </dependency> <dependency> - <groupId>org.apache.calcite</groupId> - <artifactId>calcite-avatica</artifactId> - <version>${calcite.version}</version> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> </dependency> <dependency> - <groupId>org.apache.tez</groupId> - <artifactId>tez-api</artifactId> - <version>${tez.version}</version> - <optional>true</optional> + <groupId>junit</groupId> + <artifactId>junit</artifactId> </dependency> <dependency> - <groupId>org.apache.tez</groupId> - <artifactId>tez-runtime-library</artifactId> - <version>${tez.version}</version> - <optional>true</optional> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> </dependency> <dependency> - <groupId>org.apache.tez</groupId> - <artifactId>tez-runtime-internals</artifactId> - <version>${tez.version}</version> - <optional>true</optional> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-integration</artifactId> </dependency> - <dependency> - <groupId>org.apache.tez</groupId> - <artifactId>tez-mapreduce</artifactId> - <version>${tez.version}</version> - <optional>true</optional> - </dependency> - <dependency> - <groupId>org.apache.hadoop</groupId> - <artifactId>hadoop-common</artifactId> - <version>${hadoop.version}</version> + <!-- TO DEBUG JERSEY2 code: Comment the two jackson depedencies to debug jersey2 code. Their presence prevents jersy2 connections to work. --> + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-mapper-asl</artifactId> + <version>${codehaus.jackson.version}</version> </dependency> <dependency> - <groupId>org.apache.hadoop</groupId> - <artifactId>hadoop-hdfs</artifactId> - <version>${hadoop.version}</version> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-core-asl</artifactId> + <version>${codehaus.jackson.version}</version> </dependency> - <dependency> - <groupId>org.apache.hbase</groupId> - <artifactId>hbase-server</artifactId> - <version>${hbase.version}</version> - </dependency> - <dependency> - <groupId>org.apache.hive</groupId> - <artifactId>hive-common</artifactId> - <version>${hive.version}</version> - </dependency> - <dependency> - <groupId>org.apache.hive</groupId> - <artifactId>hive-service</artifactId> - <version>${hive.version}</version> - </dependency> - <dependency> + <dependency> <groupId>security_plugins.ranger-plugins-common</groupId> <artifactId>ranger-plugins-common</artifactId> <version>${project.version}</version> - </dependency> +<!-- TO DEBUG JERSEY2 code: uncomment this exclusion + <exclusions><exclusion><artifactId>*</artifactId><groupId>*</groupId></exclusion></exclusions> + --> + </dependency> <dependency> <groupId>security_plugins.ranger-plugins-audit</groupId> <artifactId>ranger-plugins-audit</artifactId> <version>${project.version}</version> +<!-- TO DEBUG JERSEY2 code: uncomment this exclusion + <exclusions><exclusion><artifactId>*</artifactId><groupId>*</groupId></exclusion></exclusions> + --> </dependency> - </dependencies> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>${commons.lang.version}</version> + </dependency> + <dependency> + <groupId>commons-collections</groupId> + <artifactId>commons-collections</artifactId> + <version>${commons.collections.version}</version> + </dependency> + </dependencies> </project> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/knox-agent/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor ---------------------------------------------------------------------- diff --git a/knox-agent/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor b/knox-agent/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor deleted file mode 100644 index c0c4576..0000000 --- a/knox-agent/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor +++ /dev/null @@ -1,18 +0,0 @@ -########################################################################## -# 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. -########################################################################## -org.apache.ranger.authorization.knox.deploy.RangerPDPKnoxDeploymentContributor http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java ---------------------------------------------------------------------- diff --git a/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java b/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java new file mode 100644 index 0000000..fa16566 --- /dev/null +++ b/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java @@ -0,0 +1,261 @@ +/* + * 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.ranger.admin.client; + +import java.lang.reflect.Type; +import java.util.Date; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.security.AccessControlException; +import org.apache.ranger.plugin.util.GrantRevokeRequest; +import org.apache.ranger.plugin.util.RangerRESTUtils; +import org.apache.ranger.plugin.util.RangerSslHelper; +import org.apache.ranger.plugin.util.ServicePolicies; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; + +public class RangerAdminJersey2RESTClient implements RangerAdminClient { + + // none of the members are public -- this is only for testability. None of these is meant to be accessible + private static final Log LOG = LogFactory.getLog(RangerAdminJersey2RESTClient.class); + RangerRESTUtils _utils = new RangerRESTUtils(); + + boolean _isSSL = false; + volatile Client _client = null; + SSLContext _sslContext = null; + HostnameVerifier _hv; + String _baseUrl = null; + String _sslConfigFileName = null; + + + @Override + public void init(String configPropertyPrefix) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAdminJersey2RESTClient.init(" + configPropertyPrefix + ")"); + } + + _baseUrl = _utils.getPolicyRestUrl(configPropertyPrefix); + _sslConfigFileName = _utils.getSsslConfigFileName(configPropertyPrefix); + _isSSL = _utils.isSsl(_baseUrl); + + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Base URL[%s], SSL Congig filename[%s]", _baseUrl, _sslConfigFileName)); + } + + _client = getClient(); + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAdminJersey2RESTClient.init(" + configPropertyPrefix + "): " + _client.toString()); + } + } + + @Override + public ServicePolicies getServicePoliciesIfUpdated(String serviceName, + long lastKnownVersion) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAdminJersey2RESTClient.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ")"); + } + + ServicePolicies servicePolicies = null; + String url = _utils.getUrlForPolicyUpdate(_baseUrl, serviceName, lastKnownVersion); + Response response = _client.target(url) + .request(MediaType.APPLICATION_JSON_TYPE) + .get(); + int httpResponseCode = response == null ? -1 : response.getStatus(); + String body = null; + + switch (httpResponseCode) { + case 200: + body = response.readEntity(String.class); + + if (LOG.isDebugEnabled()) { + LOG.debug("Response from 200 server: " + body); + } + + Gson gson = getGson(); + servicePolicies = gson.fromJson(body, ServicePolicies.class); + + if (LOG.isDebugEnabled()) { + LOG.debug("Deserialized response to: " + servicePolicies); + } + break; + case 304: + LOG.debug("Got response: 304. Ok. Returning null"); + break; + case -1: + LOG.warn("Unexpected: Null response from policy server while trying to get policies! Returning null!"); + break; + default: + body = response.readEntity(String.class); + LOG.warn(String.format("Unexpected: Received status[%d] with body[%s] form url[%s]", httpResponseCode, body, url)); + break; + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAdminJersey2RESTClient.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + "): " + servicePolicies); + } + return servicePolicies; + } + + @Override + public void grantAccess(String serviceName, GrantRevokeRequest request) + throws Exception { + + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAdminRESTClient.grantAccess(" + serviceName + ", " + request + ")"); + } + + String url = _utils.getUrlForGrantAccess(_baseUrl, serviceName); + Response response = _client.target(url) + .request(MediaType.APPLICATION_JSON_TYPE) + .get(); + int httpResponseCode = response == null ? -1 : response.getStatus(); + + switch(httpResponseCode) { + case -1: + LOG.warn("Unexpected: Null response from policy server while grating access! Returning null!"); + throw new Exception("unknown error!"); + case 200: + LOG.debug("grantAccess() suceeded: HTTP status=" + httpResponseCode); + break; + case 401: + throw new AccessControlException(); + default: + String body = response.readEntity(String.class); + String message = String.format("Unexpected: Received status[%d] with body[%s] form url[%s]", httpResponseCode, body, url); + LOG.warn(message); + throw new Exception("HTTP status: " + httpResponseCode); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAdminRESTClient.grantAccess(" + serviceName + ", " + request + ")"); + } + } + + @Override + public void revokeAccess(String serviceName, GrantRevokeRequest request) + throws Exception { + + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAdminRESTClient.grantAccess(" + serviceName + ", " + request + ")"); + } + + String url = _utils.getUrlForRevokeAccess(_baseUrl, serviceName); + Response response = _client.target(url) + .request(MediaType.APPLICATION_JSON_TYPE) + .get(); + int httpResponseCode = response == null ? -1 : response.getStatus(); + + switch(httpResponseCode) { + case -1: + LOG.warn("Unexpected: Null response from policy server while grating access! Returning null!"); + throw new Exception("unknown error!"); + case 200: + LOG.debug("grantAccess() suceeded: HTTP status=" + httpResponseCode); + break; + case 401: + throw new AccessControlException(); + default: + String body = response.readEntity(String.class); + String message = String.format("Unexpected: Received status[%d] with body[%s] form url[%s]", httpResponseCode, body, url); + LOG.warn(message); + throw new Exception("HTTP status: " + httpResponseCode); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAdminRESTClient.grantAccess(" + serviceName + ", " + request + ")"); + } + } + + // We get date from the policy manager as unix long! This deserializer exists to deal with it. Remove this class once we start send date/time per RFC 3339 + public static class GsonUnixDateDeserializer implements JsonDeserializer<Date> { + + @Override + public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + return new Date(json.getAsJsonPrimitive().getAsLong()); + } + + } + + // package level methods left so (and not private only for testability!) Not intended for use outside this class!! + Gson getGson() { + return new GsonBuilder() + .setPrettyPrinting() + // We get date from the policy manager as unix long! This deserializer exists to deal with it. Remove this class once we start send date/time per RFC 3339 + .registerTypeAdapter(Date.class, new GsonUnixDateDeserializer()) + .create(); + } + + Client getClient() { + Client result = _client; + if(result == null) { + synchronized(this) { + result = _client; + if(result == null) { + _client = result = buildClient(); + } + } + } + + return result; + } + + Client buildClient() { + + if (_isSSL) { + if (_sslContext == null) { + RangerSslHelper sslHelper = new RangerSslHelper(_sslConfigFileName); + _sslContext = sslHelper.createContext(); + } + if (_hv == null) { + _hv = new HostnameVerifier() { + public boolean verify(String urlHostName, SSLSession session) { + return session.getPeerHost().equals(urlHostName); + } + }; + } + _client = ClientBuilder.newBuilder() + .sslContext(_sslContext) + .hostnameVerifier(_hv) + .build(); + } + + if(_client == null) { + _client = ClientBuilder.newClient(); + } + + return _client; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/knox-agent/src/main/java/org/apache/ranger/authorization/knox/KnoxRangerPlugin.java ---------------------------------------------------------------------- diff --git a/knox-agent/src/main/java/org/apache/ranger/authorization/knox/KnoxRangerPlugin.java b/knox-agent/src/main/java/org/apache/ranger/authorization/knox/KnoxRangerPlugin.java index d5095de..354d2f0 100644 --- a/knox-agent/src/main/java/org/apache/ranger/authorization/knox/KnoxRangerPlugin.java +++ b/knox-agent/src/main/java/org/apache/ranger/authorization/knox/KnoxRangerPlugin.java @@ -19,14 +19,12 @@ package org.apache.ranger.authorization.knox; -import java.util.Collections; -import java.util.Map; import java.util.Set; import org.apache.ranger.authorization.knox.KnoxRangerPlugin.KnoxConstants.AccessType; import org.apache.ranger.authorization.knox.KnoxRangerPlugin.KnoxConstants.PluginConfiguration; import org.apache.ranger.authorization.knox.KnoxRangerPlugin.KnoxConstants.ResourceName; -import org.apache.ranger.plugin.conditionevaluator.RangerIpMatcher; +import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler; import org.apache.ranger.plugin.policyengine.RangerAccessRequest; import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl; import org.apache.ranger.plugin.policyengine.RangerResourceImpl; @@ -43,7 +41,10 @@ public class KnoxRangerPlugin extends RangerBasePlugin { @Override synchronized public void init() { if (!initialized) { + // mandatory call to base plugin super.init(); + // One time call to register the audit hander with the policy engine. + super.setDefaultAuditHandler(new RangerDefaultAuditHandler()); initialized = true; } } @@ -94,9 +95,6 @@ public class KnoxRangerPlugin extends RangerBasePlugin { request.setUser(_user); request.setUserGroups(_groups); request.setResource(resource); - // build condition for IP address - Map<String, Object> conditions = Collections.singletonMap(RangerIpMatcher.ConditionName, (Object)_clientIp); - request.setContext(conditions); return request; } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/knox-agent/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor ---------------------------------------------------------------------- diff --git a/knox-agent/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor b/knox-agent/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor new file mode 100644 index 0000000..c0c4576 --- /dev/null +++ b/knox-agent/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor @@ -0,0 +1,18 @@ +########################################################################## +# 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. +########################################################################## +org.apache.ranger.authorization.knox.deploy.RangerPDPKnoxDeploymentContributor http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/knox-agent/src/test/resources/log4j.properties ---------------------------------------------------------------------- diff --git a/knox-agent/src/test/resources/log4j.properties b/knox-agent/src/test/resources/log4j.properties new file mode 100644 index 0000000..16c7516 --- /dev/null +++ b/knox-agent/src/test/resources/log4j.properties @@ -0,0 +1,16 @@ +# Define some default values that can be overridden by system properties +ranger.root.logger=DEBUG,console +# Define the root logger to the system property "hbase.root.logger". +log4j.rootLogger=${ranger.root.logger} + +# Logging Threshold +log4j.threshold=ALL + +# +# console +# Add "console" to rootlogger above if you want to use this +# +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.target=System.err +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/acefb073/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 072e7a9..0c39eb8 100644 --- a/pom.xml +++ b/pom.xml @@ -137,6 +137,7 @@ <javax.servlet.version>3.1.0</javax.servlet.version> <jericho.html.version>3.3</jericho.html.version> <jersey-bundle.version>1.17.1</jersey-bundle.version> + <jersey-client.version>2.6</jersey-client.version> <junit.version>4.11</junit.version> <mockito.version>1.8.4</mockito.version> <hamcrest-version>1.3</hamcrest-version> @@ -274,6 +275,16 @@ <version>${hamcrest-version}</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-client</artifactId> + <version>${jersey-client.version}</version> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>${gson.version}</version> + </dependency> </dependencies> </dependencyManagement> <build>
