This is an automated email from the ASF dual-hosted git repository.
dineshkumar-yadav pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 37b6e02c4 RANGER-5687: Add feature flag to artifacts for RANGER-5628
(#1073)
37b6e02c4 is described below
commit 37b6e02c4d3b989790bbd669b7d5d4366f7f7644
Author: fmorg-git <[email protected]>
AuthorDate: Mon Jul 20 02:25:51 2026 -0700
RANGER-5687: Add feature flag to artifacts for RANGER-5628 (#1073)
* add feature flag to artifacts for RANGER-5628
* bug fixes - missing flag on patch and if flag is on and condition set on
resource policy, then flag is off, ui hangs
(cherry picked from commit e25cdb00df8ca54a75bb998863ede76e8d52148f)
* fix checkstyle issue
(cherry picked from commit d06e4049a352ee3caad45a561098a7031ada557f)
* Confine Ozone action-policy gating to plugin-ozone module.
Move enableOzoneActionPolicy handling out of RangerInlinePolicyEvaluator
into RangerOzoneAuthorizer, including legacy session-policy sanitization
and a unit test for flag-off behavior with embedded grant actions.
* RANGER-5687: read ozone action-policy flag without agents-common changes.
Use ServiceDefUtil.getBooleanValue in plugin-ozone and security-admin per
PR review, and revert agents-common ozone-specific additions.
* Scope action-matcher option to ozone service-def only.
Rename enableOzoneActionPolicy to enableActionMatcherInPoliciesCondition and
admin config to
ranger.servicedef.ozone.enableActionMatcherInPoliciesCondition.
Non-ozone service defs always get false; ozone reads site config.
Addresses PR review from fimugdha.
* fix checkstyle issues
* remove agents-common modification per mneethiraj and address fimugdha
comments
* Persist ozone action-matcher flag in J10065 def_options upgrade.
On upgrade, sync enableActionMatcherInPoliciesCondition from admin config
into ozone def_options only, alongside existing policyConditions updates for
action-matches.
* Add ozone action-matcher docker flag and align J10065 def_options sync.
Wire RANGER_OZONE_ENABLE_ACTION_MATCHER into ranger-docker so admin setup
reads the flag before J10065 runs, fix the def_options constant, and update
patch unit tests after E2E validation on Mac with fresh Postgres installs.
* Simplify ozone docker flag script and restore generic BUILD_OPTS.
Use update_property.py from the admin tarball instead of inline Python,
and keep BUILD_OPTS empty so ranger-docker builds remain full by default.
* Fix ImportOrder checkstyle violation in J10065 patch.
* Make ozone action-matcher flag follow admin config at runtime.
Stale def_options from an earlier J10065 run or the pre-rename
enableOzoneActionPolicy
option could override
ranger.servicedef.ozone.enableActionMatcherInPoliciesCondition,
hiding action-matches in Admin UI and ozone authorizer even when the flag
was set true.
Admin config is now authoritative when serving the ozone service-def, and
action-matches
is restored from the embedded def when enabled but missing from DB.
* Remove legacy enableOzoneActionPolicy handling.
The renamed enableActionMatcherInPoliciesCondition option and admin runtime
overlay make enableOzoneActionPolicy obsolete for 3.0.
* pr review comment for mneethiraj - don't automatically disable
action-matches for non-Ozone service definition
* pr review comments for mneethiraj - don't reference feature flag in ui
* pr review comment for mneethiraj - revert updates to patch
* pr review comment for mneethiraj - rename
PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION to
PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE
* add clarification statement for docker
* Update RangerOzoneAuthorizer.java
* pr review update for mneethiraj - revamp Docker handling
* remove no longer valid unit test
* renamed FF_ENAB_OZONE_ACTION_MATCHES_CONDITION to
FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION
---------
Co-authored-by: Fabian Morgan <[email protected]>
Co-authored-by: ramk <[email protected]>
Co-authored-by: Madhan Neethiraj <[email protected]>
---
dev-support/ranger-docker/.env | 2 +-
dev-support/ranger-docker/README.md | 46 ++++++++
.../admin/ranger-admin-install-mysql.properties | 3 +
.../admin/ranger-admin-install-oracle.properties | 3 +
.../admin/ranger-admin-install-postgres.properties | 3 +
.../ranger-admin-install-sqlserver.properties | 3 +
.../ozone/authorizer/RangerOzoneAuthorizer.java | 43 ++++++-
.../authorizer/TestRangerOzoneAuthorizer.java | 131 +++++++++++++++++++++
security-admin/scripts/install.properties | 3 +
security-admin/scripts/setup.sh | 11 ++
.../ranger/service/RangerServiceDefService.java | 112 ++++++++++++++++++
.../conf.dist/ranger-admin-default-site.xml | 8 ++
.../main/resources/conf.dist/ranger-admin-site.xml | 4 +
.../main/webapp/react-webapp/src/utils/XAUtils.js | 2 +-
.../views/GovernedData/Dataset/AccessGrantForm.jsx | 6 +-
.../views/PolicyListing/AddUpdatePolicyForm.jsx | 12 +-
.../service/TestRangerServiceDefService.java | 116 +++++++++++++++++-
17 files changed, 493 insertions(+), 15 deletions(-)
diff --git a/dev-support/ranger-docker/.env b/dev-support/ranger-docker/.env
index 8ca362eab..c6439db0e 100644
--- a/dev-support/ranger-docker/.env
+++ b/dev-support/ranger-docker/.env
@@ -6,7 +6,7 @@ PROFILE=
BUILD_OPTS=
# Java Opts Configuration in JDK17
-JAVA_OPTS=--add-opens=java.base/java.nio=ALL-UNNAMED
--add-exports=java.base/sun.net.dns=ALL-UNNAMED
--add-exports=java.base/sun.net.util=ALL-UNNAMED
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-exports=java.base/java.util.logging=ALL-UNNAMED
--add-opens=java.base/java.io=ALL-UNNAMED
+JAVA_OPTS="--add-opens=java.base/java.nio=ALL-UNNAMED
--add-exports=java.base/sun.net.dns=ALL-UNNAMED
--add-exports=java.base/sun.net.util=ALL-UNNAMED
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-exports=java.xml.crypto/com.sun.org.apache.xml.internal.security.utils=ALL-UNNAMED"
# DockerHub Ranger Base Image
RANGER_BASE_IMAGE=apache/ranger-base
diff --git a/dev-support/ranger-docker/README.md
b/dev-support/ranger-docker/README.md
index 1ddd9c3fd..4c09881c5 100644
--- a/dev-support/ranger-docker/README.md
+++ b/dev-support/ranger-docker/README.md
@@ -94,10 +94,56 @@ docker compose -f docker-compose.ranger.yml -f
docker-compose.ranger-hadoop.yml
docker compose -f docker-compose.ranger.yml -f
docker-compose.ranger-hadoop.yml -f docker-compose.ranger-hbase.yml up -d
~~~
#### Bring up ozone containers
+
+##### Ozone action-matcher feature flag
+
+The flag is controlled at runtime by
+`ranger.servicedef.ozone.enableActionMatcherInPoliciesCondition` in
+`ranger-admin-site.xml`. Docker maps it from
+`FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION` in
+`scripts/admin/ranger-admin-install-*.properties` during Admin setup.
+
+**Prerequisite:** the admin distribution must include an uncommented property
+entry in `conf.dist/ranger-admin-site.xml`. Rebuild dist before building the
+Admin image:
+
+~~~
+docker compose -f docker-compose.ranger-build.yml build
+docker compose -f docker-compose.ranger-build.yml up
+~~~
+
+**First-time setup:** set `FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION=true` in
+`scripts/admin/ranger-admin-install-<db>.properties`, then bring up services.
+
+**Changing the flag later** (choose one):
+
+1. Edit `FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION` in
+ `scripts/admin/ranger-admin-install-<db>.properties` and recreate Admin so
+ setup runs again:
+ ~~~
+ docker compose -f docker-compose.ranger.yml -f
docker-compose.ranger-ozone.yml \
+ up -d --build --force-recreate ranger
+ ~~~
+ Works even if the DB already exists; setup re-runs on a fresh container.
+
+2. Edit the live value in the container's
+ `ranger-admin-site.xml` and restart Admin.
+
+`install.properties` is not re-read on restart alone — only when setup runs.
+`RangerServiceDefService` applies the site.xml value when serving the ozone
+service-def.
+
~~~
./scripts/ozone/ozone-plugin-docker-setup.sh
docker compose -f docker-compose.ranger.yml -f docker-compose.ranger-ozone.yml
up -d
~~~
+
+Verify (after login):
+
+~~~
+curl -s -u admin:rangerR0cks!
http://localhost:6080/service/plugins/definitions/name/ozone \
+ | python3 -c "import json,sys; d=json.load(sys.stdin); print('options',
d.get('options')); print('conditions', [c['name'] for c in
d.get('policyConditions',[])])"
+~~~
#### Bring up trino container (requires docker build with jdk 11):
~~~
docker compose -f docker-compose.ranger.yml -f docker-compose.ranger-trino.yml
up -d
diff --git
a/dev-support/ranger-docker/scripts/admin/ranger-admin-install-mysql.properties
b/dev-support/ranger-docker/scripts/admin/ranger-admin-install-mysql.properties
index 18a4c8da7..14b4330ad 100644
---
a/dev-support/ranger-docker/scripts/admin/ranger-admin-install-mysql.properties
+++
b/dev-support/ranger-docker/scripts/admin/ranger-admin-install-mysql.properties
@@ -59,6 +59,9 @@ audit_elasticsearch_bootstrap_enabled=true
policymgr_external_url=http://ranger-admin:6080
policymgr_http_enabled=true
+# Enable Ozone action-matches policy condition (maps to ranger-admin-site.xml
at setup)
+FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION=false
+
unix_user=ranger
unix_user_pwd=ranger
unix_group=ranger
diff --git
a/dev-support/ranger-docker/scripts/admin/ranger-admin-install-oracle.properties
b/dev-support/ranger-docker/scripts/admin/ranger-admin-install-oracle.properties
index 22b177c02..4748dc0dc 100644
---
a/dev-support/ranger-docker/scripts/admin/ranger-admin-install-oracle.properties
+++
b/dev-support/ranger-docker/scripts/admin/ranger-admin-install-oracle.properties
@@ -61,6 +61,9 @@ audit_elasticsearch_bootstrap_enabled=true
policymgr_external_url=http://ranger-admin:6080
policymgr_http_enabled=true
+# Enable Ozone action-matches policy condition (maps to ranger-admin-site.xml
at setup)
+FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION=false
+
unix_user=ranger
unix_user_pwd=ranger
unix_group=ranger
diff --git
a/dev-support/ranger-docker/scripts/admin/ranger-admin-install-postgres.properties
b/dev-support/ranger-docker/scripts/admin/ranger-admin-install-postgres.properties
index fc8e8682a..80c18df4e 100644
---
a/dev-support/ranger-docker/scripts/admin/ranger-admin-install-postgres.properties
+++
b/dev-support/ranger-docker/scripts/admin/ranger-admin-install-postgres.properties
@@ -74,6 +74,9 @@ audit_opensearch_bootstrap_enabled=true
policymgr_external_url=http://ranger-admin:6080
policymgr_http_enabled=true
+# Enable Ozone action-matches policy condition (maps to ranger-admin-site.xml
at setup)
+FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION=false
+
unix_user=ranger
unix_user_pwd=ranger
unix_group=ranger
diff --git
a/dev-support/ranger-docker/scripts/admin/ranger-admin-install-sqlserver.properties
b/dev-support/ranger-docker/scripts/admin/ranger-admin-install-sqlserver.properties
index 8a1919374..40f77c3fd 100644
---
a/dev-support/ranger-docker/scripts/admin/ranger-admin-install-sqlserver.properties
+++
b/dev-support/ranger-docker/scripts/admin/ranger-admin-install-sqlserver.properties
@@ -68,6 +68,9 @@ audit_elasticsearch_bootstrap_enabled=true
policymgr_external_url=http://ranger-admin:6080
policymgr_http_enabled=true
+# Enable Ozone action-matches policy condition (maps to ranger-admin-site.xml
at setup)
+FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION=false
+
unix_user=ranger
unix_user_pwd=ranger
unix_group=ranger
diff --git
a/plugin-ozone/src/main/java/org/apache/ranger/authorization/ozone/authorizer/RangerOzoneAuthorizer.java
b/plugin-ozone/src/main/java/org/apache/ranger/authorization/ozone/authorizer/RangerOzoneAuthorizer.java
index f7d61fec2..95094bd10 100644
---
a/plugin-ozone/src/main/java/org/apache/ranger/authorization/ozone/authorizer/RangerOzoneAuthorizer.java
+++
b/plugin-ozone/src/main/java/org/apache/ranger/authorization/ozone/authorizer/RangerOzoneAuthorizer.java
@@ -41,6 +41,7 @@
import org.apache.ranger.plugin.service.RangerBasePlugin;
import org.apache.ranger.plugin.util.JsonUtilsV2;
import org.apache.ranger.plugin.util.RangerPerfTracer;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -74,6 +75,8 @@ public class RangerOzoneAuthorizer implements
IAccessAuthorizer {
private static final String S3_VOLUME_NAME = "s3Vol";
+ private static final String
OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION =
"enableActionMatcherInPoliciesCondition";
+
private static volatile RangerBasePlugin rangerPlugin;
public RangerOzoneAuthorizer() {
@@ -168,7 +171,11 @@ public boolean checkAccess(IOzoneObj ozoneObject,
RequestContext context) {
rangerResource.setOwnerUser(context.getOwnerName());
rangerRequest.setResource(rangerResource);
rangerRequest.setAccessType(accessType);
- rangerRequest.setAction(context.getS3Action());
+ if (isOzoneActionPolicyEnabled(plugin)) {
+ rangerRequest.setAction(context.getS3Action());
+ } else {
+ rangerRequest.setAction(accessType);
+ }
rangerRequest.setRequestData(resource);
rangerRequest.setClusterName(clusterName);
@@ -192,7 +199,8 @@ public boolean checkAccess(IOzoneObj ozoneObject,
RequestContext context) {
try {
if (StringUtils.isNotBlank(context.getSessionPolicy())) {
-
rangerRequest.setInlinePolicy(JsonUtilsV2.jsonToObj(context.getSessionPolicy(),
RangerInlinePolicy.class));
+ RangerInlinePolicy inlinePolicy =
JsonUtilsV2.jsonToObj(context.getSessionPolicy(), RangerInlinePolicy.class);
+
rangerRequest.setInlinePolicy(sanitizeInlinePolicyForActionFlag(inlinePolicy,
plugin));
}
RangerAccessResult result = plugin.isAccessAllowed(rangerRequest);
@@ -313,9 +321,12 @@ private static RangerInlinePolicy.Grant
toRangerGrant(OzoneGrant ozoneGrant, Ran
ret.setPermissions(ozoneGrant.getPermissions().stream().map(RangerOzoneAuthorizer::toRangerPermission).filter(Objects::nonNull).collect(Collectors.toSet()));
}
- final Set<String> s3Actions = ozoneGrant.getS3Actions();
- if (s3Actions != null && !s3Actions.isEmpty()) {
- ret.setActions(s3Actions);
+ if (isOzoneActionPolicyEnabled(plugin)) {
+ final Set<String> s3Actions = ozoneGrant.getS3Actions();
+
+ if (s3Actions != null && !s3Actions.isEmpty()) {
+ ret.setActions(s3Actions);
+ }
}
LOG.debug("toRangerGrant(ozoneGrant={}): ret={}", ozoneGrant, ret);
@@ -384,4 +395,26 @@ private static String toRangerPermission(ACLType acl) {
return null;
}
+
+ private static boolean isOzoneActionPolicyEnabled(final RangerBasePlugin
plugin) {
+ return plugin != null
+ && plugin.getServiceDef() != null
+ &&
ServiceDefUtil.getBooleanValue(plugin.getServiceDef().getOptions(),
OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION, false);
+ }
+
+ /**
+ * When action-policy is disabled, strip grant actions so generic inline
evaluation
+ * does not enforce S3 actions (same effect as omitting actions in {@link
#toRangerGrant}).
+ */
+ static RangerInlinePolicy
sanitizeInlinePolicyForActionFlag(RangerInlinePolicy policy, RangerBasePlugin
plugin) {
+ if (policy != null && policy.getGrants() != null &&
!isOzoneActionPolicyEnabled(plugin)) {
+ for (RangerInlinePolicy.Grant grant : policy.getGrants()) {
+ if (grant != null) {
+ grant.setActions(null);
+ }
+ }
+ }
+
+ return policy;
+ }
}
diff --git
a/plugin-ozone/src/test/java/org/apache/ranger/authorization/ozone/authorizer/TestRangerOzoneAuthorizer.java
b/plugin-ozone/src/test/java/org/apache/ranger/authorization/ozone/authorizer/TestRangerOzoneAuthorizer.java
index a715e9c6f..7a90e758d 100644
---
a/plugin-ozone/src/test/java/org/apache/ranger/authorization/ozone/authorizer/TestRangerOzoneAuthorizer.java
+++
b/plugin-ozone/src/test/java/org/apache/ranger/authorization/ozone/authorizer/TestRangerOzoneAuthorizer.java
@@ -37,7 +37,9 @@
import java.net.InetAddress;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -53,8 +55,10 @@ public class TestRangerOzoneAuthorizer {
private static final String RANGER_APP_ID = "om";
private static final String OZONE_SERVICE_ID = "om";
private static final String OWNER_NAME = "ozone";
+ private static final String
OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION =
"enableActionMatcherInPoliciesCondition";
private static RangerOzoneAuthorizer ozoneAuthorizer;
+ private static RangerBasePlugin testPlugin;
private final String hostname = "localhost";
private final InetAddress ipAddress =
InetAddress.getLoopbackAddress();
@@ -85,7 +89,9 @@ public static void setUpBeforeClass() {
// loads policies from om_dev_ozone.json, by
EmbeddedResourcePolicySource configured in ranger-ozone-security.xml
plugin.init();
+ setOzoneActionPolicyEnabled(plugin);
+ testPlugin = plugin;
ozoneAuthorizer = new RangerOzoneAuthorizer(plugin);
assertNotNull(ozoneAuthorizer);
@@ -273,4 +279,129 @@ public void testCheckAccessWithS3Action() throws
Exception {
assertFalse(ozoneAuthorizer.checkAccess(key1, ctxWriteNoAction),
"session-policy should deny write on key1 when no S3 action is
specified and grant has S3 actions");
}
+
+ @Test
+ public void testAssumeRoleWithS3ActionsNotPropagatedWhenFlagDisabled()
throws Exception {
+ final String previous = setOzoneActionPolicyDisabled();
+
+ try {
+ final Set<OzoneGrant> grants =
Collections.singleton(grantWriteWithS3Actions);
+ final AssumeRoleRequest request = new AssumeRoleRequest(hostname,
ipAddress, user1, role1, grants);
+
+ final String sessionPolicy =
ozoneAuthorizer.generateAssumeRoleSessionPolicy(request);
+
+ assertNotNull(sessionPolicy);
+
+ final RangerInlinePolicy inlinePolicy =
JsonUtilsV2.jsonToObj(sessionPolicy, RangerInlinePolicy.class);
+ final RangerInlinePolicy.Grant grant =
inlinePolicy.getGrants().iterator().next();
+
+ assertNull(grant.getActions(), "S3 actions should not be
propagated when ozone action policy is disabled");
+ } finally {
+ restoreOzoneActionPolicyEnabled(previous);
+ }
+ }
+
+ @Test
+ public void testCheckAccessIgnoresS3ActionWhenFlagDisabled() throws
Exception {
+ final String previous = setOzoneActionPolicyDisabled();
+
+ try {
+ final Set<OzoneGrant> grants =
Collections.singleton(grantWriteWithS3Actions);
+ final AssumeRoleRequest request = new AssumeRoleRequest(hostname,
ipAddress, user1, role1, grants);
+
+ final String sessionPolicy =
ozoneAuthorizer.generateAssumeRoleSessionPolicy(request);
+
+ assertNotNull(sessionPolicy);
+
+ final RequestContext ctxWriteGetObject = reqCtxBuilder
+ .setAclRights(IAccessAuthorizer.ACLType.WRITE)
+ .setRecursiveAccessCheck(false)
+ .setSessionPolicy(sessionPolicy)
+ .setS3Action("GetObject")
+ .build();
+
+ assertTrue(ozoneAuthorizer.checkAccess(key1, ctxWriteGetObject),
+ "session-policy should allow write when S3 action
enforcement is disabled");
+
+ final RequestContext ctxWriteNoAction = reqCtxBuilder
+ .setAclRights(IAccessAuthorizer.ACLType.WRITE)
+ .setRecursiveAccessCheck(false)
+ .setSessionPolicy(sessionPolicy)
+ .setS3Action(null)
+ .build();
+
+ assertTrue(ozoneAuthorizer.checkAccess(key1, ctxWriteNoAction),
+ "session-policy should allow write when S3 action
enforcement is disabled");
+ } finally {
+ restoreOzoneActionPolicyEnabled(previous);
+ }
+ }
+
+ @Test
+ public void testLegacySessionPolicyActionsStrippedWhenFlagDisabled()
throws Exception {
+ // Simulate a session policy issued when action-policy was enabled
(actions embedded in JSON).
+ Set<OzoneGrant> grants =
Collections.singleton(grantWriteWithS3Actions);
+ AssumeRoleRequest request = new AssumeRoleRequest(hostname, ipAddress,
user1, role1, grants);
+
+ String legacySessionPolicy =
ozoneAuthorizer.generateAssumeRoleSessionPolicy(request);
+
+ RangerInlinePolicy legacyPolicy =
JsonUtilsV2.jsonToObj(legacySessionPolicy, RangerInlinePolicy.class);
+ RangerInlinePolicy.Grant legacyGrant =
legacyPolicy.getGrants().iterator().next();
+
+ assertNotNull(legacyGrant.getActions(),
+ "legacy session policy should contain S3 actions as if created
with flag enabled");
+
+ final String previous = setOzoneActionPolicyDisabled();
+
+ try {
+ RangerInlinePolicy sanitized =
RangerOzoneAuthorizer.sanitizeInlinePolicyForActionFlag(legacyPolicy,
testPlugin);
+
+ assertNull(sanitized.getGrants().iterator().next().getActions(),
+ "sanitizeInlinePolicyForActionFlag should strip grant
actions when flag is disabled");
+
+ RequestContext ctxWriteGetObject = reqCtxBuilder
+ .setAclRights(IAccessAuthorizer.ACLType.WRITE)
+ .setRecursiveAccessCheck(false)
+ .setSessionPolicy(legacySessionPolicy)
+ .setS3Action("GetObject")
+ .build();
+
+ assertTrue(ozoneAuthorizer.checkAccess(key1, ctxWriteGetObject),
+ "legacy session-policy with embedded S3 actions should
allow write when flag is disabled");
+ } finally {
+ restoreOzoneActionPolicyEnabled(previous);
+ }
+ }
+
+ private static void setOzoneActionPolicyEnabled(RangerBasePlugin plugin) {
+ if (plugin == null || plugin.getServiceDef() == null) {
+ return;
+ }
+
+ Map<String, String> options = plugin.getServiceDef().getOptions();
+
+ if (options == null) {
+ options = new HashMap<>();
+ plugin.getServiceDef().setOptions(options);
+ }
+
+ options.put(OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION,
Boolean.toString(true));
+ }
+
+ private static String setOzoneActionPolicyDisabled() {
+ final Map<String, String> options =
testPlugin.getServiceDef().getOptions();
+ final String previous =
options.put(OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION,
Boolean.toString(false));
+
+ return previous;
+ }
+
+ private static void restoreOzoneActionPolicyEnabled(String previous) {
+ final Map<String, String> options =
testPlugin.getServiceDef().getOptions();
+
+ if (previous == null) {
+ options.remove(OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION);
+ } else {
+ options.put(OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION,
previous);
+ }
+ }
}
diff --git a/security-admin/scripts/install.properties
b/security-admin/scripts/install.properties
index e8a9f2f81..6a6ababc0 100644
--- a/security-admin/scripts/install.properties
+++ b/security-admin/scripts/install.properties
@@ -152,6 +152,9 @@ policymgr_https_keystore_password=
#Example : policymgr_supportedcomponents=hive,hbase,hdfs
policymgr_supportedcomponents=
+# Enable Ozone action-matches policy condition in Admin UI and authorizer
+FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION=false
+
#
# ------- PolicyManager CONFIG - END ---------------
#
diff --git a/security-admin/scripts/setup.sh b/security-admin/scripts/setup.sh
index ae2048edc..b0bc26214 100755
--- a/security-admin/scripts/setup.sh
+++ b/security-admin/scripts/setup.sh
@@ -175,6 +175,7 @@ cred_keystore_filename=$(eval echo "$(get_prop
'cred_keystore_filename' $PROPFIL
sso_enabled=$(get_prop 'sso_enabled' $PROPFILE)
sso_providerurl=$(get_prop 'sso_providerurl' $PROPFILE)
sso_publickey=$(get_prop 'sso_publickey' $PROPFILE)
+FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION=$(get_prop_or_default
'FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION' $PROPFILE 'false')
RANGER_ADMIN_LOG_DIR=$(eval echo "$(get_prop 'RANGER_ADMIN_LOG_DIR'
$PROPFILE)")
RANGER_ADMIN_LOGBACK_CONF_FILE=$(eval echo "$(get_prop
'RANGER_ADMIN_LOGBACK_CONF_FILE' $PROPFILE)")
RANGER_PID_DIR_PATH=$(eval echo "$(get_prop 'RANGER_PID_DIR_PATH' $PROPFILE)")
@@ -1090,6 +1091,16 @@ update_properties() {
updatePropertyToFilePy $propertyName "${newPropertyValue}"
$to_file_ranger
fi
+
+ ff_enable_ozone_action_matches_condition=$(echo
"${FF_ENABLE_OZONE_ACTION_MATCHES_CONDITION}" | tr '[:upper:]' '[:lower:]')
+ if [ "${ff_enable_ozone_action_matches_condition}" != "true" ]
+ then
+ ff_enable_ozone_action_matches_condition=false
+ fi
+
propertyName=ranger.servicedef.ozone.enableActionMatcherInPoliciesCondition
+ newPropertyValue="${ff_enable_ozone_action_matches_condition}"
+ updatePropertyToFilePy $propertyName "${newPropertyValue}"
$to_file_ranger
+
if [ "${javax_net_ssl_keyStore}" != "" ] && [
"${javax_net_ssl_keyStorePassword}" != "" ]
then
javax_net_ssl_keyStoreAlias=keyStoreAlias
diff --git
a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefService.java
b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefService.java
index 5bdd3ad90..78e269aa6 100644
---
a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefService.java
+++
b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefService.java
@@ -21,17 +21,24 @@
import org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
import org.apache.ranger.entity.XXServiceDef;
import org.apache.ranger.plugin.model.RangerServiceDef;
+import
org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@Scope("singleton")
public class RangerServiceDefService extends
RangerServiceDefServiceBase<XXServiceDef, RangerServiceDef> {
+ public static final String
PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE =
"ranger.servicedef.ozone.enableActionMatcherInPoliciesCondition";
+ public static final String
OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION =
"enableActionMatcherInPoliciesCondition";
+
+ private static final String POLICY_CONDITION_ACTION_MATCHES =
"action-matches";
+
private final RangerAdminConfig config;
public RangerServiceDefService() {
@@ -101,4 +108,109 @@ protected RangerServiceDef
mapEntityToViewBean(RangerServiceDef vObj, XXServiceD
return ret;
}
+
+ @Override
+ protected RangerServiceDef populateViewBean(XXServiceDef xServiceDef) {
+ final RangerServiceDef ret = super.populateViewBean(xServiceDef);
+
+ applyActionMatcherInPoliciesConditionHiddenOption(ret);
+
+ return ret;
+ }
+
+ void applyActionMatcherInPoliciesConditionHiddenOption(RangerServiceDef
serviceDef) {
+ if (serviceDef == null) {
+ return;
+ }
+
+ final boolean isOzoneServiceDef =
StringUtils.equalsIgnoreCase(serviceDef.getName(),
EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_OZONE_NAME);
+
+ if (!isOzoneServiceDef) {
+ return;
+ }
+
+ Map<String, String> serviceDefOptions = serviceDef.getOptions();
+
+ if (serviceDefOptions == null) {
+ serviceDefOptions = new HashMap<>();
+ serviceDef.setOptions(serviceDefOptions);
+ }
+
+ // Admin site config is authoritative at runtime; stale def_options
must not override it.
+ boolean enabled =
config.getBoolean(PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE,
false);
+
+
serviceDefOptions.put(OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION,
Boolean.toString(enabled));
+ serviceDef.setOptions(serviceDefOptions);
+
+ if (enabled) {
+ ensureActionMatchesPolicyCondition(serviceDef);
+ } else {
+ removeActionMatchesPolicyCondition(serviceDef);
+ }
+ }
+
+ private void ensureActionMatchesPolicyCondition(RangerServiceDef
serviceDef) {
+ if (hasActionMatchesPolicyCondition(serviceDef)) {
+ return;
+ }
+
+ try {
+ final RangerServiceDef embeddedOzoneServiceDef =
EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_OZONE_NAME);
+
+ if (embeddedOzoneServiceDef == null ||
embeddedOzoneServiceDef.getPolicyConditions() == null) {
+ return;
+ }
+
+ for (RangerPolicyConditionDef embeddedPolicyConditionDef :
embeddedOzoneServiceDef.getPolicyConditions()) {
+ if (StringUtils.equals(embeddedPolicyConditionDef.getName(),
POLICY_CONDITION_ACTION_MATCHES)) {
+ List<RangerPolicyConditionDef> policyConditions =
serviceDef.getPolicyConditions();
+
+ if (policyConditions == null) {
+ policyConditions = new ArrayList<>();
+ serviceDef.setPolicyConditions(policyConditions);
+ }
+
+ policyConditions.add(embeddedPolicyConditionDef);
+
+ return;
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to restore ozone action-matches
policy condition", e);
+ }
+ }
+
+ private void removeActionMatchesPolicyCondition(RangerServiceDef
serviceDef) {
+ List<RangerPolicyConditionDef> policyConditions =
serviceDef.getPolicyConditions();
+
+ if (policyConditions == null || policyConditions.isEmpty()) {
+ return;
+ }
+
+ List<RangerPolicyConditionDef> filteredPolicyConditions = new
ArrayList<>();
+
+ for (RangerPolicyConditionDef policyConditionDef : policyConditions) {
+ if (!StringUtils.equals(policyConditionDef.getName(),
POLICY_CONDITION_ACTION_MATCHES)) {
+ filteredPolicyConditions.add(policyConditionDef);
+ }
+ }
+
+ serviceDef.setPolicyConditions(filteredPolicyConditions);
+ }
+
+ private static boolean hasActionMatchesPolicyCondition(RangerServiceDef
serviceDef) {
+ List<RangerPolicyConditionDef> policyConditions =
serviceDef.getPolicyConditions();
+
+ if (policyConditions == null || policyConditions.isEmpty()) {
+ return false;
+ }
+
+ for (RangerPolicyConditionDef policyConditionDef : policyConditions) {
+ if (StringUtils.equals(policyConditionDef.getName(),
POLICY_CONDITION_ACTION_MATCHES)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git
a/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml
b/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml
index a69d5886d..164b63d02 100644
--- a/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml
+++ b/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml
@@ -152,6 +152,14 @@
<name>ranger.resource.accessControl.enabled</name>
<value>true</value>
</property>
+ <property>
+
<name>ranger.servicedef.ozone.enableActionMatcherInPoliciesCondition</name>
+ <value>false</value>
+ <description>
+ When true, enables Ozone action-matches
(RangerActionMatcher) policy conditions
+ in the Admin UI and applies S3 action-based evaluation
in the Ozone authorizer.
+ </description>
+ </property>
<property>
<name>ranger.xuser.createdByUserId</name>
<value>1</value>
diff --git a/security-admin/src/main/resources/conf.dist/ranger-admin-site.xml
b/security-admin/src/main/resources/conf.dist/ranger-admin-site.xml
index 4effba2da..388ce1674 100644
--- a/security-admin/src/main/resources/conf.dist/ranger-admin-site.xml
+++ b/security-admin/src/main/resources/conf.dist/ranger-admin-site.xml
@@ -506,4 +506,8 @@
<name>xasecure.audit.jaas.Client.option.principal</name>
<value></value>
</property>
+ <property>
+
<name>ranger.servicedef.ozone.enableActionMatcherInPoliciesCondition</name>
+ <value>false</value>
+ </property>
</configuration>
diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
b/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
index a39a24f45..382305c7f 100644
--- a/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
+++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
@@ -1495,7 +1495,7 @@ export const requestDataTitle = (serviceType) => {
//Policy condition evaluation
export const policyConditionUpdatedJSON = (policyCond) => {
- let newPolicyConditionJSON = [...policyCond];
+ let newPolicyConditionJSON = [...(Array.isArray(policyCond) ? policyCond :
[])];
newPolicyConditionJSON.filter(function (key) {
if (!key?.uiHint || key?.uiHint == "") {
if (
diff --git
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/AccessGrantForm.jsx
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/AccessGrantForm.jsx
index aed34bddb..e53402f6c 100755
---
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/AccessGrantForm.jsx
+++
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/AccessGrantForm.jsx
@@ -268,7 +268,7 @@ function AccessGrantForm({
for (let data of val.conditions) {
let conditionObj = find(
- policyConditionUpdatedJSON(serviceCompDetails?.policyConditions),
+ policyConditionUpdatedJSON(serviceCompDetails?.policyConditions ||
[]),
function (m) {
if (m.name == data.type) {
return m;
@@ -276,7 +276,9 @@ function AccessGrantForm({
}
);
- if (!isEmpty(conditionObj.uiHint)) {
+ // Ignore policy conditions that are not defined in the service-def.
+ // Without this guard, form initialization can fail and crash the
page.
+ if (conditionObj?.uiHint && !isEmpty(conditionObj.uiHint)) {
obj.conditions[data?.type] = JSON.parse(conditionObj.uiHint)
.isMultiValue
? data?.values.map((m) => {
diff --git
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/AddUpdatePolicyForm.jsx
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/AddUpdatePolicyForm.jsx
index b4e6f03ab..5957f7658 100644
---
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/AddUpdatePolicyForm.jsx
+++
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/AddUpdatePolicyForm.jsx
@@ -512,7 +512,7 @@ export default function AddUpdatePolicyForm() {
data.conditions = {};
for (let val of policyData.conditions) {
let conditionObj = find(
- policyConditionUpdatedJSON(serviceCompData?.policyConditions),
+ policyConditionUpdatedJSON(serviceCompData?.policyConditions ||
[]),
function (m) {
if (m.name == val.type) {
return m;
@@ -520,7 +520,9 @@ export default function AddUpdatePolicyForm() {
}
);
- if (!isEmpty(conditionObj.uiHint)) {
+ // Ignore policy conditions that are not defined in the service-def.
+ // Without this guard, form initialization can fail and leave the
page on the loader.
+ if (conditionObj?.uiHint && !isEmpty(conditionObj.uiHint)) {
data.conditions[val?.type] = JSON.parse(conditionObj.uiHint)
.isMultiValue
? val?.values
@@ -702,7 +704,7 @@ export default function AddUpdatePolicyForm() {
for (let data of val.conditions) {
let conditionObj = find(
- policyConditionUpdatedJSON(serviceData?.policyConditions),
+ policyConditionUpdatedJSON(serviceData?.policyConditions || []),
function (m) {
if (m.name == data.type) {
return m;
@@ -710,7 +712,9 @@ export default function AddUpdatePolicyForm() {
}
);
- if (!isEmpty(conditionObj.uiHint)) {
+ // Ignore policy conditions that are not defined in the service-def.
+ // Without this guard, form initialization can fail and leave the
page on the loader.
+ if (conditionObj?.uiHint && !isEmpty(conditionObj.uiHint)) {
obj.conditions[data?.type] = JSON.parse(conditionObj.uiHint)
.isMultiValue
? data?.values
diff --git
a/security-admin/src/test/java/org/apache/ranger/service/TestRangerServiceDefService.java
b/security-admin/src/test/java/org/apache/ranger/service/TestRangerServiceDefService.java
index c536f9942..41d0be2d9 100644
---
a/security-admin/src/test/java/org/apache/ranger/service/TestRangerServiceDefService.java
+++
b/security-admin/src/test/java/org/apache/ranger/service/TestRangerServiceDefService.java
@@ -17,6 +17,7 @@
package org.apache.ranger.service;
import org.apache.commons.lang3.StringUtils;
+import org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
import org.apache.ranger.biz.RangerBizUtil;
import org.apache.ranger.common.ContextUtil;
import org.apache.ranger.common.PropertiesUtil;
@@ -54,6 +55,7 @@
import
org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.ServiceDefUtil;
import org.apache.ranger.security.context.RangerContextHolder;
import org.apache.ranger.security.context.RangerSecurityContext;
@@ -71,8 +73,10 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
+import static
org.apache.ranger.service.RangerServiceDefService.PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE;
import static
org.apache.ranger.service.RangerServiceDefService.PROP_ENABLE_IMPLICIT_CONDITION_EXPRESSION;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -92,7 +96,8 @@
@ExtendWith(MockitoExtension.class)
@TestMethodOrder(MethodOrderer.MethodName.class)
public class TestRangerServiceDefService {
- private static final Long Id = 8L;
+ private static final Long Id = 8L;
+ private static final String
OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION =
RangerServiceDefService.OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION;
@InjectMocks
RangerServiceDefService serviceDefService;
@Mock
@@ -764,7 +769,7 @@ public void testMapViewToEntityBean() throws
NoSuchMethodException {
v.setRbKeyLabel("rbl");
v.setRbKeyDescription("rbd");
v.setIsEnabled(Boolean.TRUE);
- v.setOptions(new java.util.HashMap<>());
+ v.setOptions(new HashMap<>());
try {
method.invoke(rangerServiceDefWithAssignedIdService, v,
xxServiceDefWithAssignedId, 1);
@@ -782,6 +787,80 @@ public void testMapViewToEntityBean() throws
NoSuchMethodException {
}
}
+ @Test
+ public void testOzoneActionPolicyOptionDisabled() {
+
RangerAdminConfig.getInstance().set(PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE,
Boolean.FALSE.toString());
+
+ try {
+ RangerServiceDef serviceDef =
buildOzoneServiceDefWithActionMatches();
+
+
serviceDefService.applyActionMatcherInPoliciesConditionHiddenOption(serviceDef);
+
+ assertEquals("false",
serviceDef.getOptions().get(OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION));
+ assertFalse(hasActionMatchesCondition(serviceDef));
+ } finally {
+
RangerAdminConfig.getInstance().unset(PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE);
+ }
+ }
+
+ @Test
+ public void testOzoneActionPolicyOptionEnabled() {
+
RangerAdminConfig.getInstance().set(PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE,
Boolean.TRUE.toString());
+
+ try {
+ RangerServiceDef serviceDef =
buildOzoneServiceDefWithActionMatches();
+
+
serviceDefService.applyActionMatcherInPoliciesConditionHiddenOption(serviceDef);
+
+ assertEquals("true",
serviceDef.getOptions().get(OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION));
+ assertTrue(hasActionMatchesCondition(serviceDef));
+ } finally {
+
RangerAdminConfig.getInstance().unset(PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE);
+ }
+ }
+
+ @Test
+ public void testOzoneActionPolicyConfigTrueOverridesStoredFalseOption() {
+
RangerAdminConfig.getInstance().set(PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE,
Boolean.TRUE.toString());
+
+ try {
+ RangerServiceDef serviceDef =
buildOzoneServiceDefWithActionMatches();
+
serviceDef.getOptions().put(OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION,
Boolean.FALSE.toString());
+
+
serviceDefService.applyActionMatcherInPoliciesConditionHiddenOption(serviceDef);
+
+ assertEquals("true",
serviceDef.getOptions().get(OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION));
+ assertTrue(hasActionMatchesCondition(serviceDef));
+ } finally {
+
RangerAdminConfig.getInstance().unset(PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE);
+ }
+ }
+
+ @Test
+ public void
testOzoneActionPolicyConfigTrueRestoresMissingActionMatchesCondition() {
+
RangerAdminConfig.getInstance().set(PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE,
Boolean.TRUE.toString());
+
+ try {
+ RangerPolicyConditionDef ipRange = new RangerPolicyConditionDef();
+ ipRange.setName("ip-range");
+
+ List<RangerPolicyConditionDef> policyConditions = new
ArrayList<>();
+ policyConditions.add(ipRange);
+
+ RangerServiceDef serviceDef = new RangerServiceDef();
+
serviceDef.setName(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_OZONE_NAME);
+ serviceDef.setOptions(new HashMap<>());
+ serviceDef.setPolicyConditions(policyConditions);
+
+
serviceDefService.applyActionMatcherInPoliciesConditionHiddenOption(serviceDef);
+
+ assertEquals("true",
serviceDef.getOptions().get(OPTION_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION));
+ assertTrue(hasActionMatchesCondition(serviceDef));
+ } finally {
+
RangerAdminConfig.getInstance().unset(PROP_ENABLE_ACTION_MATCHER_IN_POLICIES_CONDITION_FOR_OZONE);
+ }
+ }
+
@Test
public void testMapViewToEntityBean_intOverload_executes() throws
Exception {
Method method =
RangerServiceDefWithAssignedIdService.class.getDeclaredMethod("mapViewToEntityBean",
RangerServiceDef.class, XXServiceDefWithAssignedId.class, int.class);
@@ -832,6 +911,39 @@ public void testValidateForUpdate() throws
NoSuchMethodException {
}
}
+ private boolean hasActionMatchesCondition(RangerServiceDef serviceDef) {
+ if (serviceDef.getPolicyConditions() == null) {
+ return false;
+ }
+
+ for (RangerPolicyConditionDef conditionDef :
serviceDef.getPolicyConditions()) {
+ if (StringUtils.equals(conditionDef.getName(), "action-matches")) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private RangerServiceDef buildOzoneServiceDefWithActionMatches() {
+ RangerPolicyConditionDef ipRange = new RangerPolicyConditionDef();
+ ipRange.setName("ip-range");
+
+ RangerPolicyConditionDef actionMatches = new
RangerPolicyConditionDef();
+ actionMatches.setName("action-matches");
+
+ List<RangerPolicyConditionDef> policyConditions = new ArrayList<>();
+ policyConditions.add(ipRange);
+ policyConditions.add(actionMatches);
+
+ RangerServiceDef serviceDef = new RangerServiceDef();
+
serviceDef.setName(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_OZONE_NAME);
+ serviceDef.setOptions(new HashMap<>());
+ serviceDef.setPolicyConditions(policyConditions);
+
+ return serviceDef;
+ }
+
private RangerServiceDef rangerServiceDef() {
List<RangerServiceConfigDef> configs = new ArrayList<>();
List<RangerResourceDef> resources = new ArrayList<>();