RANGER-203: PolicyResource updated with addition of attributes matcher and matcherOptions - to enable pluggable resource comparators (string, path,..). Updated resources in legacy service-def with appropriate matcher specification. Added Path and Default resource matchers, which are used in legacy service-def
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/8928c2e5 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/8928c2e5 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/8928c2e5 Branch: refs/heads/stack Commit: 8928c2e59ffc7881cea588c66188d7e9a88243d3 Parents: 033e4ec Author: Madhan Neethiraj <[email protected]> Authored: Sat Dec 20 13:45:17 2014 -0800 Committer: Madhan Neethiraj <[email protected]> Committed: Wed Jan 7 11:18:37 2015 -0800 ---------------------------------------------------------------------- .../ranger/plugin/model/RangerServiceDef.java | 38 ++++- .../RangerDefaultResourceMatcher.java | 113 +++++++++++++++ .../policyengine/RangerPathResourceMatcher.java | 137 +++++++++++++++++++ .../policyengine/RangerResourceMatcher.java | 32 +++++ .../service-defs/ranger-servicedef-hbase.json | 6 +- .../service-defs/ranger-servicedef-hdfs.json | 2 +- .../service-defs/ranger-servicedef-hive.json | 8 +- .../service-defs/ranger-servicedef-knox.json | 4 +- .../service-defs/ranger-servicedef-storm.json | 2 +- 9 files changed, 329 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8928c2e5/plugin-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java b/plugin-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java index 524abea..5f8cf22 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java @@ -713,6 +713,8 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S private Boolean lookupSupported = null; private Boolean recursiveSupported = null; private Boolean excludesSupported = null; + private String matcher = null; + private String matcherOptions = null; private String label = null; private String description = null; private String rbKeyLabel = null; @@ -720,10 +722,10 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S public RangerResourceDef() { - this(null, null, null, null, null, null, null, null, null, null, null); + this(null, null, null, null, null, null, null, null, null, null, null, null, null); } - public RangerResourceDef(String name, Integer level, String parent, Boolean mandatory, Boolean lookupSupported, Boolean recursiveSupported, Boolean excludesSupported, String label, String description, String rbKeyLabel, String rbKeyDescription) { + public RangerResourceDef(String name, Integer level, String parent, Boolean mandatory, Boolean lookupSupported, Boolean recursiveSupported, Boolean excludesSupported, String matcher, String matcherOptions, String label, String description, String rbKeyLabel, String rbKeyDescription) { setName(name); setLevel(level); setParent(parent); @@ -731,6 +733,8 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S setLookupSupported(lookupSupported); setRecursiveSupported(recursiveSupported); setExcludesSupported(excludesSupported); + setMatcher(matcher); + setMatcher(matcherOptions); setLabel(label); setDescription(description); setRbKeyLabel(rbKeyLabel); @@ -836,6 +840,34 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S } /** + * @return the matcher + */ + public String getMatcher() { + return matcher; + } + + /** + * @param matcher the matcher to set + */ + public void setMatcher(String matcher) { + this.matcher = matcher; + } + + /** + * @return the matcher + */ + public String getMatcherOptions() { + return matcherOptions; + } + + /** + * @param matcher the matcher to set + */ + public void setMatcherOptions(String matcherOptions) { + this.matcherOptions = matcherOptions; + } + + /** * @return the label */ public String getLabel() { @@ -909,6 +941,8 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S sb.append("lookupSupported={").append(lookupSupported).append("} "); sb.append("recursiveSupported={").append(recursiveSupported).append("} "); sb.append("excludesSupported={").append(excludesSupported).append("} "); + sb.append("matcher={").append(matcher).append("} "); + sb.append("matcherOptions={").append(matcherOptions).append("} "); sb.append("label={").append(label).append("} "); sb.append("description={").append(description).append("} "); sb.append("rbKeyLabel={").append(rbKeyLabel).append("} "); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8928c2e5/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDefaultResourceMatcher.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDefaultResourceMatcher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDefaultResourceMatcher.java new file mode 100644 index 0000000..735b5b9 --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDefaultResourceMatcher.java @@ -0,0 +1,113 @@ +/* + * 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.policyengine; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; + +public class RangerDefaultResourceMatcher implements RangerResourceMatcher { + private List<String> policyValues = null; + private boolean policyIsExcludes = false; + private boolean optIgnoreCase = false; + private boolean optWildCard = false; + + @Override + public void init(RangerPolicyResource policyResource, String options) { + this.policyValues = new ArrayList<String>(); + this.policyIsExcludes = false; + this.optIgnoreCase = false; + this.optWildCard = false; + + if(options != null) { + for(String optionStr : options.split(OPTIONS_SEP)) { + if(optionStr == null) { + continue; + } + optionStr = optionStr.trim(); + + if(!optionStr.isEmpty()) { + String[] optionArr = optionStr.split("="); + + String optionName = optionArr.length > 0 ? optionArr[0].trim() : null; + String optionValue = optionArr.length > 1 ? optionArr[1].trim() : null; + + if(optionName == null) { + continue; + } + + if(optionName.equals(OPTION_IGNORE_CASE)) { + optIgnoreCase = (optionValue == null || optionValue.isEmpty()) ? true : Boolean.parseBoolean(optionValue); + } else if(optionName.equals(OPTION_WILD_CARD)) { + optWildCard = (optionValue == null || optionValue.isEmpty()) ? true : Boolean.parseBoolean(optionValue); + } else { + // log warning: unrecognized option.. + } + } + } + } + + + if(policyResource != null) { + policyIsExcludes = policyResource.getIsExcludes(); + + if(policyResource.getValues() != null && !policyResource.getValues().isEmpty()) { + for(String policyValue : policyResource.getValues()) { + if(policyValue == null) { + continue; + } + + if(optIgnoreCase) { + policyValue = policyValue.toLowerCase(); + } + + policyValues.add(policyValue); + } + } + } + } + + @Override + public boolean isMatch(String value) { + boolean ret = false; + + if(value != null) { + if(optIgnoreCase) { + value = value.toLowerCase(); + } + + for(String policyValue : policyValues) { + ret = optWildCard ? value.matches(policyValue) : value.equals(policyValue); + + if(ret) { + break; + } + } + } + + if(policyIsExcludes) { + ret = !ret; + } + + return ret; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8928c2e5/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPathResourceMatcher.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPathResourceMatcher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPathResourceMatcher.java new file mode 100644 index 0000000..67e1887 --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPathResourceMatcher.java @@ -0,0 +1,137 @@ +/* + * 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.policyengine; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.FilenameUtils; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; + +public class RangerPathResourceMatcher implements RangerResourceMatcher { + private List<String> policyValues = null; + private boolean policyIsExcludes = false; + private boolean policyIsRecursive = false; + private boolean optIgnoreCase = false; + private boolean optWildCard = false; + + @Override + public void init(RangerPolicyResource policyResource, String options) { + this.policyValues = new ArrayList<String>(); + this.policyIsExcludes = false; + this.policyIsRecursive = false; + this.optIgnoreCase = false; + this.optWildCard = false; + + if(options != null) { + for(String optionStr : options.split(OPTIONS_SEP)) { + if(optionStr == null) { + continue; + } + optionStr = optionStr.trim(); + + if(!optionStr.isEmpty()) { + String[] optionArr = optionStr.split("="); + + String optionName = optionArr.length > 0 ? optionArr[0].trim() : null; + String optionValue = optionArr.length > 1 ? optionArr[1].trim() : null; + + if(optionName == null) { + continue; + } + + if(optionName.equals(OPTION_IGNORE_CASE)) { + optIgnoreCase = (optionValue == null || optionValue.isEmpty()) ? true : Boolean.parseBoolean(optionValue); + } else if(optionName.equals(OPTION_WILD_CARD)) { + optWildCard = (optionValue == null || optionValue.isEmpty()) ? true : Boolean.parseBoolean(optionValue); + } else { + // log warning: unrecognized option.. + } + } + } + } + + if(policyResource != null) { + policyIsExcludes = policyResource.getIsExcludes(); + policyIsRecursive = policyResource.getIsRecursive(); + + if(policyResource.getValues() != null && !policyResource.getValues().isEmpty()) { + for(String policyValue : policyResource.getValues()) { + if(policyValue == null) { + continue; + } + + if(optIgnoreCase) { + policyValue = policyValue.toLowerCase(); + } + + policyValues.add(policyValue); + } + } + } + } + + @Override + public boolean isMatch(String value) { + boolean ret = false; + + if(value != null) { + if(optIgnoreCase) { + value = value.toLowerCase(); + } + + for(String policyValue : policyValues) { + if(policyIsRecursive) { + ret = optWildCard ? isRecursiveWildCardMatch(value, policyValue) : value.startsWith(policyValue); + } else { + ret = optWildCard ? FilenameUtils.wildcardMatch(value, policyValue) : value.equals(policyValue); + } + + if(ret) { + break; + } + } + } + + if(policyIsExcludes) { + ret = !ret; + } + + return ret; + } + + private static boolean isRecursiveWildCardMatch(String pathToCheck, String wildcardPath) { + if (pathToCheck != null) { + StringBuilder sb = new StringBuilder() ; + for(String p : pathToCheck.split(File.separator) ) { + sb.append(p) ; + boolean matchFound = FilenameUtils.wildcardMatch(sb.toString(), wildcardPath) ; + if (matchFound) { + return true ; + } + sb.append(File.separator) ; + } + sb = null; + } + return false; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8928c2e5/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceMatcher.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceMatcher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceMatcher.java new file mode 100644 index 0000000..bfe3605 --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceMatcher.java @@ -0,0 +1,32 @@ +/* + * 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.policyengine; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; + +public interface RangerResourceMatcher { + public final String OPTIONS_SEP = ";"; + public final String OPTION_IGNORE_CASE = "ignoreCase"; + public final String OPTION_WILD_CARD = "wildCard"; + + void init(RangerPolicyResource policyResource, String options); + + boolean isMatch(String value); +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8928c2e5/plugin-common/src/main/resources/service-defs/ranger-servicedef-hbase.json ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/resources/service-defs/ranger-servicedef-hbase.json b/plugin-common/src/main/resources/service-defs/ranger-servicedef-hbase.json index 10b84bb..5f06235 100644 --- a/plugin-common/src/main/resources/service-defs/ranger-servicedef-hbase.json +++ b/plugin-common/src/main/resources/service-defs/ranger-servicedef-hbase.json @@ -33,9 +33,9 @@ ], "resources": [ - {"name":"table","level":1,"parent":"","mandatory":true,"lookupSupported":true,"label":"HBase Table","description":"HBase Table"}, - {"name":"column-family","level":2,"parent":"table","mandatory":true,"lookupSupported":true,"label":"HBase Column-family","description":"HBase Column-family"}, - {"name":"column","level":3,"parent":"column-family","mandatory":true,"lookupSupported":false,"label":"HBase Column","description":"HBase Column"} + {"name":"table","level":1,"parent":"","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.policyengine.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"HBase Table","description":"HBase Table"}, + {"name":"column-family","level":2,"parent":"table","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.policyengine.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"HBase Column-family","description":"HBase Column-family"}, + {"name":"column","level":3,"parent":"column-family","mandatory":true,"lookupSupported":false,"matcher":"org.apache.ranger.plugin.policyengine.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"HBase Column","description":"HBase Column"} ], "accessTypes": [ http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8928c2e5/plugin-common/src/main/resources/service-defs/ranger-servicedef-hdfs.json ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/resources/service-defs/ranger-servicedef-hdfs.json b/plugin-common/src/main/resources/service-defs/ranger-servicedef-hdfs.json index f8a90a2..193932e 100644 --- a/plugin-common/src/main/resources/service-defs/ranger-servicedef-hdfs.json +++ b/plugin-common/src/main/resources/service-defs/ranger-servicedef-hdfs.json @@ -45,7 +45,7 @@ ], "resources": [ - {"name":"path","level":1,"mandatory":true,"lookupSupported":true,"label":"Resource Path","description":"HDFS file or directory path"} + {"name":"path","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.policyengine.RangerPathResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"Resource Path","description":"HDFS file or directory path"} ], "accessTypes": [ http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8928c2e5/plugin-common/src/main/resources/service-defs/ranger-servicedef-hive.json ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/resources/service-defs/ranger-servicedef-hive.json b/plugin-common/src/main/resources/service-defs/ranger-servicedef-hive.json index c6df80c..ca388ef 100644 --- a/plugin-common/src/main/resources/service-defs/ranger-servicedef-hive.json +++ b/plugin-common/src/main/resources/service-defs/ranger-servicedef-hive.json @@ -21,10 +21,10 @@ ], "resources": [ - {"name":"database","level":1,"mandatory":true,"lookupSupported":true,"label":"Hive Database","description":"Hive Database"}, - {"name":"table","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"label":"Hive Table","description":"Hive Table"}, - {"name":"udf","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"label":"Hive UDF","description":"Hive UDF"}, - {"name":"column","level":3,"parent":"table","mandatory":true,"lookupSupported":true,"label":"Hive Column","description":"Hive Column"} + {"name":"database","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.policyengine.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"Hive Database","description":"Hive Database"}, + {"name":"table","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.policyengine.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"Hive Table","description":"Hive Table"}, + {"name":"udf","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.policyengine.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"Hive UDF","description":"Hive UDF"}, + {"name":"column","level":3,"parent":"table","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.policyengine.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"Hive Column","description":"Hive Column"} ], "accessTypes": [ http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8928c2e5/plugin-common/src/main/resources/service-defs/ranger-servicedef-knox.json ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/resources/service-defs/ranger-servicedef-knox.json b/plugin-common/src/main/resources/service-defs/ranger-servicedef-knox.json index 81621e6..a9afe42 100644 --- a/plugin-common/src/main/resources/service-defs/ranger-servicedef-knox.json +++ b/plugin-common/src/main/resources/service-defs/ranger-servicedef-knox.json @@ -20,8 +20,8 @@ ], "resources": [ - {"name":"topology","level":1,"mandatory":true,"lookupSupported":true,"label":"Knox Topology","description":"Knox Topology"}, - {"name":"service","level":2,"parent":"topology","mandatory":true,"lookupSupported":true,"label":"Knox Service","description":"Knox Service"} + {"name":"topology","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.policyengine.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"Knox Topology","description":"Knox Topology"}, + {"name":"service","level":2,"parent":"topology","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.policyengine.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"Knox Service","description":"Knox Service"} ], "accessTypes": [ http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8928c2e5/plugin-common/src/main/resources/service-defs/ranger-servicedef-storm.json ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/resources/service-defs/ranger-servicedef-storm.json b/plugin-common/src/main/resources/service-defs/ranger-servicedef-storm.json index ed10459..db69dbb 100644 --- a/plugin-common/src/main/resources/service-defs/ranger-servicedef-storm.json +++ b/plugin-common/src/main/resources/service-defs/ranger-servicedef-storm.json @@ -20,7 +20,7 @@ ], "resources": [ - {"name":"topology","level":1,"mandatory":true,"lookupSupported":true,"label":"Storm Topology","description":"Storm Topology"} + {"name":"topology","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.policyengine.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"Storm Topology","description":"Storm Topology"} ], "accessTypes": [
