Repository: incubator-ranger Updated Branches: refs/heads/stack fbe800a16 -> 87fffe02e
RANGER-203: 1) URL for few methods in ServiceREST updated to be consistent 2) plugin-common project updated to read configuration using existing RangerConfiguration class. 3) Added ServiceRESTStore, to access service store via REST interface. Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/87fffe02 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/87fffe02 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/87fffe02 Branch: refs/heads/stack Commit: 87fffe02e0e12b58d1e731b6f0b46c4375f1d281 Parents: fbe800a Author: Madhan Neethiraj <mad...@apache.org> Authored: Thu Jan 15 23:31:55 2015 -0800 Committer: Madhan Neethiraj <mad...@apache.org> Committed: Thu Jan 15 23:31:55 2015 -0800 ---------------------------------------------------------------------- plugin-common/pom.xml | 5 + .../ranger/plugin/service/RangerBasePlugin.java | 19 +- .../ranger/plugin/store/ServiceStore.java | 6 +- .../plugin/store/ServiceStoreFactory.java | 14 +- .../ranger/plugin/store/file/BaseFileStore.java | 3 +- .../plugin/store/file/ServiceFileStore.java | 109 ++-- .../plugin/store/rest/ServiceRESTStore.java | 565 +++++++++++++++++++ .../ranger/plugin/util/PolicyRefresher.java | 3 +- .../ranger/plugin/util/RangerRESTClient.java | 376 ++++++++++++ .../ranger/plugin/store/TestServiceStore.java | 8 +- .../org/apache/ranger/rest/ServiceREST.java | 236 +++++--- .../webapp/scripts/controllers/Controller.js | 2 +- 12 files changed, 1188 insertions(+), 158 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/87fffe02/plugin-common/pom.xml ---------------------------------------------------------------------- diff --git a/plugin-common/pom.xml b/plugin-common/pom.xml index 3e1d0bc..0aa4583 100644 --- a/plugin-common/pom.xml +++ b/plugin-common/pom.xml @@ -60,5 +60,10 @@ <artifactId>ranger-plugins-audit</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>security_plugins.ranger-plugins-common</groupId> + <artifactId>ranger-plugins-common</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> </project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/87fffe02/plugin-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/plugin-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java index d27733b..6deea8f 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java @@ -19,6 +19,8 @@ package org.apache.ranger.plugin.service; +import org.apache.commons.lang.StringUtils; +import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; import org.apache.ranger.plugin.policyengine.RangerPolicyEngine; import org.apache.ranger.plugin.store.ServiceStore; import org.apache.ranger.plugin.store.ServiceStoreFactory; @@ -34,7 +36,22 @@ public abstract class RangerBasePlugin { if(!initDone) { synchronized(this) { if(! initDone) { - String serviceName = System.getProperty("ranger.plugin.service.name", "hbasedev"); // TODO: read from configuration + String serviceName = null; + + // get the serviceName from download URL: http://ranger-admin-host:port/service/assets/policyList/serviceName + String policyDownloadUrl = RangerConfiguration.getInstance().get("xasecure.hdfs.policymgr.url"); + + if(! StringUtils.isEmpty(policyDownloadUrl)) { + int idx = policyDownloadUrl.lastIndexOf('/'); + + if(idx != -1) { + serviceName = policyDownloadUrl.substring(idx) + 1; + } + } + + if(StringUtils.isEmpty(serviceName)) { + serviceName = RangerConfiguration.getInstance().get("ranger.plugin.service.name", "hbasedev"); + } ServiceStore serviceStore = ServiceStoreFactory.instance().getServiceStore(); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/87fffe02/plugin-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java b/plugin-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java index f986def..8d48305 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java @@ -61,13 +61,11 @@ public interface ServiceStore { RangerPolicy getPolicy(Long id) throws Exception; - RangerPolicy getPolicyByName(String serviceName, String policyName) throws Exception; - List<RangerPolicy> getAllPolicies() throws Exception; - List<RangerPolicy> getServicePolicies(String serviceName) throws Exception; - List<RangerPolicy> getServicePolicies(Long serviceId) throws Exception; + List<RangerPolicy> getServicePolicies(String serviceName) throws Exception; + ServicePolicies getServicePoliciesIfUpdated(String serviceName, Long lastKnownVersion) throws Exception; } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/87fffe02/plugin-common/src/main/java/org/apache/ranger/plugin/store/ServiceStoreFactory.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/store/ServiceStoreFactory.java b/plugin-common/src/main/java/org/apache/ranger/plugin/store/ServiceStoreFactory.java index 7be2311..a2af931 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/store/ServiceStoreFactory.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/store/ServiceStoreFactory.java @@ -22,6 +22,8 @@ package org.apache.ranger.plugin.store; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ranger.plugin.store.file.ServiceFileStore; +import org.apache.ranger.plugin.store.rest.ServiceRESTStore; +import org.apache.ranger.plugin.util.RangerRESTClient; public class ServiceStoreFactory { @@ -60,8 +62,18 @@ public class ServiceStoreFactory { if(LOG.isDebugEnabled()) { LOG.debug("==> ServiceStoreFactory.init()"); } + + boolean useFileStore = true; + + if(useFileStore) { + serviceStore = new ServiceFileStore(); // TODO: configurable store implementation + } else { + RangerRESTClient restClient = new RangerRESTClient("http://172.18.145.30:6080", ""); + restClient.setBasicAuthInfo("admin", "admin"); + + serviceStore = new ServiceRESTStore(restClient); + } - serviceStore = new ServiceFileStore(); // TODO: configurable store implementation if(LOG.isDebugEnabled()) { LOG.debug("<== ServiceStoreFactory.init()"); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/87fffe02/plugin-common/src/main/java/org/apache/ranger/plugin/store/file/BaseFileStore.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/store/file/BaseFileStore.java b/plugin-common/src/main/java/org/apache/ranger/plugin/store/file/BaseFileStore.java index 8717495..ea22745 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/store/file/BaseFileStore.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/store/file/BaseFileStore.java @@ -37,6 +37,7 @@ import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.PathFilter; +import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; import org.apache.ranger.plugin.model.RangerBaseModelObject; import org.apache.ranger.plugin.model.RangerPolicy; import org.apache.ranger.plugin.model.RangerService; @@ -58,7 +59,7 @@ public class BaseFileStore { protected void init() { - dataDir = System.getProperty("ranger.policystore.file.dir", "/etc/ranger/data"); // TODO: read from configuration + dataDir = RangerConfiguration.getInstance().get("ranger.policystore.file.dir", "/etc/ranger/data"); try { gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z").setPrettyPrinting().create(); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/87fffe02/plugin-common/src/main/java/org/apache/ranger/plugin/store/file/ServiceFileStore.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/store/file/ServiceFileStore.java b/plugin-common/src/main/java/org/apache/ranger/plugin/store/file/ServiceFileStore.java index feac5d4..f5207ef 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/store/file/ServiceFileStore.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/store/file/ServiceFileStore.java @@ -493,7 +493,7 @@ public class ServiceFileStore extends BaseFileStore implements ServiceStore { throw new Exception("service does not exist - name=" + policy.getService()); } - RangerPolicy existing = getPolicyByName(policy.getService(), policy.getName()); + RangerPolicy existing = findPolicyByName(policy.getService(), policy.getName()); if(existing != null) { throw new Exception("policy already exists: ServiceName=" + policy.getService() + "; PolicyName=" + policy.getName() + ". ID=" + existing.getId()); @@ -547,7 +547,7 @@ public class ServiceFileStore extends BaseFileStore implements ServiceStore { boolean renamed = !StringUtils.equalsIgnoreCase(policy.getName(), existing.getName()); if(renamed) { - RangerPolicy newNamePolicy = getPolicyByName(service.getName(), policy.getName()); + RangerPolicy newNamePolicy = findPolicyByName(service.getName(), policy.getName()); if(newNamePolicy != null) { throw new Exception("another policy already exists with name '" + policy.getName() + "'. ID=" + newNamePolicy.getId()); @@ -646,61 +646,44 @@ public class ServiceFileStore extends BaseFileStore implements ServiceStore { } @Override - public RangerPolicy getPolicyByName(String serviceName, String policyName) throws Exception { + public List<RangerPolicy> getAllPolicies() throws Exception { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceFileStore.getPolicyByName(" + serviceName + ", " + policyName + ")"); - } - - RangerService service = getServiceByName(serviceName); - - if(service == null) { - throw new Exception("service does not exist - name='" + serviceName); + LOG.debug("==> ServiceFileStore.getAllPolicies()"); } - RangerPolicy ret = null; + List<RangerPolicy> ret = null; try { - List<RangerPolicy> policies = getAllPolicies(); - - if(policies != null) { - for(RangerPolicy policy : policies) { - if(StringUtils.equals(policy.getService(), service.getName()) && - StringUtils.equals(policy.getName(), policyName)) { - ret = policy; + ret = loadFromDir(new Path(getDataDir()), FILE_PREFIX_POLICY, RangerPolicy.class); - break; - } - } - } + nextPolicyId = getMaxId(ret) + 1; } catch(Exception excp) { - LOG.error("ServiceFileStore.getPolicyByName(" + serviceName + ", " + policyName + "): failed to read policies", excp); + LOG.error("ServiceFileStore.getAllPolicies(): failed to read policies", excp); } if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceFileStore.getPolicyByName(" + serviceName + ", " + policyName + "): " + ret); + LOG.debug("<== ServiceFileStore.getAllPolicies(): count=" + (ret == null ? 0 : ret.size())); } return ret; } @Override - public List<RangerPolicy> getAllPolicies() throws Exception { + public List<RangerPolicy> getServicePolicies(Long serviceId) throws Exception { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceFileStore.getAllPolicies()"); + LOG.debug("==> ServiceFileStore.getPolicies(" + serviceId + ")"); } - List<RangerPolicy> ret = null; - - try { - ret = loadFromDir(new Path(getDataDir()), FILE_PREFIX_POLICY, RangerPolicy.class); + RangerService service = getService(serviceId); - nextPolicyId = getMaxId(ret) + 1; - } catch(Exception excp) { - LOG.error("ServiceFileStore.getAllPolicies(): failed to read policies", excp); + if(service == null) { + throw new Exception("service does not exist - id='" + serviceId); } + List<RangerPolicy> ret = getServicePolicies(service.getName()); + if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceFileStore.getAllPolicies(): count=" + (ret == null ? 0 : ret.size())); + LOG.debug("<== ServiceFileStore.getPolicies(" + serviceId + "): " + ((ret == null) ? 0 : ret.size())); } return ret; @@ -748,27 +731,6 @@ public class ServiceFileStore extends BaseFileStore implements ServiceStore { } @Override - public List<RangerPolicy> getServicePolicies(Long serviceId) throws Exception { - if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceFileStore.getPolicies(" + serviceId + ")"); - } - - RangerService service = getService(serviceId); - - if(service == null) { - throw new Exception("service does not exist - id='" + serviceId); - } - - List<RangerPolicy> ret = getServicePolicies(service.getName()); - - if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceFileStore.getPolicies(" + serviceId + "): " + ((ret == null) ? 0 : ret.size())); - } - - return ret; - } - - @Override public ServicePolicies getServicePoliciesIfUpdated(String serviceName, Long lastKnownVersion) throws Exception { if(LOG.isDebugEnabled()) { LOG.debug("==> ServiceFileStore.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ")"); @@ -921,6 +883,43 @@ public class ServiceFileStore extends BaseFileStore implements ServiceStore { return ret; } + private RangerPolicy findPolicyByName(String serviceName, String policyName) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.findPolicyByName(" + serviceName + ", " + policyName + ")"); + } + + RangerService service = getServiceByName(serviceName); + + if(service == null) { + throw new Exception("service does not exist - name='" + serviceName); + } + + RangerPolicy ret = null; + + try { + List<RangerPolicy> policies = getAllPolicies(); + + if(policies != null) { + for(RangerPolicy policy : policies) { + if(StringUtils.equals(policy.getService(), service.getName()) && + StringUtils.equals(policy.getName(), policyName)) { + ret = policy; + + break; + } + } + } + } catch(Exception excp) { + LOG.error("ServiceFileStore.findPolicyByName(" + serviceName + ", " + policyName + "): failed to read policies", excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.findPolicyByName(" + serviceName + ", " + policyName + "): " + ret); + } + + return ret; + } + private boolean isLegacyServiceDef(RangerServiceDef sd) { return sd == null ? false : (isLegacyServiceDef(sd.getName()) || isLegacyServiceDef(sd.getId())); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/87fffe02/plugin-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java b/plugin-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java new file mode 100644 index 0000000..cdb2fa5 --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java @@ -0,0 +1,565 @@ +/* + * 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.store.rest; + +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.admin.client.datatype.RESTResponse; +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerService; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.store.ServiceStore; +import org.apache.ranger.plugin.util.RangerRESTClient; +import org.apache.ranger.plugin.util.ServicePolicies; + +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.GenericType; +import com.sun.jersey.api.client.WebResource; + + +public class ServiceRESTStore implements ServiceStore { + private static final Log LOG = LogFactory.getLog(ServiceRESTStore.class); + + + public final String REST_URL_SERVICEDEF_CREATE = "/service/plugins/definitions"; + public final String REST_URL_SERVICEDEF_UPDATE = "/service/plugins/definitions/"; + public final String REST_URL_SERVICEDEF_DELETE = "/service/plugins/definitions/"; + public final String REST_URL_SERVICEDEF_GET = "/service/plugins/definitions/"; + public final String REST_URL_SERVICEDEF_GET_BY_NAME = "/service/plugins/definitions/name/"; + public final String REST_URL_SERVICEDEF_GET_ALL = "/service/plugins/definitions"; + + public final String REST_URL_SERVICE_CREATE = "/service/plugins/services"; + public final String REST_URL_SERVICE_UPDATE = "/service/plugins/services/"; + public final String REST_URL_SERVICE_DELETE = "/service/plugins/services/"; + public final String REST_URL_SERVICE_GET = "/service/plugins/services/"; + public final String REST_URL_SERVICE_GET_BY_NAME = "/service/plugins/services/name/"; + public final String REST_URL_SERVICE_GET_ALL = "/service/plugins/services"; + + public final String REST_URL_POLICY_CREATE = "/service/plugins/policies"; + public final String REST_URL_POLICY_UPDATE = "/service/plugins/policies/"; + public final String REST_URL_POLICY_DELETE = "/service/plugins/policies/"; + public final String REST_URL_POLICY_GET = "/service/plugins/policies/"; + public final String REST_URL_POLICY_GET_BY_NAME = "/service/plugins/policies/name/"; + public final String REST_URL_POLICY_GET_ALL = "/service/plugins/policies"; + public final String REST_URL_POLICY_GET_FOR_SERVICE = "/service/plugins/policies/service/"; + public final String REST_URL_POLICY_GET_FOR_SERVICE_BY_NAME = "/service/plugins/policies/service/name/"; + + public static final String REST_MIME_TYPE_JSON = "application/json" ; + + private RangerRESTClient restClient; + + public ServiceRESTStore(RangerRESTClient restClient) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.ServiceRESTStore(" + restClient + ")"); + } + + this.restClient = restClient; + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.ServiceRESTStore(" + restClient + ")"); + } + } + + + @Override + public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.createServiceDef(" + serviceDef + ")"); + } + + RangerServiceDef ret = null; + + WebResource webResource = restClient.getResource(REST_URL_SERVICEDEF_CREATE); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).post(ClientResponse.class, restClient.toJson(serviceDef)); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerServiceDef.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.createServiceDef(" + serviceDef + "): " + ret); + } + + return ret; + } + + @Override + public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.updateServiceDef(" + serviceDef + ")"); + } + + RangerServiceDef ret = null; + + WebResource webResource = restClient.getResource(REST_URL_SERVICEDEF_UPDATE + serviceDef.getId()); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).put(ClientResponse.class, restClient.toJson(serviceDef)); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerServiceDef.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.updateServiceDef(" + serviceDef + "): " + ret); + } + + return ret; + } + + @Override + public void deleteServiceDef(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.deleteServiceDef(" + id + ")"); + } + + WebResource webResource = restClient.getResource(REST_URL_SERVICEDEF_DELETE + id); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).delete(ClientResponse.class); + + if(response == null || (response.getStatus() != 200 && response.getStatus() != 204)) { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.deleteServiceDef(" + id + ")"); + } + } + + @Override + public RangerServiceDef getServiceDef(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getServiceDef(" + id + ")"); + } + + RangerServiceDef ret = null; + + WebResource webResource = restClient.getResource(REST_URL_SERVICEDEF_GET + id); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerServiceDef.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.getServiceDef(" + id + "): " + ret); + } + + return ret; + } + + @Override + public RangerServiceDef getServiceDefByName(String name) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getServiceDefByName(" + name + ")"); + } + + RangerServiceDef ret = null; + + WebResource webResource = restClient.getResource(REST_URL_SERVICEDEF_GET_BY_NAME + name); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerServiceDef.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.getServiceDefByName(" + name + "): " + ret); + } + + return ret; + } + + @Override + public List<RangerServiceDef> getAllServiceDefs() throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getAllServiceDefs()"); + } + + List<RangerServiceDef> ret = null; + + WebResource webResource = restClient.getResource(REST_URL_SERVICEDEF_GET_ALL); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(new GenericType<List<RangerServiceDef>>() { }); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.getAllServiceDefs(): " + ret); + } + + return ret; + } + + @Override + public RangerService createService(RangerService service) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.createService(" + service + ")"); + } + + RangerService ret = null; + + WebResource webResource = restClient.getResource(REST_URL_SERVICE_CREATE); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).post(ClientResponse.class, restClient.toJson(service)); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerService.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.createService(" + service + "): " + ret); + } + + return ret; + } + + @Override + public RangerService updateService(RangerService service) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.updateService(" + service + ")"); + } + + RangerService ret = null; + + WebResource webResource = restClient.getResource(REST_URL_SERVICE_UPDATE + service.getId()); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).put(ClientResponse.class, restClient.toJson(service)); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerService.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.updateService(" + service + "): " + ret); + } + + return ret; + } + + @Override + public void deleteService(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.deleteService(" + id + ")"); + } + + WebResource webResource = restClient.getResource(REST_URL_SERVICE_DELETE + id); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).delete(ClientResponse.class); + + if(response == null || (response.getStatus() != 200 && response.getStatus() != 204)) { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.deleteService(" + id + ")"); + } + } + + @Override + public RangerService getService(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getService(" + id + ")"); + } + + RangerService ret = null; + + WebResource webResource = restClient.getResource(REST_URL_SERVICE_GET + id); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerService.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.getService(" + id + "): " + ret); + } + + return ret; + } + + @Override + public RangerService getServiceByName(String name) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getServiceByName(" + name + ")"); + } + + RangerService ret = null; + + WebResource webResource = restClient.getResource(REST_URL_SERVICE_GET_BY_NAME + name); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerService.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.getServiceByName(" + name + "): " + ret); + } + + return ret; + } + + @Override + public List<RangerService> getAllServices() throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getAllServices()"); + } + + List<RangerService> ret = null; + + WebResource webResource = restClient.getResource(REST_URL_SERVICE_GET_ALL); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(new GenericType<List<RangerService>>() { }); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.getAllServices(): " + ret); + } + + return ret; + } + + @Override + public RangerPolicy createPolicy(RangerPolicy policy) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.createPolicy(" + policy + ")"); + } + + RangerPolicy ret = null; + + WebResource webResource = restClient.getResource(REST_URL_POLICY_CREATE); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).post(ClientResponse.class, restClient.toJson(policy)); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerPolicy.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.createPolicy(" + policy + "): " + ret); + } + + return ret; + } + + @Override + public RangerPolicy updatePolicy(RangerPolicy policy) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.updatePolicy(" + policy + ")"); + } + + RangerPolicy ret = null; + + WebResource webResource = restClient.getResource(REST_URL_POLICY_UPDATE + policy.getId()); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).put(ClientResponse.class, restClient.toJson(policy)); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerPolicy.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.updatePolicy(" + policy + "): " + ret); + } + + return ret; + } + + @Override + public void deletePolicy(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.deletePolicy(" + id + ")"); + } + + WebResource webResource = restClient.getResource(REST_URL_POLICY_DELETE + id); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).delete(ClientResponse.class); + + if(response == null || (response.getStatus() != 200 && response.getStatus() != 204)) { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.deletePolicy(" + id + ")"); + } + } + + @Override + public RangerPolicy getPolicy(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getPolicy(" + id + ")"); + } + + RangerPolicy ret = null; + + WebResource webResource = restClient.getResource(REST_URL_POLICY_GET + id); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerPolicy.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.getPolicy(" + id + "): " + ret); + } + + return ret; + } + + @Override + public List<RangerPolicy> getAllPolicies() throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getAllPolicies()"); + } + + List<RangerPolicy> ret = null; + + WebResource webResource = restClient.getResource(REST_URL_POLICY_GET_ALL); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(new GenericType<List<RangerPolicy>>() { }); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.getAllPolicies(): " + ret); + } + + return ret; + } + + @Override + public List<RangerPolicy> getServicePolicies(Long serviceId) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getServicePolicies(" + serviceId + ")"); + } + + List<RangerPolicy> ret = null; + + WebResource webResource = restClient.getResource(REST_URL_POLICY_GET_FOR_SERVICE + serviceId); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(new GenericType<List<RangerPolicy>>() { }); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.getServicePolicies(" + serviceId + "): " + ret); + } + + return ret; + } + + @Override + public List<RangerPolicy> getServicePolicies(String serviceName) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getServicePolicies(" + serviceName + ")"); + } + + List<RangerPolicy> ret = null; + + WebResource webResource = restClient.getResource(REST_URL_POLICY_GET_FOR_SERVICE_BY_NAME + serviceName); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(new GenericType<List<RangerPolicy>>() { }); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.getServicePolicies(" + serviceName + "): " + ret); + } + + return ret; + } + + @Override + public ServicePolicies getServicePoliciesIfUpdated(String serviceName, + Long lastKnownVersion) throws Exception { + // TODO Auto-generated method stub + return null; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/87fffe02/plugin-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java index 12d616c..146d151 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java @@ -21,6 +21,7 @@ package org.apache.ranger.plugin.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; import org.apache.ranger.plugin.policyengine.RangerPolicyEngine; import org.apache.ranger.plugin.store.ServiceStore; @@ -46,7 +47,7 @@ public class PolicyRefresher extends Thread { this.serviceName = serviceName; this.serviceStore = serviceStore; - this.pollingIntervalMilliSeconds = 30 * 1000; // TODO: read from configuration + this.pollingIntervalMilliSeconds = RangerConfiguration.getInstance().getLong("xasecure.hdfs.policymgr.url.reloadIntervalInMillis", 30 * 1000); if(LOG.isDebugEnabled()) { LOG.debug("<== PolicyRefresher.PolicyRefresher(serviceName=" + serviceName + ")"); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/87fffe02/plugin-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java b/plugin-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java new file mode 100644 index 0000000..cfff4b7 --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java @@ -0,0 +1,376 @@ +/* + * 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.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; +import org.apache.ranger.authorization.hadoop.utils.RangerCredentialProvider; +import org.apache.ranger.authorization.utils.StringUtil; +import org.codehaus.jackson.jaxrs.JacksonJsonProvider; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.config.ClientConfig; +import com.sun.jersey.api.client.config.DefaultClientConfig; +import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; +import com.sun.jersey.client.urlconnection.HTTPSProperties; + + +public class RangerRESTClient { + private static final Log LOG = LogFactory.getLog(RangerRESTClient.class); + + public static final String RANGER_PROP_POLICYMGR_URL = "xasecure.policymgr.url"; + public static final String RANGER_PROP_POLICYMGR_SSLCONFIG_FILENAME = "xasecure.policymgr.sslconfig.filename"; + + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE = "xasecure.policymgr.clientssl.keystore"; + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_PASSWORD = "xasecure.policymgr.clientssl.keystore.password"; + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE = "xasecure.policymgr.clientssl.keystore.type"; + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL = "xasecure.policymgr.clientssl.keystore.credential.file"; + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL_ALIAS = "sslKeyStore"; + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE_DEFAULT = "jks"; + + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE = "xasecure.policymgr.clientssl.truststore"; + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_PASSWORD = "xasecure.policymgr.clientssl.truststore.password"; + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE = "xasecure.policymgr.clientssl.truststore.type"; + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL = "xasecure.policymgr.clientssl.truststore.credential.file"; + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL_ALIAS = "sslTrustStore"; + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE_DEFAULT = "jks"; + + public static final String RANGER_SSL_KEYMANAGER_ALGO_TYPE = "SunX509" ; + public static final String RANGER_SSL_TRUSTMANAGER_ALGO_TYPE = "SunX509" ; + public static final String RANGER_SSL_CONTEXT_ALGO_TYPE = "SSL" ; + + + private String mUrl = null; + private String mSslConfigFileName = null; + private String mUsername = null; + private String mPassword = null; + private boolean mIsSSL = false; + + 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; + + private Gson gsonBuilder = null; + private Client client = null; + + public RangerRESTClient() { + this(RangerConfiguration.getInstance().get(RANGER_PROP_POLICYMGR_URL), + RangerConfiguration.getInstance().get(RANGER_PROP_POLICYMGR_SSLCONFIG_FILENAME)); + } + + public RangerRESTClient(String url, String sslConfigFileName) { + mUrl = url; + mSslConfigFileName = sslConfigFileName; + + init(); + } + + public String getUrl() { + return mUrl; + } + + public void setUrl(String url) { + this.mUrl = url; + } + + public String getUsername() { + return mUsername; + } + + public String getPassword() { + return mPassword; + } + + public void setBasicAuthInfo(String username, String password) { + mUsername = username; + mPassword = password; + } + + public WebResource getResource(String relativeUrl) { + WebResource ret = getClient().resource(getUrl() + relativeUrl); + + return ret; + } + + public String toJson(Object obj) { + return gsonBuilder.toJson(obj); + } + + public <T> T fromJson(String json, Class<T> cls) { + return gsonBuilder.fromJson(json, cls); + } + + public Client getClient() { + if(client == null) { + synchronized(this) { + if(client == null) { + client = buildClient(); + } + } + } + + return client; + } + + private Client buildClient() { + Client client = null; + + if (mIsSSL) { + KeyManager[] kmList = getKeyManagers(); + TrustManager[] tmList = getTrustManagers(); + SSLContext sslContext = getSSLContext(kmList, tmList); + ClientConfig config = new DefaultClientConfig(); + + config.getClasses().add(JacksonJsonProvider.class); // to handle List<> unmarshalling + + HostnameVerifier hv = new HostnameVerifier() { + public boolean verify(String urlHostName, SSLSession session) { + return session.getPeerHost().equals(urlHostName); + } + }; + + config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(hv, sslContext)); + + client = Client.create(config); + } + + if(client == null) { + ClientConfig config = new DefaultClientConfig(); + + config.getClasses().add(JacksonJsonProvider.class); // to handle List<> unmarshalling + + client = Client.create(config); + } + + // TODO: for testing only + if(!StringUtils.isEmpty(mUsername) || !StringUtils.isEmpty(mPassword)) { + client.addFilter(new HTTPBasicAuthFilter(mUsername, mPassword)); + } + + return client; + } + + private void init() { + try { + gsonBuilder = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").setPrettyPrinting().create(); + } catch(Throwable excp) { + LOG.fatal("RangerRESTClient.init(): failed to create GsonBuilder object", excp); + } + + mIsSSL = StringUtil.containsIgnoreCase(mUrl, "https"); + + 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); + } + 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 initials 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/87fffe02/plugin-common/src/test/java/org/apache/ranger/plugin/store/TestServiceStore.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/test/java/org/apache/ranger/plugin/store/TestServiceStore.java b/plugin-common/src/test/java/org/apache/ranger/plugin/store/TestServiceStore.java index 722c8a7..d0ef299 100644 --- a/plugin-common/src/test/java/org/apache/ranger/plugin/store/TestServiceStore.java +++ b/plugin-common/src/test/java/org/apache/ranger/plugin/store/TestServiceStore.java @@ -64,6 +64,8 @@ public class TestServiceStore { @Test public void testServiceStore() throws Exception { + String updatedName, updatedDescription; + List<RangerServiceDef> sds = svcStore.getAllServiceDefs(); int initSdCount = sds == null ? 0 : sds.size(); @@ -76,7 +78,7 @@ public class TestServiceStore { sds = svcStore.getAllServiceDefs(); assertEquals("createServiceDef() failed", initSdCount + 1, sds == null ? 0 : sds.size()); - String updatedDescription = sd.getDescription() + ": updated"; + updatedDescription = sd.getDescription() + ": updated"; createdSd.setDescription(updatedDescription); RangerServiceDef updatedSd = svcStore.updateServiceDef(createdSd); assertNotNull("updateServiceDef(updatedDescription) failed", updatedSd); @@ -86,7 +88,7 @@ public class TestServiceStore { assertEquals("updateServiceDef(updatedDescription) failed", initSdCount + 1, sds == null ? 0 : sds.size()); /* - String updatedName = sd.getName() + "-Renamed"; + updatedName = sd.getName() + "-Renamed"; updatedSd.setName(updatedName); updatedSd = sdMgr.update(updatedSd); assertNotNull("updateServiceDef(updatedName) failed", updatedSd); @@ -117,7 +119,7 @@ public class TestServiceStore { services = svcStore.getAllServices(); assertEquals("updateService(updatedDescription) failed", initServiceCount + 1, services == null ? 0 : services.size()); - String updatedName = serviceName + "-Renamed"; + updatedName = serviceName + "-Renamed"; updatedSvc.setName(updatedName); updatedSvc = svcStore.updateService(updatedSvc); assertNotNull("updateService(updatedName) failed", updatedSvc); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/87fffe02/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java index 2ecd347..cfe07d0 100644 --- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java +++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java @@ -39,6 +39,7 @@ import org.apache.ranger.plugin.model.RangerService; import org.apache.ranger.plugin.model.RangerServiceDef; import org.apache.ranger.plugin.store.ServiceStore; import org.apache.ranger.plugin.store.ServiceStoreFactory; +import org.apache.ranger.plugin.util.ServicePolicies; import org.apache.ranger.view.VXResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; @@ -62,6 +63,75 @@ public class ServiceREST { svcStore = ServiceStoreFactory.instance().getServiceStore(); } + + @POST + @Path("/definitions") + @Produces({ "application/json", "application/xml" }) + @PreAuthorize("hasRole('ROLE_SYS_ADMIN')") + public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceREST.createServiceDef(" + serviceDef + ")"); + } + + RangerServiceDef ret = null; + + try { + ret = svcStore.createServiceDef(serviceDef); + } catch(Exception excp) { + throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceREST.createServiceDef(" + serviceDef + "): " + ret); + } + + return ret; + } + + @PUT + @Path("/definitions/{id}") + @Produces({ "application/json", "application/xml" }) + @PreAuthorize("hasRole('ROLE_SYS_ADMIN')") + public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceREST.updateServiceDef(" + serviceDef + ")"); + } + + RangerServiceDef ret = null; + + try { + ret = svcStore.updateServiceDef(serviceDef); + } catch(Exception excp) { + throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceREST.updateServiceDef(" + serviceDef + "): " + ret); + } + + return ret; + } + + @DELETE + @Path("/definitions/{id}") + @Produces({ "application/json", "application/xml" }) + @PreAuthorize("hasRole('ROLE_SYS_ADMIN')") + public void deleteServiceDef(@PathParam("id") Long id) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceREST.deleteServiceDef(" + id + ")"); + } + + try { + svcStore.deleteServiceDef(id); + } catch(Exception excp) { + throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceREST.deleteServiceDef(" + id + ")"); + } + } + @GET @Path("/definitions/{id}") @Produces({ "application/json", "application/xml" }) @@ -139,75 +209,73 @@ public class ServiceREST { return ret; } + @POST - @Path("/definitions") + @Path("/services") @Produces({ "application/json", "application/xml" }) - @PreAuthorize("hasRole('ROLE_SYS_ADMIN')") - public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) { + public RangerService createService(RangerService service) { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceREST.createServiceDef(" + serviceDef + ")"); + LOG.debug("==> ServiceREST.createService(" + service + ")"); } - RangerServiceDef ret = null; + RangerService ret = null; try { - ret = svcStore.createServiceDef(serviceDef); + ret = svcStore.createService(service); } catch(Exception excp) { throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); } if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceREST.createServiceDef(" + serviceDef + "): " + ret); + LOG.debug("<== ServiceREST.createService(" + service + "): " + ret); } return ret; } @PUT - @Path("/definitions") + @Path("/services/{id}") @Produces({ "application/json", "application/xml" }) - @PreAuthorize("hasRole('ROLE_SYS_ADMIN')") - public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) { + public RangerService updateService(RangerService service) { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceREST.updateServiceDef(" + serviceDef + ")"); + LOG.debug("==> ServiceREST.updateService(): " + service); } - RangerServiceDef ret = null; + RangerService ret = null; try { - ret = svcStore.updateServiceDef(serviceDef); + ret = svcStore.updateService(service); } catch(Exception excp) { throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); } if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceREST.updateServiceDef(" + serviceDef + "): " + ret); + LOG.debug("<== ServiceREST.updateService(" + service + "): " + ret); } return ret; } @DELETE - @Path("/definitions/{id}") + @Path("/services/{id}") @Produces({ "application/json", "application/xml" }) @PreAuthorize("hasRole('ROLE_SYS_ADMIN')") - public void deleteServiceDef(@PathParam("id") Long id) { + public void deleteService(@PathParam("id") Long id) { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceREST.deleteServiceDef(" + id + ")"); + LOG.debug("==> ServiceREST.deleteService(" + id + ")"); } try { - svcStore.deleteServiceDef(id); + svcStore.deleteService(id); } catch(Exception excp) { throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); } if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceREST.deleteServiceDef(" + id + ")"); + LOG.debug("<== ServiceREST.deleteService(" + id + ")"); } } - @GET @Path("/services/{id}") @Produces({ "application/json", "application/xml" }) @@ -311,96 +379,96 @@ public class ServiceREST { } @POST - @Path("/services") + @Path("/services/validateConfig") @Produces({ "application/json", "application/xml" }) - public RangerService createService(RangerService service) { + public VXResponse validateConfig(RangerService service) { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceREST.createService(" + service + ")"); + LOG.debug("==> ServiceREST.validateConfig(" + service + ")"); } - RangerService ret = null; + VXResponse ret = new VXResponse(); try { - ret = svcStore.createService(service); + // TODO: svcStore.validateConfig(service); } catch(Exception excp) { - throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); + ret.setStatusCode(VXResponse.STATUS_ERROR); + // TODO: message } if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceREST.createService(" + service + "): " + ret); + LOG.debug("<== ServiceREST.validateConfig(" + service + "): " + ret); } return ret; } - @PUT - @Path("/services/{id}") + + @POST + @Path("/policies") @Produces({ "application/json", "application/xml" }) - public RangerService updateService(RangerService service) { + public RangerPolicy createPolicy(RangerPolicy policy) { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceREST.updateService(): " + service); + LOG.debug("==> ServiceREST.createPolicy(" + policy + ")"); } - RangerService ret = null; + RangerPolicy ret = null; try { - ret = svcStore.updateService(service); + ret = svcStore.createPolicy(policy); } catch(Exception excp) { throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); } if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceREST.updateService(" + service + "): " + ret); + LOG.debug("<== ServiceREST.createPolicy(" + policy + "): " + ret); } return ret; } - @DELETE - @Path("/services/{id}") + @PUT + @Path("/policies/{id}") @Produces({ "application/json", "application/xml" }) - @PreAuthorize("hasRole('ROLE_SYS_ADMIN')") - public void deleteService(@PathParam("id") Long id) { + public RangerPolicy updatePolicy(RangerPolicy policy) { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceREST.deleteService(" + id + ")"); + LOG.debug("==> ServiceREST.updatePolicy(" + policy + ")"); } + RangerPolicy ret = null; + try { - svcStore.deleteService(id); + ret = svcStore.updatePolicy(policy); } catch(Exception excp) { throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); } if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceREST.deleteService(" + id + ")"); + LOG.debug("<== ServiceREST.updatePolicy(" + policy + "): " + ret); } + + return ret; } - @POST - @Path("/services/validateConfig") + @DELETE + @Path("/policies/{id}") @Produces({ "application/json", "application/xml" }) - public VXResponse validateConfig(RangerService service) { + @PreAuthorize("hasRole('ROLE_SYS_ADMIN')") + public void deletePolicy(@PathParam("id") Long id) { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceREST.validateConfig(" + service + ")"); + LOG.debug("==> ServiceREST.deletePolicy(" + id + ")"); } - VXResponse ret = new VXResponse(); - try { - // TODO: svcStore.validateConfig(service); + svcStore.deletePolicy(id); } catch(Exception excp) { - ret.setStatusCode(VXResponse.STATUS_ERROR); - // TODO: message + throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); } if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceREST.validateConfig(" + service + "): " + ret); + LOG.debug("<== ServiceREST.deletePolicy(" + id + ")"); } - - return ret; } - @GET @Path("/policies/{id}") @Produces({ "application/json", "application/xml" }) @@ -439,9 +507,7 @@ public class ServiceREST { List<RangerPolicy> ret = null; try { - Long serviceId = Long.parseLong(request.getParameter("serviceId")); - - ret = svcStore.getServicePolicies(serviceId); + ret = svcStore.getAllPolicies(); } catch(Exception excp) { throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); } @@ -479,7 +545,7 @@ public class ServiceREST { } @GET - @Path("/services/{id}/policies") + @Path("/policies/service/{id}") @Produces({ "application/json", "application/xml" }) public List<RangerPolicy> getServicePolicies(@PathParam("id") Long serviceId, @Context HttpServletRequest request) { if(LOG.isDebugEnabled()) { @@ -505,69 +571,57 @@ public class ServiceREST { return ret; } - @POST - @Path("/policies") + @GET + @Path("/policies/service/name/{name}") @Produces({ "application/json", "application/xml" }) - public RangerPolicy createPolicy(RangerPolicy policy) { + public List<RangerPolicy> getServicePolicies(@PathParam("name") String serviceName, @Context HttpServletRequest request) { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceREST.createPolicy(" + policy + ")"); + LOG.debug("==> ServiceREST.getServicePolicies(" + serviceName + ")"); } - RangerPolicy ret = null; + List<RangerPolicy> ret = null; try { - ret = svcStore.createPolicy(policy); + ret = svcStore.getServicePolicies(serviceName); } catch(Exception excp) { throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); } + if(ret == null) { + throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true); + } + if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceREST.createPolicy(" + policy + "): " + ret); + LOG.debug("<== ServiceREST.getServicePolicies(" + serviceName + "): count=" + (ret == null ? 0 : ret.size())); } return ret; } - @PUT - @Path("/policies") + @GET + @Path("/policies/service/name/{name}/{lastKnownVersion}") @Produces({ "application/json", "application/xml" }) - public RangerPolicy updatePolicy(RangerPolicy policy) { + public ServicePolicies getServicePoliciesIfUpdated(@PathParam("name") String serviceName, @PathParam("lastKnownVersion") Long lastKnownVersion) throws Exception { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceREST.updatePolicy(" + policy + ")"); + LOG.debug("==> ServiceREST.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ")"); } - RangerPolicy ret = null; + ServicePolicies ret = null; try { - ret = svcStore.updatePolicy(policy); + ret = svcStore.getServicePoliciesIfUpdated(serviceName, lastKnownVersion); } catch(Exception excp) { throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); } - if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceREST.updatePolicy(" + policy + "): " + ret); + if(ret == null) { + throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true); } - return ret; - } - - @DELETE - @Path("/policies/{id}") - @Produces({ "application/json", "application/xml" }) - @PreAuthorize("hasRole('ROLE_SYS_ADMIN')") - public void deletePolicy(@PathParam("id") Long id) { if(LOG.isDebugEnabled()) { - LOG.debug("==> ServiceREST.deletePolicy(" + id + ")"); + LOG.debug("<== ServiceREST.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + "): count=" + ((ret == null || ret.getPolicies() == null) ? 0 : ret.getPolicies().size())); } - try { - svcStore.deletePolicy(id); - } catch(Exception excp) { - throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true); - } - - if(LOG.isDebugEnabled()) { - LOG.debug("<== ServiceREST.deletePolicy(" + id + ")"); - } + return ret; } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/87fffe02/security-admin/src/main/webapp/scripts/controllers/Controller.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/controllers/Controller.js b/security-admin/src/main/webapp/scripts/controllers/Controller.js index 9dc44b5..b58a632 100644 --- a/security-admin/src/main/webapp/scripts/controllers/Controller.js +++ b/security-admin/src/main/webapp/scripts/controllers/Controller.js @@ -687,7 +687,7 @@ define(function(require) { 'serviceId' : serviceId } });*/ - rangerPolicyList.url = "service/plugins/services/"+serviceId+"/policies" + rangerPolicyList.url = "service/plugins/policies/service/"+serviceId rangerService.fetch({ cache : false,