http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/store/file/ServiceFileStore.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/file/ServiceFileStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/file/ServiceFileStore.java new file mode 100644 index 0000000..b51c160 --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/file/ServiceFileStore.java @@ -0,0 +1,1589 @@ +/* + * 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.file; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.collections.Predicate; +import org.apache.commons.collections.PredicateUtils; +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.fs.Path; +import org.apache.ranger.plugin.model.RangerBaseModelObject; +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.apache.ranger.plugin.model.RangerService; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; +import org.apache.ranger.plugin.store.ServiceStore; +import org.apache.ranger.plugin.util.SearchFilter; +import org.apache.ranger.plugin.util.ServicePolicies; + + +public class ServiceFileStore extends BaseFileStore implements ServiceStore { + private static final Log LOG = LogFactory.getLog(ServiceFileStore.class); + + private long nextServiceDefId = 0; + private long nextServiceId = 0; + private long nextPolicyId = 0; + + static Map<String, Long> legacyServiceDefs = new HashMap<String, Long>(); + + static { + legacyServiceDefs.put("hdfs", new Long(1)); + legacyServiceDefs.put("hbase", new Long(2)); + legacyServiceDefs.put("hive", new Long(3)); + legacyServiceDefs.put("knox", new Long(5)); + legacyServiceDefs.put("storm", new Long(6)); + } + + public ServiceFileStore() { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.ServiceFileStore()"); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.ServiceFileStore()"); + } + } + + @Override + public void init() throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.init()"); + } + + super.initStore(); + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.init()"); + } + } + + @Override + public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceDefFileStore.createServiceDef(" + serviceDef + ")"); + } + + RangerServiceDef existing = getServiceDefByName(serviceDef.getName()); + + if(existing != null) { + throw new Exception(serviceDef.getName() + ": service-def already exists (id=" + existing.getId() + ")"); + } + + RangerServiceDef ret = null; + + try { + preCreate(serviceDef); + + serviceDef.setId(nextServiceDefId++); + + ret = saveToFile(serviceDef, false); + + postCreate(ret); + } catch(Exception excp) { + LOG.warn("ServiceDefFileStore.createServiceDef(): failed to save service-def '" + serviceDef.getName() + "'", excp); + + throw new Exception("failed to save service-def '" + serviceDef.getName() + "'", excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceDefFileStore.createServiceDef(" + serviceDef + ")"); + } + + return ret; + } + + @Override + public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceDefFileStore.updateServiceDef(" + serviceDef + ")"); + } + + RangerServiceDef existing = getServiceDef(serviceDef.getId()); + + if(existing == null) { + throw new Exception(serviceDef.getId() + ": service-def does not exist"); + } + + if(isLegacyServiceDef(existing)) { + String msg = existing.getName() + ": is an in-built service-def. Update not allowed"; + + LOG.warn(msg); + + throw new Exception(msg); + } + + String existingName = existing.getName(); + + boolean renamed = !StringUtils.equalsIgnoreCase(serviceDef.getName(), existingName); + + // renaming service-def would require updating services that refer to this service-def + if(renamed) { + LOG.warn("ServiceDefFileStore.updateServiceDef(): service-def renaming not supported. " + existingName + " ==> " + serviceDef.getName()); + + throw new Exception("service-def renaming not supported. " + existingName + " ==> " + serviceDef.getName()); + } + + RangerServiceDef ret = null; + + try { + existing.updateFrom(serviceDef); + + preUpdate(existing); + + ret = saveToFile(existing, true); + + postUpdate(ret); + } catch(Exception excp) { + LOG.warn("ServiceDefFileStore.updateServiceDef(): failed to save service-def '" + existing.getName() + "'", excp); + + throw new Exception("failed to save service-def '" + existing.getName() + "'", excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceDefFileStore.updateServiceDef(" + serviceDef + "): " + ret); + } + + return ret; + } + + @Override + public void deleteServiceDef(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceDefFileStore.deleteServiceDef(" + id + ")"); + } + + RangerServiceDef existing = getServiceDef(id); + + if(existing == null) { + throw new Exception("service-def does not exist. id=" + id); + } + + if(isLegacyServiceDef(existing)) { + String msg = existing.getName() + ": is an in-built service-def. Update not allowed"; + + LOG.warn(msg); + + throw new Exception(msg); + } + + // TODO: deleting service-def would require deleting services that refer to this service-def + + try { + preDelete(existing); + + Path filePath = new Path(getServiceDefFile(id)); + + deleteFile(filePath); + + postDelete(existing); + } catch(Exception excp) { + throw new Exception("failed to delete service-def. id=" + id + "; name=" + existing.getName(), excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceDefFileStore.deleteServiceDef(" + id + ")"); + } + } + + @Override + public RangerServiceDef getServiceDef(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceDefFileStore.getServiceDef(" + id + ")"); + } + + RangerServiceDef ret = null; + + if(id != null) { + SearchFilter filter = new SearchFilter(SearchFilter.SERVICE_TYPE_ID, id.toString()); + + List<RangerServiceDef> serviceDefs = getServiceDefs(filter); + + ret = CollectionUtils.isEmpty(serviceDefs) ? null : serviceDefs.get(0); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceDefFileStore.getServiceDef(" + id + "): " + ret); + } + + return ret; + } + + @Override + public RangerServiceDef getServiceDefByName(String name) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceDefFileStore.getServiceDefByName(" + name + ")"); + } + + RangerServiceDef ret = null; + + if(name != null) { + SearchFilter filter = new SearchFilter(SearchFilter.SERVICE_TYPE, name); + + List<RangerServiceDef> serviceDefs = getServiceDefs(filter); + + ret = CollectionUtils.isEmpty(serviceDefs) ? null : serviceDefs.get(0); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceDefFileStore.getServiceDefByName(" + name + "): " + ret); + } + + return ret; + } + + @Override + public List<RangerServiceDef> getServiceDefs(SearchFilter filter) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceDefFileStore.getServiceDefs()"); + } + + List<RangerServiceDef> ret = getAllServiceDefs(); + + if(ret != null && filter != null && !filter.isEmpty()) { + CollectionUtils.filter(ret, getPredicate(filter)); + + Comparator<RangerBaseModelObject> comparator = getSorter(filter); + + if(comparator != null) { + Collections.sort(ret, comparator); + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceDefFileStore.getServiceDefs(): count=" + (ret == null ? 0 : ret.size())); + } + + return ret; + } + + + @Override + public RangerService createService(RangerService service) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.createService(" + service + ")"); + } + + RangerService existing = getServiceByName(service.getName()); + + if(existing != null) { + throw new Exception("service already exists - '" + service.getName() + "'. ID=" + existing.getId()); + } + + RangerService ret = null; + + try { + preCreate(service); + + service.setId(nextServiceId++); + + ret = saveToFile(service, false); + + postCreate(service); + } catch(Exception excp) { + throw new Exception("failed to save service '" + service.getName() + "'", excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.createService(" + service + "): " + ret); + } + + return ret; + } + + @Override + public RangerService updateService(RangerService service) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.updateService(" + service + ")"); + } + + RangerService existing = getService(service.getId()); + + if(existing == null) { + throw new Exception("no service exists with ID=" + service.getId()); + } + + String existingName = existing.getName(); + + boolean renamed = !StringUtils.equalsIgnoreCase(service.getName(), existingName); + + if(renamed) { + RangerService newNameService = getServiceByName(service.getName()); + + if(newNameService != null) { + throw new Exception("another service already exists with name '" + service.getName() + "'. ID=" + newNameService.getId()); + } + } + + RangerService ret = null; + + try { + existing.updateFrom(service); + + preUpdate(existing); + + ret = saveToFile(existing, true); + + postUpdate(ret); + + if(renamed) { + handleServiceRename(ret, existingName); + } + } catch(Exception excp) { + throw new Exception("failed to update service '" + existing.getName() + "'", excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.updateService(" + service + "): " + ret); + } + + return ret; + } + + @Override + public void deleteService(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.deleteService(" + id + ")"); + } + + RangerService existing = getService(id); + + if(existing == null) { + throw new Exception("no service exists with ID=" + id); + } + + try { + Path filePath = new Path(getServiceFile(id)); + + preDelete(existing); + + handleServiceDelete(existing); + + deleteFile(filePath); + + postDelete(existing); + } catch(Exception excp) { + throw new Exception("failed to delete service with ID=" + id, excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.deleteService(" + id + ")"); + } + } + + @Override + public RangerService getService(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.getService(" + id + ")"); + } + + RangerService ret = null; + + try { + Path filePath = new Path(getServiceFile(id)); + + ret = loadFromFile(filePath, RangerService.class); + } catch(Exception excp) { + LOG.error("ServiceFileStore.getService(" + id + "): failed to read service", excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.getService(" + id + "): " + ret); + } + + return ret; + } + + @Override + public RangerService getServiceByName(String name) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.getServiceByName(" + name + ")"); + } + + RangerService ret = null; + + if(name != null) { + SearchFilter filter = new SearchFilter(SearchFilter.SERVICE_NAME, name); + + List<RangerService> services = getServices(filter); + + ret = CollectionUtils.isEmpty(services) ? null : services.get(0); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.getServiceByName(" + name + "): " + ret); + } + + return ret; + } + + @Override + public List<RangerService> getServices(SearchFilter filter) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.getServices()"); + } + + List<RangerService> ret = getAllServices(); + + if(ret != null && filter != null && !filter.isEmpty()) { + CollectionUtils.filter(ret, getPredicate(filter)); + + Comparator<RangerBaseModelObject> comparator = getSorter(filter); + + if(comparator != null) { + Collections.sort(ret, comparator); + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.getServices(): count=" + (ret == null ? 0 : ret.size())); + } + + return ret; + } + + @Override + public RangerPolicy createPolicy(RangerPolicy policy) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.createPolicy(" + policy + ")"); + } + + RangerService service = getServiceByName(policy.getService()); + + if(service == null) { + throw new Exception("service does not exist - name=" + policy.getService()); + } + + 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()); + } + + RangerPolicy ret = null; + + try { + preCreate(policy); + + policy.setId(nextPolicyId++); + + ret = saveToFile(policy, service.getId(), false); + + handlePolicyUpdate(service); + + postCreate(ret); + } catch(Exception excp) { + throw new Exception("failed to save policy: ServiceName=" + policy.getService() + "; PolicyName=" + policy.getName(), excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.createPolicy(" + policy + "): " + ret); + } + + return ret; + } + + @Override + public RangerPolicy updatePolicy(RangerPolicy policy) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.updatePolicy(" + policy + ")"); + } + + RangerPolicy existing = getPolicy(policy.getId()); + + if(existing == null) { + throw new Exception("no policy exists with ID=" + policy.getId()); + } + + RangerService service = getServiceByName(policy.getService()); + + if(service == null) { + throw new Exception("service does not exist - name=" + policy.getService()); + } + + if(! StringUtils.equalsIgnoreCase(existing.getService(), policy.getService())) { + throw new Exception("policy id=" + policy.getId() + " already exists in service " + existing.getService() + ". It can not be moved to service " + policy.getService()); + } + + boolean renamed = !StringUtils.equalsIgnoreCase(policy.getName(), existing.getName()); + + if(renamed) { + RangerPolicy newNamePolicy = findPolicyByName(service.getName(), policy.getName()); + + if(newNamePolicy != null) { + throw new Exception("another policy already exists with name '" + policy.getName() + "'. ID=" + newNamePolicy.getId()); + } + } + + RangerPolicy ret = null; + + try { + existing.updateFrom(policy); + + preUpdate(existing); + + ret = saveToFile(existing, service.getId(), true); + + handlePolicyUpdate(service); + + postUpdate(ret); + } catch(Exception excp) { + throw new Exception("failed to update policy - ID=" + existing.getId(), excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.updatePolicy(" + policy + "): " + ret); + } + + return ret; + } + + @Override + public void deletePolicy(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.deletePolicy(" + id + ")"); + } + + RangerPolicy existing = getPolicy(id); + + if(existing == null) { + throw new Exception("no policy exists with ID=" + id); + } + + RangerService service = getServiceByName(existing.getService()); + + if(service == null) { + throw new Exception("service does not exist - name='" + existing.getService()); + } + + try { + preDelete(existing); + + Path filePath = new Path(getPolicyFile(service.getId(), existing.getId())); + + deleteFile(filePath); + + handlePolicyUpdate(service); + + postDelete(existing); + } catch(Exception excp) { + throw new Exception(existing.getId() + ": failed to delete policy", excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.deletePolicy(" + id + ")"); + } + } + + @Override + public RangerPolicy getPolicy(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.getPolicy(" + id + ")"); + } + + RangerPolicy ret = null; + + if(id != null) { + SearchFilter filter = new SearchFilter(SearchFilter.POLICY_ID, id.toString()); + + List<RangerPolicy> policies = getPolicies(filter); + + ret = CollectionUtils.isEmpty(policies) ? null : policies.get(0); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.getPolicy(" + id + "): " + ret); + } + + return ret; + } + + @Override + public List<RangerPolicy> getPolicies(SearchFilter filter) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.getPolicies()"); + } + + List<RangerPolicy> ret = getAllPolicies(); + + if(ret != null && filter != null && !filter.isEmpty()) { + CollectionUtils.filter(ret, getPredicate(filter)); + + Comparator<RangerBaseModelObject> comparator = getSorter(filter); + + if(comparator != null) { + Collections.sort(ret, comparator); + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.getPolicies(): count=" + (ret == null ? 0 : ret.size())); + } + + return ret; + } + + @Override + public List<RangerPolicy> getServicePolicies(Long serviceId, SearchFilter filter) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.getServicePolicies(" + serviceId + ")"); + } + + RangerService service = getService(serviceId); + + if(service == null) { + throw new Exception("service does not exist - id='" + serviceId); + } + + List<RangerPolicy> ret = getServicePolicies(service.getName(), filter); + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.getServicePolicies(" + serviceId + "): " + ((ret == null) ? 0 : ret.size())); + } + + return ret; + } + + @Override + public List<RangerPolicy> getServicePolicies(String serviceName, SearchFilter filter) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.getServicePolicies(" + serviceName + ")"); + } + + List<RangerPolicy> ret = new ArrayList<RangerPolicy>(); + + try { + if(filter == null) { + filter = new SearchFilter(); + } + + filter.setParam(SearchFilter.SERVICE_NAME, serviceName); + + ret = getPolicies(filter); + } catch(Exception excp) { + LOG.error("ServiceFileStore.getServicePolicies(" + serviceName + "): failed to read policies", excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.getServicePolicies(" + serviceName + "): count=" + ((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 + ")"); + } + + RangerService service = getServiceByName(serviceName); + + if(service == null) { + throw new Exception("service does not exist - name=" + serviceName); + } + + RangerServiceDef serviceDef = getServiceDefByName(service.getType()); + + if(serviceDef == null) { + throw new Exception(service.getType() + ": unknown service-def)"); + } + + ServicePolicies ret = new ServicePolicies(); + ret.setServiceId(service.getId()); + ret.setServiceName(service.getName()); + ret.setPolicyVersion(service.getPolicyVersion()); + ret.setPolicyUpdateTime(service.getPolicyUpdateTime()); + ret.setServiceDef(serviceDef); + ret.setPolicies(new ArrayList<RangerPolicy>()); + + if(lastKnownVersion == null || service.getPolicyVersion() == null || lastKnownVersion.longValue() != service.getPolicyVersion().longValue()) { + SearchFilter filter = new SearchFilter(SearchFilter.SERVICE_NAME, serviceName); + + List<RangerPolicy> policies = getPolicies(filter); + + ret.setPolicies(policies); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + "): count=" + ((ret == null || ret.getPolicies() == null) ? 0 : ret.getPolicies().size())); + } + + if(ret != null && ret.getPolicies() != null) { + Collections.sort(ret.getPolicies(), idComparator); + } + + return ret; + } + + + private void handleServiceRename(RangerService service, String oldName) throws Exception { + List<RangerPolicy> policies = getAllPolicies(); + + if(policies != null) { + for(RangerPolicy policy : policies) { + if(StringUtils.equalsIgnoreCase(policy.getService(), oldName)) { + policy.setService(service.getName()); + + preUpdate(policy); + + saveToFile(policy, service.getId(), true); + + postUpdate(policy); + } + } + } + } + + private void handleServiceDelete(RangerService service) throws Exception { + List<RangerPolicy> policies = getAllPolicies(); + + if(policies != null) { + for(RangerPolicy policy : policies) { + if(! StringUtils.equals(policy.getService(), service.getName())) { + continue; + } + + preDelete(policy); + + Path filePath = new Path(getPolicyFile(service.getId(), policy.getId())); + + deleteFile(filePath); + + postDelete(policy); + } + } + } + + private void handlePolicyUpdate(RangerService service) throws Exception { + if(service == null) { + return; + } + + Long policyVersion = service.getPolicyVersion(); + + if(policyVersion == null) { + policyVersion = new Long(1); + } else { + policyVersion = new Long(policyVersion.longValue() + 1); + } + + service.setPolicyVersion(policyVersion); + service.setPolicyUpdateTime(new Date()); + + saveToFile(service, true); + } + + 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; + + SearchFilter filter = new SearchFilter(); + + filter.setParam(SearchFilter.SERVICE_NAME, serviceName); + filter.setParam(SearchFilter.POLICY_NAME, policyName); + + List<RangerPolicy> policies = getPolicies(filter); + + ret = CollectionUtils.isEmpty(policies) ? null : policies.get(0); + + 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())); + } + + private boolean isLegacyServiceDef(String name) { + return name == null ? false : legacyServiceDefs.containsKey(name); + } + + private boolean isLegacyServiceDef(Long id) { + return id == null ? false : legacyServiceDefs.containsValue(id); + } + + private List<RangerServiceDef> getAllServiceDefs() throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceDefFileStore.getAllServiceDefs()"); + } + + List<RangerServiceDef> ret = new ArrayList<RangerServiceDef>(); + + try { + // load definitions for legacy services from embedded resources + String[] legacyServiceDefResources = { + "/service-defs/ranger-servicedef-hdfs.json", + "/service-defs/ranger-servicedef-hive.json", + "/service-defs/ranger-servicedef-hbase.json", + "/service-defs/ranger-servicedef-knox.json", + "/service-defs/ranger-servicedef-storm.json", + }; + + for(String resource : legacyServiceDefResources) { + RangerServiceDef sd = loadFromResource(resource, RangerServiceDef.class); + + if(sd != null) { + ret.add(sd); + } + } + nextServiceDefId = getMaxId(ret) + 1; + + // load service definitions from file system + List<RangerServiceDef> sds = loadFromDir(new Path(getDataDir()), FILE_PREFIX_SERVICE_DEF, RangerServiceDef.class); + + if(sds != null) { + for(RangerServiceDef sd : sds) { + if(sd != null) { + if(isLegacyServiceDef(sd)) { + LOG.warn("Found in-built service-def '" + sd.getName() + "' under " + getDataDir() + ". Ignorning"); + + continue; + } + + // if the ServiceDef is already found, remove the earlier definition + for(int i = 0; i < ret.size(); i++) { + RangerServiceDef currSd = ret.get(i); + + if(StringUtils.equals(currSd.getName(), sd.getName()) || + ObjectUtils.equals(currSd.getId(), sd.getId())) { + ret.remove(i); + } + } + + ret.add(sd); + } + } + } + nextServiceDefId = getMaxId(ret) + 1; + } catch(Exception excp) { + LOG.error("ServiceDefFileStore.getAllServiceDefs(): failed to read service-defs", excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceDefFileStore.getAllServiceDefs(): count=" + (ret == null ? 0 : ret.size())); + } + + if(ret != null) { + Collections.sort(ret, idComparator); + + for(RangerServiceDef sd : ret) { + Collections.sort(sd.getResources(), resourceLevelComparator); + } + } + + return ret; + } + + private List<RangerService> getAllServices() throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.getAllServices()"); + } + + List<RangerService> ret = null; + + try { + ret = loadFromDir(new Path(getDataDir()), FILE_PREFIX_SERVICE, RangerService.class); + + nextServiceId = getMaxId(ret) + 1; + } catch(Exception excp) { + LOG.error("ServiceFileStore.getAllServices(): failed to read services", excp); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.getAllServices(): count=" + (ret == null ? 0 : ret.size())); + } + + if(ret != null) { + Collections.sort(ret, idComparator); + } + + return ret; + } + + private List<RangerPolicy> getAllPolicies() throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceFileStore.getAllPolicies()"); + } + + List<RangerPolicy> ret = null; + + try { + ret = loadFromDir(new Path(getDataDir()), FILE_PREFIX_POLICY, RangerPolicy.class); + + nextPolicyId = getMaxId(ret) + 1; + } catch(Exception excp) { + LOG.error("ServiceFileStore.getAllPolicies(): failed to read policies", excp); + } + + if(ret != null) { + Collections.sort(ret, idComparator); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceFileStore.getAllPolicies(): count=" + (ret == null ? 0 : ret.size())); + } + + return ret; + } + + private String getServiceType(String serviceName) { + RangerService service = null; + + try { + service = getServiceByName(serviceName); + } catch(Exception excp) { + // ignore + } + + return service != null ? service.getType() : null; + } + + private Long getServiceId(String serviceName) { + RangerService service = null; + + try { + service = getServiceByName(serviceName); + } catch(Exception excp) { + // ignore + } + + return service != null ? service.getId() : null; + } + + private final static Comparator<RangerBaseModelObject> idComparator = new Comparator<RangerBaseModelObject>() { + @Override + public int compare(RangerBaseModelObject o1, RangerBaseModelObject o2) { + Long val1 = (o1 != null) ? o1.getId() : null; + Long val2 = (o2 != null) ? o2.getId() : null; + + return ObjectUtils.compare(val1, val2); + } + }; + + private final static Comparator<RangerBaseModelObject> createTimeComparator = new Comparator<RangerBaseModelObject>() { + @Override + public int compare(RangerBaseModelObject o1, RangerBaseModelObject o2) { + Date val1 = (o1 != null) ? o1.getCreateTime() : null; + Date val2 = (o2 != null) ? o2.getCreateTime() : null; + + return ObjectUtils.compare(val1, val2); + } + }; + + private final static Comparator<RangerBaseModelObject> updateTimeComparator = new Comparator<RangerBaseModelObject>() { + @Override + public int compare(RangerBaseModelObject o1, RangerBaseModelObject o2) { + Date val1 = (o1 != null) ? o1.getUpdateTime() : null; + Date val2 = (o2 != null) ? o2.getUpdateTime() : null; + + return ObjectUtils.compare(val1, val2); + } + }; + + private final static Comparator<RangerBaseModelObject> serviceDefNameComparator = new Comparator<RangerBaseModelObject>() { + @Override + public int compare(RangerBaseModelObject o1, RangerBaseModelObject o2) { + String val1 = null; + String val2 = null; + + if(o1 != null) { + if(o1 instanceof RangerServiceDef) { + val1 = ((RangerServiceDef)o1).getName(); + } else if(o1 instanceof RangerService) { + val1 = ((RangerService)o1).getType(); + } + } + + if(o2 != null) { + if(o2 instanceof RangerServiceDef) { + val2 = ((RangerServiceDef)o2).getName(); + } else if(o2 instanceof RangerService) { + val2 = ((RangerService)o2).getType(); + } + } + + return ObjectUtils.compare(val1, val2); + } + }; + + private final static Comparator<RangerBaseModelObject> serviceNameComparator = new Comparator<RangerBaseModelObject>() { + @Override + public int compare(RangerBaseModelObject o1, RangerBaseModelObject o2) { + String val1 = null; + String val2 = null; + + if(o1 != null) { + if(o1 instanceof RangerPolicy) { + val1 = ((RangerPolicy)o1).getService(); + } else if(o1 instanceof RangerService) { + val1 = ((RangerService)o1).getType(); + } + } + + if(o2 != null) { + if(o2 instanceof RangerPolicy) { + val2 = ((RangerPolicy)o2).getService(); + } else if(o2 instanceof RangerService) { + val2 = ((RangerService)o2).getType(); + } + } + + return ObjectUtils.compare(val1, val2); + } + }; + + private final static Comparator<RangerBaseModelObject> policyNameComparator = new Comparator<RangerBaseModelObject>() { + @Override + public int compare(RangerBaseModelObject o1, RangerBaseModelObject o2) { + String val1 = (o1 != null && o1 instanceof RangerPolicy) ? ((RangerPolicy)o1).getName() : null; + String val2 = (o2 != null && o2 instanceof RangerPolicy) ? ((RangerPolicy)o2).getName() : null; + + return ObjectUtils.compare(val1, val2); + } + }; + + private final static Comparator<RangerResourceDef> resourceLevelComparator = new Comparator<RangerResourceDef>() { + @Override + public int compare(RangerResourceDef o1, RangerResourceDef o2) { + Integer val1 = (o1 != null) ? o1.getLevel() : null; + Integer val2 = (o2 != null) ? o2.getLevel() : null; + + return ObjectUtils.compare(val1, val2); + } + }; + + private Predicate getPredicate(SearchFilter filter) { + if(filter == null || filter.isEmpty()) { + return null; + } + + List<Predicate> predicates = new ArrayList<Predicate>(); + + addPredicateForLoginUser(filter.getParam(SearchFilter.LOGIN_USER), predicates); + addPredicateForServiceType(filter.getParam(SearchFilter.SERVICE_TYPE), predicates); + addPredicateForServiceTypeId(filter.getParam(SearchFilter.SERVICE_TYPE_ID), predicates); + addPredicateForServiceName(filter.getParam(SearchFilter.SERVICE_NAME), predicates); + addPredicateForServiceId(filter.getParam(SearchFilter.SERVICE_ID), predicates); + addPredicateForPolicyName(filter.getParam(SearchFilter.POLICY_NAME), predicates); + addPredicateForPolicyId(filter.getParam(SearchFilter.POLICY_ID), predicates); + addPredicateForStatus(filter.getParam(SearchFilter.STATUS), predicates); + addPredicateForUserName(filter.getParam(SearchFilter.USER), predicates); + addPredicateForGroupName(filter.getParam(SearchFilter.GROUP), predicates); + addPredicateForResources(filter.getParamsWithPrefix(SearchFilter.RESOURCE_PREFIX, true), predicates); + + Predicate ret = CollectionUtils.isEmpty(predicates) ? null : PredicateUtils.allPredicate(predicates); + + return ret; + } + + private static Map<String, Comparator<RangerBaseModelObject>> sorterMap = new HashMap<String, Comparator<RangerBaseModelObject>>(); + + static { + sorterMap.put(SearchFilter.SERVICE_TYPE, serviceDefNameComparator); + sorterMap.put(SearchFilter.SERVICE_TYPE_ID, idComparator); + sorterMap.put(SearchFilter.SERVICE_NAME, serviceNameComparator); + sorterMap.put(SearchFilter.SERVICE_TYPE_ID, idComparator); + sorterMap.put(SearchFilter.POLICY_NAME, policyNameComparator); + sorterMap.put(SearchFilter.POLICY_ID, idComparator); + sorterMap.put(SearchFilter.CREATE_TIME, createTimeComparator); + sorterMap.put(SearchFilter.UPDATE_TIME, updateTimeComparator); + } + + private Comparator<RangerBaseModelObject> getSorter(SearchFilter filter) { + String sortBy = filter == null ? null : filter.getParam(SearchFilter.SORT_BY); + + if(StringUtils.isEmpty(sortBy)) { + return null; + } + + Comparator<RangerBaseModelObject> ret = sorterMap.get(sortBy); + + return ret; + } + + private Predicate addPredicateForLoginUser(final String loginUser, List<Predicate> predicates) { + if(StringUtils.isEmpty(loginUser)) { + return null; + } + + Predicate ret = new Predicate() { + @Override + public boolean evaluate(Object object) { + if(object == null) { + return false; + } + + boolean ret = false; + + if(object instanceof RangerPolicy) { + RangerPolicy policy = (RangerPolicy)object; + + for(RangerPolicyItem policyItem : policy.getPolicyItems()) { + if(!policyItem.getDelegateAdmin()) { + continue; + } + + if(policyItem.getUsers().contains(loginUser)) { // TODO: group membership check + ret = true; + + break; + } + } + } else { + ret = true; + } + + return ret; + } + }; + + if(ret != null) { + predicates.add(ret); + } + + return ret; + } + + private Predicate addPredicateForServiceType(final String serviceType, List<Predicate> predicates) { + if(StringUtils.isEmpty(serviceType)) { + return null; + } + + Predicate ret = new Predicate() { + @Override + public boolean evaluate(Object object) { + if(object == null) { + return false; + } + + boolean ret = false; + + if(object instanceof RangerPolicy) { + RangerPolicy policy = (RangerPolicy)object; + + ret = StringUtils.equals(serviceType, getServiceType(policy.getService())); + } else if(object instanceof RangerService) { + RangerService service = (RangerService)object; + + ret = StringUtils.equals(serviceType, service.getType()); + } else if(object instanceof RangerServiceDef) { + RangerServiceDef serviceDef = (RangerServiceDef)object; + + ret = StringUtils.equals(serviceType, serviceDef.getName()); + } + + return ret; + } + }; + + if(predicates != null) { + predicates.add(ret); + } + + return ret; + } + + private Predicate addPredicateForServiceTypeId(final String serviceTypeId, List<Predicate> predicates) { + if(StringUtils.isEmpty(serviceTypeId)) { + return null; + } + + Predicate ret = new Predicate() { + @Override + public boolean evaluate(Object object) { + if(object == null) { + return false; + } + + boolean ret = false; + + if(object instanceof RangerServiceDef) { + RangerServiceDef serviceDef = (RangerServiceDef)object; + Long svcDefId = serviceDef.getId(); + + if(svcDefId != null) { + ret = StringUtils.equals(serviceTypeId, svcDefId.toString()); + } + } else { + ret = true; + } + + return ret; + } + }; + + if(predicates != null) { + predicates.add(ret); + } + + return ret; + } + + private Predicate addPredicateForServiceName(final String serviceName, List<Predicate> predicates) { + if(StringUtils.isEmpty(serviceName)) { + return null; + } + + Predicate ret = new Predicate() { + @Override + public boolean evaluate(Object object) { + if(object == null) { + return false; + } + + boolean ret = false; + + if(object instanceof RangerPolicy) { + RangerPolicy policy = (RangerPolicy)object; + + ret = StringUtils.equals(serviceName, policy.getService()); + } else if(object instanceof RangerService) { + RangerService service = (RangerService)object; + + ret = StringUtils.equals(serviceName, service.getName()); + } else { + ret = true; + } + + return ret; + } + }; + + if(ret != null) { + predicates.add(ret); + } + + return ret; + } + + private Predicate addPredicateForServiceId(final String serviceId, List<Predicate> predicates) { + if(StringUtils.isEmpty(serviceId)) { + return null; + } + + Predicate ret = new Predicate() { + @Override + public boolean evaluate(Object object) { + if(object == null) { + return false; + } + + boolean ret = false; + + if(object instanceof RangerPolicy) { + RangerPolicy policy = (RangerPolicy)object; + Long svcId = getServiceId(policy.getService()); + + if(svcId != null) { + ret = StringUtils.equals(serviceId, svcId.toString()); + } + } else if(object instanceof RangerService) { + RangerService service = (RangerService)object; + + if(service.getId() != null) { + ret = StringUtils.equals(serviceId, service.getId().toString()); + } + } else { + ret = true; + } + + return ret; + } + }; + + if(predicates != null) { + predicates.add(ret); + } + + return ret; + } + + private Predicate addPredicateForPolicyName(final String policyName, List<Predicate> predicates) { + if(StringUtils.isEmpty(policyName)) { + return null; + } + + Predicate ret = new Predicate() { + @Override + public boolean evaluate(Object object) { + if(object == null) { + return false; + } + + boolean ret = false; + + if(object instanceof RangerPolicy) { + RangerPolicy policy = (RangerPolicy)object; + + ret = StringUtils.equals(policyName, policy.getName()); + } else { + ret = true; + } + + return ret; + } + }; + + if(predicates != null) { + predicates.add(ret); + } + + return ret; + } + + private Predicate addPredicateForPolicyId(final String policyId, List<Predicate> predicates) { + if(StringUtils.isEmpty(policyId)) { + return null; + } + + Predicate ret = new Predicate() { + @Override + public boolean evaluate(Object object) { + if(object == null) { + return false; + } + + boolean ret = false; + + if(object instanceof RangerPolicy) { + RangerPolicy policy = (RangerPolicy)object; + + if(policy.getId() != null) { + ret = StringUtils.equals(policyId, policy.getId().toString()); + } + } else { + ret = true; + } + + return ret; + } + }; + + if(predicates != null) { + predicates.add(ret); + } + + return ret; + } + + private Predicate addPredicateForUserName(final String userName, List<Predicate> predicates) { + if(StringUtils.isEmpty(userName)) { + return null; + } + + Predicate ret = new Predicate() { + @Override + public boolean evaluate(Object object) { + if(object == null) { + return false; + } + + boolean ret = false; + + if(object instanceof RangerPolicy) { + RangerPolicy policy = (RangerPolicy)object; + + for(RangerPolicyItem policyItem : policy.getPolicyItems()) { + if(policyItem.getUsers().contains(userName)) { // TODO: group membership check + ret = true; + + break; + } + } + } else { + ret = true; + } + + return ret; + } + }; + + if(predicates != null) { + predicates.add(ret); + } + + return ret; + } + + private Predicate addPredicateForGroupName(final String groupName, List<Predicate> predicates) { + if(StringUtils.isEmpty(groupName)) { + return null; + } + + Predicate ret = new Predicate() { + @Override + public boolean evaluate(Object object) { + if(object == null) { + return false; + } + + boolean ret = false; + + if(object instanceof RangerPolicy) { + RangerPolicy policy = (RangerPolicy)object; + + for(RangerPolicyItem policyItem : policy.getPolicyItems()) { + if(policyItem.getGroups().contains(groupName)) { + ret = true; + + break; + } + } + } else { + ret = true; + } + + return ret; + } + }; + + if(predicates != null) { + predicates.add(ret); + } + + return ret; + } + + private Predicate addPredicateForStatus(final String status, List<Predicate> predicates) { + if(StringUtils.isEmpty(status)) { + return null; + } + + Predicate ret = new Predicate() { + @Override + public boolean evaluate(Object object) { + if(object == null) { + return false; + } + + boolean ret = false; + + if(object instanceof RangerBaseModelObject) { + RangerBaseModelObject obj = (RangerBaseModelObject)object; + + if(StringUtils.equals(status, "enabled")) { + ret = obj.getIsEnabled(); + } else if(StringUtils.equals(status, "disabled")) { + ret = !obj.getIsEnabled(); + } + } else { + ret = true; + } + + return ret; + } + }; + + if(predicates != null) { + predicates.add(ret); + } + + return ret; + } + + private Predicate addPredicateForResources(final Map<String, String> resources, List<Predicate> predicates) { + if(MapUtils.isEmpty(resources)) { + return null; + } + + Predicate ret = new Predicate() { + @Override + public boolean evaluate(Object object) { + if(object == null) { + return false; + } + + boolean ret = false; + + if(object instanceof RangerPolicy) { + RangerPolicy policy = (RangerPolicy)object; + + if(! MapUtils.isEmpty(policy.getResources())) { + int numFound = 0; + for(String name : resources.keySet()) { + boolean isMatch = false; + + RangerPolicyResource policyResource = policy.getResources().get(name); + + if(policyResource != null && !CollectionUtils.isEmpty(policyResource.getValues())) { + String val = resources.get(name); + + if(policyResource.getValues().contains(val)) { + isMatch = true; + } else { + for(String policyResourceValue : policyResource.getValues()) { + if(policyResourceValue.contains(val)) { // TODO: consider match for wildcard in policyResourceValue? + isMatch = true; + break; + } + } + } + } + + if(isMatch) { + numFound++; + } else { + break; + } + } + + ret = numFound == resources.size(); + } + } else { + ret = true; + } + + return ret; + } + }; + + if(predicates != null) { + predicates.add(ret); + } + + return ret; + } +}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java new file mode 100644 index 0000000..dd3624b --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java @@ -0,0 +1,609 @@ +/* + * 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.authorization.hadoop.config.RangerConfiguration; +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.SearchFilter; +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 final String REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED = "/service/plugins/policies/service/name/"; + + public static final String REST_MIME_TYPE_JSON = "application/json" ; + + private RangerRESTClient restClient; + + public ServiceRESTStore() { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.ServiceRESTStore()"); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.ServiceRESTStore()"); + } + } + + @Override + public void init() throws Exception { + String restUrl = RangerConfiguration.getInstance().get("ranger.service.store.rest.url", "http://localhost:6080"); + String restUsername = RangerConfiguration.getInstance().get("ranger.service.store.rest.username", "admin"); + String restPassword = RangerConfiguration.getInstance().get("ranger.service.store.rest.password", "admin"); + String sslConfigFile = RangerConfiguration.getInstance().get("ranger.service.store.rest.ssl.config.file", ""); + + restClient = new RangerRESTClient(restUrl, sslConfigFile); + restClient.setBasicAuthInfo(restUsername, restPassword); + } + + @Override + public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.createServiceDef(" + serviceDef + ")"); + } + + RangerServiceDef ret = null; + + WebResource webResource = createWebResource(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 = createWebResource(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 = createWebResource(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 = createWebResource(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 = createWebResource(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> getServiceDefs(SearchFilter filter) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getServiceDefs()"); + } + + List<RangerServiceDef> ret = null; + + WebResource webResource = createWebResource(REST_URL_SERVICEDEF_GET_ALL, filter); + 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 = createWebResource(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 = createWebResource(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 = createWebResource(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 = createWebResource(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 = createWebResource(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> getServices(SearchFilter filter) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getServices()"); + } + + List<RangerService> ret = null; + + WebResource webResource = createWebResource(REST_URL_SERVICE_GET_ALL, filter); + 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.getServices(): " + ret); + } + + return ret; + } + + @Override + public RangerPolicy createPolicy(RangerPolicy policy) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.createPolicy(" + policy + ")"); + } + + RangerPolicy ret = null; + + WebResource webResource = createWebResource(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 = createWebResource(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 = createWebResource(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 = createWebResource(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> getPolicies(SearchFilter filter) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getPolicies()"); + } + + List<RangerPolicy> ret = null; + + WebResource webResource = createWebResource(REST_URL_POLICY_GET_ALL, filter); + 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.getPolicies(): " + ret); + } + + return ret; + } + + @Override + public List<RangerPolicy> getServicePolicies(Long serviceId, SearchFilter filter) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getServicePolicies(" + serviceId + ")"); + } + + List<RangerPolicy> ret = null; + + WebResource webResource = createWebResource(REST_URL_POLICY_GET_FOR_SERVICE + serviceId, filter); + 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, SearchFilter filter) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getServicePolicies(" + serviceName + ")"); + } + + List<RangerPolicy> ret = null; + + WebResource webResource = createWebResource(REST_URL_POLICY_GET_FOR_SERVICE_BY_NAME + serviceName, filter); + 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 { + if(LOG.isDebugEnabled()) { + LOG.debug("==> ServiceRESTStore.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ")"); + } + + ServicePolicies ret = null; + + WebResource webResource = createWebResource(REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED + serviceName + "/" + lastKnownVersion); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(ServicePolicies.class); + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== ServiceRESTStore.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + "): " + ret); + } + + return ret; + } + + private WebResource createWebResource(String url) { + return createWebResource(url, null); + } + + private WebResource createWebResource(String url, SearchFilter filter) { + WebResource ret = restClient.getResource(url); + + if(filter != null) { + // TODO: add query params for filter + } + + return ret; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java new file mode 100644 index 0000000..7112562 --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java @@ -0,0 +1,154 @@ +/* + * 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.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.plugin.policyengine.RangerPolicyEngine; +import org.apache.ranger.plugin.store.ServiceStore; + + +public class PolicyRefresher extends Thread { + private static final Log LOG = LogFactory.getLog(PolicyRefresher.class); + + private RangerPolicyEngine policyEngine = null; + private String serviceType = null; + private String serviceName = null; + private ServiceStore serviceStore = null; + private long pollingIntervalMs = 30 * 1000; + + private boolean shutdownFlag = false; + private ServicePolicies lastKnownPolicies = null; + + + public PolicyRefresher(RangerPolicyEngine policyEngine, String serviceType, String serviceName, ServiceStore serviceStore, long pollingIntervalMs, String cacheDir) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> PolicyRefresher.PolicyRefresher(serviceName=" + serviceName + ")"); + } + + this.policyEngine = policyEngine; + this.serviceType = serviceType; + this.serviceName = serviceName; + this.serviceStore = serviceStore; + this.pollingIntervalMs = pollingIntervalMs; + + if(LOG.isDebugEnabled()) { + LOG.debug("<== PolicyRefresher.PolicyRefresher(serviceName=" + serviceName + ")"); + } + } + + /** + * @return the policyEngine + */ + public RangerPolicyEngine getPolicyEngine() { + return policyEngine; + } + + /** + * @return the serviceType + */ + public String getServiceType() { + return serviceType; + } + + /** + * @return the serviceName + */ + public String getServiceName() { + return serviceName; + } + + /** + * @return the serviceStore + */ + public ServiceStore getServiceStore() { + return serviceStore; + } + + /** + * @return the pollingIntervalMilliSeconds + */ + public long getPollingIntervalMs() { + return pollingIntervalMs; + } + + /** + * @param pollingIntervalMilliSeconds the pollingIntervalMilliSeconds to set + */ + public void setPollingIntervalMilliSeconds(long pollingIntervalMilliSeconds) { + this.pollingIntervalMs = pollingIntervalMilliSeconds; + } + + public void startRefresher() { + shutdownFlag = false; + + super.start(); + } + + public void stopRefresher() { + shutdownFlag = true; + } + + public void run() { + if(LOG.isDebugEnabled()) { + LOG.debug("==> PolicyRefresher.run()"); + } + + while(! shutdownFlag) { + try { + long lastKnownVersion = (lastKnownPolicies == null || lastKnownPolicies.getPolicyVersion() == null) ? 0 : lastKnownPolicies.getPolicyVersion().longValue(); + + ServicePolicies svcPolicies = serviceStore.getServicePoliciesIfUpdated(serviceName, lastKnownVersion); + + long newVersion = (svcPolicies == null || svcPolicies.getPolicyVersion() == null) ? 0 : svcPolicies.getPolicyVersion().longValue(); + + boolean isUpdated = newVersion != 0 && lastKnownVersion != newVersion; + + if(isUpdated) { + if(LOG.isDebugEnabled()) { + LOG.debug("PolicyRefresher(serviceName=" + serviceName + ").run(): found updated version. lastKnownVersion=" + lastKnownVersion + "; newVersion=" + newVersion); + } + + policyEngine.setPolicies(serviceName, svcPolicies.getServiceDef(), svcPolicies.getPolicies()); + + lastKnownPolicies = svcPolicies; + } else { + if(LOG.isDebugEnabled()) { + LOG.debug("PolicyRefresher(serviceName=" + serviceName + ").run(): no update found. lastKnownVersion=" + lastKnownVersion + "; newVersion=" + newVersion); + } + } + } catch(Exception excp) { + LOG.error("PolicyRefresher(serviceName=" + serviceName + ").run(): ", excp); + } + + try { + Thread.sleep(pollingIntervalMs); + } catch(Exception excp) { + LOG.error("PolicyRefresher(serviceName=" + serviceName + ").run(): error while sleep. exiting thread", excp); + + throw new RuntimeException(excp); + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== PolicyRefresher.run()"); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java new file mode 100644 index 0000000..cfff4b7 --- /dev/null +++ b/agents-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/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java new file mode 100644 index 0000000..ab8384c --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java @@ -0,0 +1,116 @@ +/* + * 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.util.HashMap; +import java.util.Map; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang.StringUtils; + + +public class SearchFilter { + public static final String LOGIN_USER = "loginUser"; // search + public static final String SERVICE_TYPE = "serviceType"; // search, sort + public static final String SERVICE_TYPE_ID = "serviceTypeId"; // search, sort + public static final String SERVICE_NAME = "serviceName"; // search, sort + public static final String SERVICE_ID = "serviceId"; // search, sort + public static final String POLICY_NAME = "policyName"; // search, sort + public static final String POLICY_ID = "policyId"; // search, sort + public static final String STATUS = "status"; // search + public static final String USER = "user"; // search + public static final String GROUP = "group"; // search + public static final String RESOURCE_PREFIX = "resource:"; // search + public static final String CREATE_TIME = "createTime"; // sort + public static final String UPDATE_TIME = "updateTime"; // sort + public static final String START_INDEX = "startIndex"; + public static final String PAGE_SIZE = "pageSize"; + public static final String SORT_BY = "sortBy"; + + private Map<String, String> params = null; + + public SearchFilter() { + this(null); + } + + public SearchFilter(String name, String value) { + setParam(name, value); + } + + public SearchFilter(Map<String, String> values) { + setParams(values); + } + + public Map<String, String> getParams() { + return params; + } + + public void setParams(Map<String, String> params) { + this.params = params; + } + + public String getParam(String name) { + return params == null ? null : params.get(name); + } + + public void setParam(String name, String value) { + if(StringUtils.isEmpty(name) || StringUtils.isEmpty(value)) { + return; + } + + if(params == null) { + params = new HashMap<String, String>(); + } + + params.put(name, value); + } + + public Map<String, String> getParamsWithPrefix(String prefix, boolean stripPrefix) { + Map<String, String> ret = null; + + if(prefix == null) { + prefix = StringUtils.EMPTY; + } + + if(params != null) { + for(Map.Entry<String, String> e : params.entrySet()) { + String name = e.getKey(); + + if(name.startsWith(prefix)) { + if(ret == null) { + ret = new HashMap<String, String>(); + } + + if(stripPrefix) { + name = name.substring(prefix.length()); + } + + ret.put(name, e.getValue()); + } + } + } + + return ret; + } + + public boolean isEmpty() { + return MapUtils.isEmpty(params); + } +}
