diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/EmbeddedResourcePolicySource.java b/agents-common/src/main/java/org/apache/ranger/admin/client/EmbeddedResourcePolicySource.java index 7b146edb5a..58e49b5b77 100644 --- a/agents-common/src/main/java/org/apache/ranger/admin/client/EmbeddedResourcePolicySource.java +++ b/agents-common/src/main/java/org/apache/ranger/admin/client/EmbeddedResourcePolicySource.java @@ -19,6 +19,7 @@ package org.apache.ranger.admin.client; +import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.ranger.plugin.util.JsonUtilsV2; import org.apache.ranger.plugin.util.RangerRoles; @@ -33,145 +34,136 @@ import java.io.InputStreamReader; // this implementation loads policies, roles, tags, userstore and gds info from embedded resources at following paths: -// {resource-path}/{appId}_{serviceName}.json -> policies -// {resource-path}/{appId}_{serviceName}_roles.json -> roles -// {resource-path}/{appId}_{serviceName}_tag.json -> tags -// {resource-path}/{appId}_{serviceName}_userstore.json -> userstore -// {resource-path}/{appId}_{serviceName}_gds.json -> gds info -public class EmbeddedResourcePolicySource extends AbstractRangerAdminClient { +// policies: {resource-path}/{serviceName}.json or {resource-path}/{appId}_{serviceName}.json +// roles: {resource-path}/{serviceName}_roles.json or {resource-path}/{appId}_{serviceName}_roles.json +// tags: {resource-path}/{serviceName}_tag.json or {resource-path}/{appId}_{serviceName}_tag.json +// userstore: {resource-path}/{serviceName}_userstore.json or {resource-path}/{appId}_{serviceName}_userstore.json +// gds: {resource-path}/{serviceName}_gds.json or {resource-path}/{appId}_{serviceName}_gds.json +public class EmbeddedResourcePolicySource extends RangerPolicySource { private static final Logger LOG = LoggerFactory.getLogger(EmbeddedResourcePolicySource.class); + private String prefix; + private String prefixWithAppId; + private ServicePolicies policies; private RangerRoles roles; private ServiceTags tags; private RangerUserStore userStore; private ServiceGdsInfo gdsInfo; - private String policiesPath; - private String rolesPath; - private String tagsPath; - private String userStorePath; - private String gdsInfoPath; - @Override public void init(String serviceName, String appId, String configPropertyPrefix, Configuration config) { super.init(serviceName, appId, configPropertyPrefix, config); - String directory = config.get(configPropertyPrefix + ".policy.source.embedded_resource.path"); - String pathPrefix = (directory == null ? "" : directory) + "/" + appId + "_" + serviceName; + String directory = config.get(configPropertyPrefix + ".policy.source.embedded_resource.path"); - if (!pathPrefix.startsWith("/")) { - pathPrefix = "/" + pathPrefix; + if (StringUtils.isBlank(directory)) { + directory = "/"; + } else if (!directory.endsWith("/")) { + directory += "/"; } - this.policiesPath = pathPrefix + ".json"; - this.rolesPath = pathPrefix + "_roles.json"; - this.tagsPath = pathPrefix + "_tag.json"; - this.userStorePath = pathPrefix + "_userstore.json"; - this.gdsInfoPath = pathPrefix + "_gds.json"; + prefix = directory + serviceName; + prefixWithAppId = StringUtils.isBlank(appId) ? null : (directory + appId + "_" + serviceName); } @Override - public ServicePolicies getServicePoliciesIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) { + public ServicePolicies getServicePoliciesIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) throws Exception { loadPolicies(); return (lastKnownVersion == -1 || policies == null || policies.getPolicyVersion() == null || !policies.getPolicyVersion().equals(lastKnownVersion)) ? policies : null; } @Override - public RangerRoles getRolesIfUpdated(long lastKnownVersion, long lastActivationTimeInMills) { + public RangerRoles getRolesIfUpdated(long lastKnownVersion, long lastActivationTimeInMills) throws Exception { loadRoles(); return (lastKnownVersion == -1 || roles == null || roles.getRoleVersion() == null || !roles.getRoleVersion().equals(lastKnownVersion)) ? roles : null; } @Override - public ServiceTags getServiceTagsIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) { + public ServiceTags getServiceTagsIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) throws Exception { loadTags(); return (lastKnownVersion == -1 || tags == null || tags.getTagVersion() == null || !tags.getTagVersion().equals(lastKnownVersion)) ? tags : null; } @Override - public RangerUserStore getUserStoreIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) { + public RangerUserStore getUserStoreIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) throws Exception { loadUserStore(); return (lastKnownVersion == -1 || userStore == null || userStore.getUserStoreVersion() == null || !userStore.getUserStoreVersion().equals(lastKnownVersion)) ? userStore : null; } @Override - public ServiceGdsInfo getGdsInfoIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) { + public ServiceGdsInfo getGdsInfoIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) throws Exception { loadGdsInfo(); return (lastKnownVersion == -1 || gdsInfo == null || gdsInfo.getGdsVersion() == null || !gdsInfo.getGdsVersion().equals(lastKnownVersion)) ? gdsInfo : null; } - private void loadPolicies() { + private void loadPolicies() throws Exception { if (policies == null) { - try { - InputStream input = getClass().getResourceAsStream(policiesPath); - - if (input != null) { - policies = gson.fromJson(new InputStreamReader(input), ServicePolicies.class); - } - } catch (Throwable t) { - LOG.error("loadPolicies(): failed to load policies from {}", policiesPath, t); - } + InputStream input = getResourceStream(SUFFIX_POLICIES_FILE); + + policies = gson.fromJson(new InputStreamReader(input), ServicePolicies.class); } } - private void loadRoles() { + private void loadRoles() throws Exception { if (roles == null) { - try { - InputStream input = getClass().getResourceAsStream(rolesPath); - - if (input != null) { - roles = gson.fromJson(new InputStreamReader(input), RangerRoles.class); - } - } catch (Throwable t) { - LOG.error("loadRoles(): failed to load roles from {}", rolesPath, t); - } + InputStream input = getResourceStream(SUFFIX_ROLES_FILE); + + roles = gson.fromJson(new InputStreamReader(input), RangerRoles.class); } } - private void loadUserStore() { + private void loadUserStore() throws Exception { if (userStore == null) { - try { - InputStream input = getClass().getResourceAsStream(userStorePath); - - if (input != null) { - userStore = gson.fromJson(new InputStreamReader(input), RangerUserStore.class); - } - } catch (Throwable t) { - LOG.error("loadUserStore(): failed to load userstore from {}", userStorePath, t); - } + InputStream input = getResourceStream(SUFFIX_USERSTORE_FILE); + + userStore = gson.fromJson(new InputStreamReader(input), RangerUserStore.class); } } - private void loadTags() { + private void loadTags() throws Exception { if (tags == null) { - try { - InputStream input = getClass().getResourceAsStream(tagsPath); - - if (input != null) { - tags = gson.fromJson(new InputStreamReader(input), ServiceTags.class); - } - } catch (Throwable t) { - LOG.error("loadTags(): failed to load tags from {}", tagsPath, t); - } + InputStream input = getResourceStream(SUFFIX_TAG_FILE); + + tags = gson.fromJson(new InputStreamReader(input), ServiceTags.class); } } - private void loadGdsInfo() { + private void loadGdsInfo() throws Exception { if (gdsInfo == null) { - try { - InputStream input = getClass().getResourceAsStream(gdsInfoPath); - - if (input != null) { - gdsInfo = JsonUtilsV2.readValue(new InputStreamReader(input), ServiceGdsInfo.class); - } - } catch (Throwable t) { - LOG.error("loadGdsInfo(): failed to load gdsInfo from {}", gdsInfoPath, t); + InputStream input = getResourceStream(SUFFIX_GDS_FILE); + + gdsInfo = JsonUtilsV2.readValue(new InputStreamReader(input), ServiceGdsInfo.class); + } + } + + private InputStream getResourceStream(String suffix) throws Exception { + if (StringUtils.isBlank(prefix)) { + throw new Exception(EmbeddedResourcePolicySource.class.getName() + ": not initialized"); + } + + try { + InputStream src = getClass().getResourceAsStream(prefix + suffix); + + if (src == null && StringUtils.isNotBlank(prefixWithAppId)) { + src = getClass().getResourceAsStream(prefixWithAppId + suffix); } + + if (src == null) { + LOG.error("{}{}: resource not found", prefix, suffix); + + throw new Exception(prefix + suffix + ": resource not found"); + } + + return src; + } catch (Exception excp) { + LOG.error("{}{}: resource not found", prefix, suffix, excp); + + throw new Exception(prefix + suffix + ": resource not found", excp); } } } diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/LocalFolderPolicySource.java b/agents-common/src/main/java/org/apache/ranger/admin/client/LocalFolderPolicySource.java index ecaf7ef8a6..71c891ae11 100644 --- a/agents-common/src/main/java/org/apache/ranger/admin/client/LocalFolderPolicySource.java +++ b/agents-common/src/main/java/org/apache/ranger/admin/client/LocalFolderPolicySource.java @@ -19,6 +19,7 @@ package org.apache.ranger.admin.client; +import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.ranger.plugin.util.JsonUtilsV2; import org.apache.ranger.plugin.util.RangerRoles; @@ -26,46 +27,50 @@ import org.apache.ranger.plugin.util.ServiceGdsInfo; import org.apache.ranger.plugin.util.ServicePolicies; import org.apache.ranger.plugin.util.ServiceTags; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileReader; // this implementation loads policies, roles, tags, userstore and gds info from the given local filesystem paths: -// {path}/{appId}_{serviceName}.json -> policies -// {path}/{appId}_{serviceName}_roles.json -> roles -// {path}/{appId}_{serviceName}_tag.json -> tags -// {path}/{appId}_{serviceName}_userstore.json -> userstore -// {path}/{appId}_{serviceName}_gds.json -> gds info -public class LocalFolderPolicySource extends AbstractRangerAdminClient { +// policies: {path}/{serviceName}.json or {path}/{appId}_{serviceName}.json +// roles: {path}/{serviceName}_roles.json or {path}/{appId}_{serviceName}_roles.json +// tags: {path}/{serviceName}_tag.json or {path}/{appId}_{serviceName}_tag.json +// userstore: {path}/{serviceName}_userstore.json or {path}/{appId}_{serviceName}_userstore.json +// gds: {path}/{serviceName}_gds.json or {path}/{appId}_{serviceName}_gds.json +public class LocalFolderPolicySource extends RangerPolicySource { + private static final Logger LOG = LoggerFactory.getLogger(LocalFolderPolicySource.class); + + private String prefix; + private String prefixWithAppId; + private ServicePolicies policies; private RangerRoles roles; private RangerUserStore userStore; private ServiceTags tags; private ServiceGdsInfo gdsInfo; - private String policiesPath; - private String rolesPath; - private String userStorePath; - private String tagsPath; - private String gdsInfoPath; - private long lastPoliciesFileModifiedTime = -1; - private long lastRolesFileModifiedTime = -1; - private long lastUserStoreFileModifiedTime = -1; - private long lastTagsFileModifiedTime = -1; - private long lastGdsInfoFileModifiedTime = -1; + private long lastPoliciesFileModifiedTime = -1; + private long lastRolesFileModifiedTime = -1; + private long lastUserStoreFileModifiedTime = -1; + private long lastTagsFileModifiedTime = -1; + private long lastGdsInfoFileModifiedTime = -1; @Override public void init(String serviceName, String appId, String configPropertyPrefix, Configuration config) { super.init(serviceName, appId, configPropertyPrefix, config); - String directory = config.get(configPropertyPrefix + ".policy.source.local_folder.path"); - String pathPrefix = (directory == null ? "" : directory) + File.separator + appId + "_" + serviceName; + String directory = config.get(configPropertyPrefix + ".policy.source.local_folder.path"); + + if (StringUtils.isBlank(directory)) { + directory = ""; + } else if (!directory.endsWith(File.separator)) { + directory += File.separator; + } - this.policiesPath = pathPrefix + ".json"; - this.rolesPath = pathPrefix + "_roles.json"; - this.userStorePath = pathPrefix + "_userstore.json"; - this.tagsPath = pathPrefix + "_tag.json"; - this.gdsInfoPath = pathPrefix + "_gds.json"; + prefix = directory + serviceName; + prefixWithAppId = StringUtils.isBlank(appId) ? null : (directory + appId + "_" + serviceName); } @Override @@ -104,11 +109,7 @@ public ServiceGdsInfo getGdsInfoIfUpdated(long lastKnownVersion, long lastActiva } private void loadPolicies() throws Exception { - File srcFile = new File(policiesPath); - - if (!srcFile.exists() || !srcFile.canRead()) { - throw new Exception(policiesPath + ": policies file not found or not readable"); - } + File srcFile = getSourceFile(SUFFIX_POLICIES_FILE); if (policies == null || srcFile.lastModified() != lastPoliciesFileModifiedTime) { try (FileReader reader = new FileReader(srcFile)) { @@ -120,11 +121,7 @@ private void loadPolicies() throws Exception { } private void loadRoles() throws Exception { - File srcFile = new File(rolesPath); - - if (!srcFile.exists() || !srcFile.canRead()) { - throw new Exception(rolesPath + ": roles file not found or not readable"); - } + File srcFile = getSourceFile(SUFFIX_ROLES_FILE); if (roles == null || srcFile.lastModified() != lastRolesFileModifiedTime) { try (FileReader reader = new FileReader(srcFile)) { @@ -136,11 +133,7 @@ private void loadRoles() throws Exception { } private void loadTags() throws Exception { - File srcFile = new File(tagsPath); - - if (!srcFile.exists() || !srcFile.canRead()) { - throw new Exception(tagsPath + ": tags file not found or not readable"); - } + File srcFile = getSourceFile(SUFFIX_TAG_FILE); if (tags == null || srcFile.lastModified() != lastTagsFileModifiedTime) { try (FileReader reader = new FileReader(srcFile)) { @@ -152,11 +145,7 @@ private void loadTags() throws Exception { } private void loadUserStore() throws Exception { - File srcFile = new File(userStorePath); - - if (!srcFile.exists() || !srcFile.canRead()) { - throw new Exception(userStorePath + ": userStore file not found or not readable"); - } + File srcFile = getSourceFile(SUFFIX_USERSTORE_FILE); if (userStore == null || srcFile.lastModified() != lastUserStoreFileModifiedTime) { try (FileReader reader = new FileReader(srcFile)) { @@ -168,11 +157,7 @@ private void loadUserStore() throws Exception { } private void loadGdsInfo() throws Exception { - File srcFile = new File(gdsInfoPath); - - if (!srcFile.exists() || !srcFile.canRead()) { - throw new Exception(gdsInfoPath + ": gdsInfo file not found or not readable"); - } + File srcFile = getSourceFile(SUFFIX_GDS_FILE); if (gdsInfo == null || srcFile.lastModified() != lastGdsInfoFileModifiedTime) { try (FileReader reader = new FileReader(srcFile)) { @@ -182,4 +167,28 @@ private void loadGdsInfo() throws Exception { } } } + + private File getSourceFile(String suffix) throws Exception { + if (StringUtils.isBlank(prefix)) { + throw new Exception(LocalFolderPolicySource.class.getName() + ": not initialized"); + } + + File src = new File(prefix + suffix); + boolean isReadable = src.exists() && src.canRead(); + + if (!isReadable) { + if (StringUtils.isNotBlank(prefixWithAppId)) { + src = new File(prefixWithAppId + suffix); + isReadable = src.exists() && src.canRead(); + } + } + + if (!isReadable) { + LOG.error("{}{}: file not found or not readable", prefix, suffix); + + throw new Exception(prefix + suffix + ": file not found or not readable"); + } + + return src; + } } diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerPolicySource.java b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerPolicySource.java new file mode 100644 index 0000000000..24f417d6f2 --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerPolicySource.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.admin.client; + +import org.apache.commons.lang3.NotImplementedException; +import org.apache.ranger.plugin.model.RangerRole; +import org.apache.ranger.plugin.util.GrantRevokeRequest; +import org.apache.ranger.plugin.util.GrantRevokeRoleRequest; + +import java.util.List; + +// Implementations of this abstract class should implement methods that supply +// following details used by policy engine: policies, tags, roles, userstore, gds +// Other methods in RangerAdminClient throw NotImplementedException +public abstract class RangerPolicySource extends AbstractRangerAdminClient { + public static final String SUFFIX_POLICIES_FILE = ".json"; + public static final String SUFFIX_ROLES_FILE = "_roles.json"; + public static final String SUFFIX_USERSTORE_FILE = "_userstore.json"; + public static final String SUFFIX_TAG_FILE = "_tag.json"; + public static final String SUFFIX_GDS_FILE = "_gds.json"; + + @Override + public RangerRole createRole(RangerRole request) throws Exception { + throw new NotImplementedException(); + } + + @Override + public void dropRole(String execUser, String roleName) throws Exception { + throw new NotImplementedException(); + } + + @Override + public List getAllRoles(String execUser) throws Exception { + throw new NotImplementedException(); + } + + @Override + public List getUserRoles(String execUser) throws Exception { + throw new NotImplementedException(); + } + + @Override + public RangerRole getRole(String execUser, String roleName) throws Exception { + throw new NotImplementedException(); + } + + @Override + public void grantRole(GrantRevokeRoleRequest request) throws Exception { + throw new NotImplementedException(); + } + + @Override + public void revokeRole(GrantRevokeRoleRequest request) throws Exception { + throw new NotImplementedException(); + } + + @Override + public void grantAccess(GrantRevokeRequest request) throws Exception { + throw new NotImplementedException(); + } + + @Override + public void revokeAccess(GrantRevokeRequest request) throws Exception { + throw new NotImplementedException(); + } + + @Override + public List getTagTypes(String tagTypePattern) throws Exception { + throw new NotImplementedException(); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/admin/client/TestEmbeddedResourcePolicySource.java b/agents-common/src/test/java/org/apache/ranger/admin/client/TestEmbeddedResourcePolicySource.java new file mode 100644 index 0000000000..548b437f29 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/admin/client/TestEmbeddedResourcePolicySource.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.admin.client; + +import org.apache.hadoop.conf.Configuration; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class TestEmbeddedResourcePolicySource { + @Test + public void testLoadWithServiceNamePrefix() throws Exception { + RangerPolicySource source = getPolicySource("s3", "dev_s3", null); + + assertNotNull(source.getServicePoliciesIfUpdated(-1, -1), "failed to load policies for service=dev_s3, appId=null"); + assertNotNull(source.getServiceTagsIfUpdated(-1, -1), "failed to load tags for service=dev_s3, appId=null"); + assertNotNull(source.getRolesIfUpdated(-1, -1), "failed to load roles for service=dev_s3, appId=null"); + assertNotNull(source.getUserStoreIfUpdated(-1, -1), "failed to load userStore for service=dev_s3, appId=null"); + assertNotNull(source.getGdsInfoIfUpdated(-1, -1), "failed to load gdsInfo for service=dev_s3, appId=null"); + } + + @Test + public void testLoadWithServiceNamePrefixIgnoreAppId() throws Exception { + RangerPolicySource source = getPolicySource("s3", "dev_s3", "s3proxy"); + + assertNotNull(source.getServicePoliciesIfUpdated(-1, -1), "failed to load policies for service=dev_s3, appId=s3proxy"); + assertNotNull(source.getServiceTagsIfUpdated(-1, -1), "failed to load tags for service=dev_s3, appId=s3proxy"); + assertNotNull(source.getRolesIfUpdated(-1, -1), "failed to load roles for service=dev_s3, appId=s3proxy"); + assertNotNull(source.getUserStoreIfUpdated(-1, -1), "failed to load userStore for service=dev_s3, appId=s3proxy"); + assertNotNull(source.getGdsInfoIfUpdated(-1, -1), "failed to load gdsInfo for service=dev_s3, appId=s3proxy"); + } + + @Test + public void testLoadWithAppIdServiceNamePrefix() throws Exception { + RangerPolicySource source = getPolicySource("hive", "dev_hive", "hiveServer2"); + + assertNotNull(source.getServicePoliciesIfUpdated(-1, -1), "failed to load policies for service=dev_hive, appId=hiveServer2"); + assertNotNull(source.getServiceTagsIfUpdated(-1, -1), "failed to load tags for service=dev_hive, appId=hiveServer2"); + assertNotNull(source.getRolesIfUpdated(-1, -1), "failed to load roles for service=dev_hive, appId=hiveServer2"); + assertNotNull(source.getUserStoreIfUpdated(-1, -1), "failed to load userStore for service=dev_hive, appId=hiveServer2"); + assertNotNull(source.getGdsInfoIfUpdated(-1, -1), "failed to load gdsInfo for service=dev_hive, appId=hiveServer2"); + } + + @Test + public void testLoadFailureWithNonExistingServiceName() throws Exception { + RangerPolicySource source = getPolicySource("s3", "test_s3", null); + + assertThrows(Exception.class, () -> source.getServicePoliciesIfUpdated(-1, -1), "expected to not find policies for service=test_s3, appId=null"); + assertThrows(Exception.class, () -> source.getServiceTagsIfUpdated(-1, -1), "expected to not find tags for service=test_s3, appId=null"); + assertThrows(Exception.class, () -> source.getRolesIfUpdated(-1, -1), "expected to not find roles for service=test_s3, appId=null"); + assertThrows(Exception.class, () -> source.getUserStoreIfUpdated(-1, -1), "expected to not find userStore for service=test_s3, appId=null"); + assertThrows(Exception.class, () -> source.getGdsInfoIfUpdated(-1, -1), "expected to not find gdsInfo for service=test_s3, appId=null"); + } + + @Test + public void testLoadFailureWithNonExistingServiceNameAndAppId() throws Exception { + RangerPolicySource source = getPolicySource("hive", "test_hive", "trino"); + + assertThrows(Exception.class, () -> source.getServicePoliciesIfUpdated(-1, -1), "expected to not find policies for service=test_hive, appId=trino"); + assertThrows(Exception.class, () -> source.getServiceTagsIfUpdated(-1, -1), "expected to not find tags for service=test_hive, appId=trino"); + assertThrows(Exception.class, () -> source.getRolesIfUpdated(-1, -1), "expected to not find roles for service=test_hive, appId=trino"); + assertThrows(Exception.class, () -> source.getUserStoreIfUpdated(-1, -1), "expected to not find userStore for service=test_hive, appId=trino"); + assertThrows(Exception.class, () -> source.getGdsInfoIfUpdated(-1, -1), "expected to not find gdsInfo for service=test_hive, appId=trino"); + } + + private RangerPolicySource getPolicySource(String serviceType, String serviceName, String appId) { + String propPrefix = "ranger.plugin." + serviceType; + Configuration conf = new Configuration(); + + conf.set(propPrefix + ".policy.source.embedded_resource.path", "/admin.client"); + + EmbeddedResourcePolicySource source = new EmbeddedResourcePolicySource(); + + source.init(serviceName, appId, propPrefix, conf); + + return source; + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/admin/client/TestLocalFolderPolicySource.java b/agents-common/src/test/java/org/apache/ranger/admin/client/TestLocalFolderPolicySource.java new file mode 100644 index 0000000000..781cdf572d --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/admin/client/TestLocalFolderPolicySource.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.admin.client; + +import org.apache.hadoop.conf.Configuration; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class TestLocalFolderPolicySource { + @Test + public void testLoadWithServiceNamePrefix() throws Exception { + RangerPolicySource source = getPolicySource("s3", "dev_s3", null); + + assertNotNull(source.getServicePoliciesIfUpdated(-1, -1), "failed to load policies for service=dev_s3, appId=null"); + assertNotNull(source.getServiceTagsIfUpdated(-1, -1), "failed to load tags for service=dev_s3, appId=null"); + assertNotNull(source.getRolesIfUpdated(-1, -1), "failed to load roles for service=dev_s3, appId=null"); + assertNotNull(source.getUserStoreIfUpdated(-1, -1), "failed to load userStore for service=dev_s3, appId=null"); + assertNotNull(source.getGdsInfoIfUpdated(-1, -1), "failed to load gdsInfo for service=dev_s3, appId=null"); + } + + @Test + public void testLoadWithServiceNamePrefixIgnoreAppId() throws Exception { + RangerPolicySource source = getPolicySource("s3", "dev_s3", "s3proxy"); + + assertNotNull(source.getServicePoliciesIfUpdated(-1, -1), "failed to load policies for service=dev_s3, appId=s3proxy"); + assertNotNull(source.getServiceTagsIfUpdated(-1, -1), "failed to load tags for service=dev_s3, appId=s3proxy"); + assertNotNull(source.getRolesIfUpdated(-1, -1), "failed to load roles for service=dev_s3, appId=s3proxy"); + assertNotNull(source.getUserStoreIfUpdated(-1, -1), "failed to load userStore for service=dev_s3, appId=s3proxy"); + assertNotNull(source.getGdsInfoIfUpdated(-1, -1), "failed to load gdsInfo for service=dev_s3, appId=s3proxy"); + } + + @Test + public void testLoadWithAppIdServiceNamePrefix() throws Exception { + RangerPolicySource source = getPolicySource("hive", "dev_hive", "hiveServer2"); + + assertNotNull(source.getServicePoliciesIfUpdated(-1, -1), "failed to load policies for service=dev_hive, appId=hiveServer2"); + assertNotNull(source.getServiceTagsIfUpdated(-1, -1), "failed to load tags for service=dev_hive, appId=hiveServer2"); + assertNotNull(source.getRolesIfUpdated(-1, -1), "failed to load roles for service=dev_hive, appId=hiveServer2"); + assertNotNull(source.getUserStoreIfUpdated(-1, -1), "failed to load userStore for service=dev_hive, appId=hiveServer2"); + assertNotNull(source.getGdsInfoIfUpdated(-1, -1), "failed to load gdsInfo for service=dev_hive, appId=hiveServer2"); + } + + @Test + public void testLoadFailureWithNonExistingServiceName() throws Exception { + RangerPolicySource source = getPolicySource("s3", "test_s3", null); + + assertThrows(Exception.class, () -> source.getServicePoliciesIfUpdated(-1, -1), "expected to not find policies for service=test_s3, appId=null"); + assertThrows(Exception.class, () -> source.getServiceTagsIfUpdated(-1, -1), "expected to not find tags for service=test_s3, appId=null"); + assertThrows(Exception.class, () -> source.getRolesIfUpdated(-1, -1), "expected to not find roles for service=test_s3, appId=null"); + assertThrows(Exception.class, () -> source.getUserStoreIfUpdated(-1, -1), "expected to not find userStore for service=test_s3, appId=null"); + assertThrows(Exception.class, () -> source.getGdsInfoIfUpdated(-1, -1), "expected to not find gdsInfo for service=test_s3, appId=null"); + } + + @Test + public void testLoadFailureWithNonExistingServiceNameAndAppId() throws Exception { + RangerPolicySource source = getPolicySource("hive", "test_hive", "trino"); + + assertThrows(Exception.class, () -> source.getServicePoliciesIfUpdated(-1, -1), "expected to not find policies for service=test_hive, appId=trino"); + assertThrows(Exception.class, () -> source.getServiceTagsIfUpdated(-1, -1), "expected to not find tags for service=test_hive, appId=trino"); + assertThrows(Exception.class, () -> source.getRolesIfUpdated(-1, -1), "expected to not find roles for service=test_hive, appId=trino"); + assertThrows(Exception.class, () -> source.getUserStoreIfUpdated(-1, -1), "expected to not find userStore for service=test_hive, appId=trino"); + assertThrows(Exception.class, () -> source.getGdsInfoIfUpdated(-1, -1), "expected to not find gdsInfo for service=test_hive, appId=trino"); + } + + private RangerPolicySource getPolicySource(String serviceType, String serviceName, String appId) { + String propPrefix = "ranger.plugin." + serviceType; + Configuration conf = new Configuration(); + + conf.set(propPrefix + ".policy.source.local_folder.path", "src/test/resources/admin.client"); + + LocalFolderPolicySource source = new LocalFolderPolicySource(); + + source.init(serviceName, appId, propPrefix, conf); + + return source; + } +} diff --git a/agents-common/src/test/resources/admin.client/dev_s3.json b/agents-common/src/test/resources/admin.client/dev_s3.json new file mode 100644 index 0000000000..55b1640ee7 --- /dev/null +++ b/agents-common/src/test/resources/admin.client/dev_s3.json @@ -0,0 +1,7 @@ +{ + "serviceName": "dev_s3", + "policyVersion": 1, + "serviceDef": { }, + "policies": [ ], + "tagPolicies": { } +} \ No newline at end of file diff --git a/agents-common/src/test/resources/admin.client/dev_s3_gds.json b/agents-common/src/test/resources/admin.client/dev_s3_gds.json new file mode 100644 index 0000000000..bed0bc2bb5 --- /dev/null +++ b/agents-common/src/test/resources/admin.client/dev_s3_gds.json @@ -0,0 +1,9 @@ +{ + "serviceName": "dev_s3", + "gdsVersion": 1, + "gdsServiceDef": { }, + "datasets": [ ], + "dataShares": [ ], + "dshids": [ ], + "resources": [ ] +} \ No newline at end of file diff --git a/agents-common/src/test/resources/admin.client/dev_s3_roles.json b/agents-common/src/test/resources/admin.client/dev_s3_roles.json new file mode 100644 index 0000000000..f7009de721 --- /dev/null +++ b/agents-common/src/test/resources/admin.client/dev_s3_roles.json @@ -0,0 +1,5 @@ +{ + "serviceName": "dev_s3", + "roleVersion": 6, + "rangerRoles": [] +} diff --git a/agents-common/src/test/resources/admin.client/dev_s3_tag.json b/agents-common/src/test/resources/admin.client/dev_s3_tag.json new file mode 100644 index 0000000000..aad6df795e --- /dev/null +++ b/agents-common/src/test/resources/admin.client/dev_s3_tag.json @@ -0,0 +1,9 @@ +{ + "serviceName": "dev_s3", + "tagVersion": 2, + "op": "add_or_update", + "tagDefinitions": { }, + "tags": { }, + "serviceResources": [ ], + "resourceToTagIds": { } +} \ No newline at end of file diff --git a/agents-common/src/test/resources/admin.client/dev_s3_userstore.json b/agents-common/src/test/resources/admin.client/dev_s3_userstore.json new file mode 100644 index 0000000000..c307ee74f8 --- /dev/null +++ b/agents-common/src/test/resources/admin.client/dev_s3_userstore.json @@ -0,0 +1,6 @@ +{ + "userStoreVersion": 2, + "userAttrMapping": { }, + "groupAttrMapping": { }, + "userGroupMapping": { } +} \ No newline at end of file diff --git a/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive.json b/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive.json new file mode 100644 index 0000000000..9dc4824260 --- /dev/null +++ b/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive.json @@ -0,0 +1,7 @@ +{ + "serviceName": "dev_hive", + "policyVersion": 1, + "serviceDef": { }, + "policies": [ ], + "tagPolicies": { } +} \ No newline at end of file diff --git a/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_gds.json b/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_gds.json new file mode 100644 index 0000000000..70fa542484 --- /dev/null +++ b/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_gds.json @@ -0,0 +1,9 @@ +{ + "serviceName": "dev_hive", + "gdsVersion": 1, + "gdsServiceDef": { }, + "datasets": [ ], + "dataShares": [ ], + "dshids": [ ], + "resources": [ ] +} \ No newline at end of file diff --git a/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_roles.json b/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_roles.json new file mode 100644 index 0000000000..0cb430e875 --- /dev/null +++ b/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_roles.json @@ -0,0 +1,5 @@ +{ + "serviceName": "dev_hive", + "roleVersion": 6, + "rangerRoles": [] +} diff --git a/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_tag.json b/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_tag.json new file mode 100644 index 0000000000..3bb7c60e5d --- /dev/null +++ b/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_tag.json @@ -0,0 +1,9 @@ +{ + "serviceName": "dev_hive", + "tagVersion": 2, + "op": "add_or_update", + "tagDefinitions": { }, + "tags": { }, + "serviceResources": [ ], + "resourceToTagIds": { } +} \ No newline at end of file diff --git a/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_userstore.json b/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_userstore.json new file mode 100644 index 0000000000..c307ee74f8 --- /dev/null +++ b/agents-common/src/test/resources/admin.client/hiveServer2_dev_hive_userstore.json @@ -0,0 +1,6 @@ +{ + "userStoreVersion": 2, + "userAttrMapping": { }, + "groupAttrMapping": { }, + "userGroupMapping": { } +} \ No newline at end of file diff --git a/authz-embedded/src/test/resources/test_hive/hive_dev_hive.json b/authz-embedded/src/test/resources/test_hive/dev_hive.json similarity index 100% rename from authz-embedded/src/test/resources/test_hive/hive_dev_hive.json rename to authz-embedded/src/test/resources/test_hive/dev_hive.json diff --git a/authz-embedded/src/test/resources/test_hive/hive_dev_hive_gds.json b/authz-embedded/src/test/resources/test_hive/dev_hive_gds.json similarity index 100% rename from authz-embedded/src/test/resources/test_hive/hive_dev_hive_gds.json rename to authz-embedded/src/test/resources/test_hive/dev_hive_gds.json diff --git a/authz-embedded/src/test/resources/test_hive/hive_dev_hive_tag.json b/authz-embedded/src/test/resources/test_hive/dev_hive_tag.json similarity index 100% rename from authz-embedded/src/test/resources/test_hive/hive_dev_hive_tag.json rename to authz-embedded/src/test/resources/test_hive/dev_hive_tag.json diff --git a/authz-embedded/src/test/resources/test_s3/s3_dev_s3.json b/authz-embedded/src/test/resources/test_s3/dev_s3.json similarity index 100% rename from authz-embedded/src/test/resources/test_s3/s3_dev_s3.json rename to authz-embedded/src/test/resources/test_s3/dev_s3.json diff --git a/authz-embedded/src/test/resources/test_s3/s3_dev_s3_gds.json b/authz-embedded/src/test/resources/test_s3/dev_s3_gds.json similarity index 100% rename from authz-embedded/src/test/resources/test_s3/s3_dev_s3_gds.json rename to authz-embedded/src/test/resources/test_s3/dev_s3_gds.json diff --git a/authz-embedded/src/test/resources/test_s3/s3_dev_s3_roles.json b/authz-embedded/src/test/resources/test_s3/dev_s3_roles.json similarity index 100% rename from authz-embedded/src/test/resources/test_s3/s3_dev_s3_roles.json rename to authz-embedded/src/test/resources/test_s3/dev_s3_roles.json diff --git a/authz-embedded/src/test/resources/test_s3/s3_dev_s3_tag.json b/authz-embedded/src/test/resources/test_s3/dev_s3_tag.json similarity index 100% rename from authz-embedded/src/test/resources/test_s3/s3_dev_s3_tag.json rename to authz-embedded/src/test/resources/test_s3/dev_s3_tag.json