blob: ba25f1326eac7d25f2e80649ddc7ae78b07997ed [file] [log] [blame]
/*
* 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.model.validation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ranger.plugin.errors.ValidationErrorCode;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerSecurityZone;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerSecurityZone.RangerSecurityZoneService;
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
import org.apache.ranger.plugin.policyengine.RangerResourceTrie;
import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.store.SecurityZoneStore;
import org.apache.ranger.plugin.store.ServiceStore;
import org.apache.ranger.plugin.util.SearchFilter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class RangerSecurityZoneValidator extends RangerValidator {
private static final Log LOG = LogFactory.getLog(RangerSecurityZoneValidator.class);
private final SecurityZoneStore securityZoneStore;
public RangerSecurityZoneValidator(ServiceStore store, SecurityZoneStore securityZoneStore) {
super(store);
this.securityZoneStore = securityZoneStore;
}
public void validate(RangerSecurityZone securityZone, Action action) throws Exception {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerPolicyValidator.validate(%s, %s)", securityZone, action));
}
List<ValidationFailureDetails> failures = new ArrayList<>();
boolean valid = isValid(securityZone, action, failures);
String message;
try {
if (!valid) {
message = serializeFailures(failures);
throw new Exception(message);
}
} finally {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerPolicyValidator.validate(%s, %s)", securityZone, action));
}
}
}
@Override
boolean isValid(String name, Action action, List<ValidationFailureDetails> failures) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s)", name, action, failures));
}
boolean ret = true;
if (action != Action.DELETE) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_UNSUPPORTED_ACTION;
failures.add(new ValidationFailureDetailsBuilder().isAnInternalError().becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build());
ret = false;
} else {
if (StringUtils.isEmpty(name)) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_FIELD;
failures.add(new ValidationFailureDetailsBuilder().becauseOf("security zone name was null/missing").field("name").isMissing().errorCode(error.getErrorCode()).becauseOf(error.getMessage("name")).build());
ret = false;
} else {
if (getSecurityZone(name) == null) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_ZONE_ID;
failures.add(new ValidationFailureDetailsBuilder().becauseOf("security zone does not exist").field("name").errorCode(error.getErrorCode()).becauseOf(error.getMessage(name)).build());
ret = false;
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerPolicyValidator.isValid(%s, %s, %s) : %s", name, action, failures, ret));
}
return ret;
}
@Override
boolean isValid(Long id, Action action, List<ValidationFailureDetails> failures) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s)", id, action, failures));
}
boolean ret = true;
if (action != Action.DELETE) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_UNSUPPORTED_ACTION;
failures.add(new ValidationFailureDetailsBuilder().isAnInternalError().becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build());
ret = false;
} else if (id == null) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_FIELD;
failures.add(new ValidationFailureDetailsBuilder().becauseOf("security zone id was null/missing").field("id").isMissing().errorCode(error.getErrorCode()).becauseOf(error.getMessage("id")).build());
ret = false;
} else if (getSecurityZone(id) == null) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_ZONE_ID;
failures.add(new ValidationFailureDetailsBuilder().becauseOf("security zone id does not exist").field("id").errorCode(error.getErrorCode()).becauseOf(error.getMessage(id)).build());
ret = false;
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerPolicyValidator.isValid(%s, %s, %s) : %s", id, action, failures, ret));
}
return ret;
}
boolean isValid(RangerSecurityZone securityZone, Action action, List<ValidationFailureDetails> failures) {
if(LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s)", securityZone, action, failures));
}
if (!(action == Action.CREATE || action == Action.UPDATE)) {
throw new IllegalArgumentException("isValid(RangerPolicy, ...) is only supported for create/update");
}
boolean ret = true;
RangerSecurityZone existingZone;
final String zoneName = securityZone.getName();
if (StringUtils.isEmpty(StringUtils.trim(zoneName))) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_FIELD;
failures.add(new ValidationFailureDetailsBuilder().becauseOf("security zone name was null/missing").field("name").isMissing().errorCode(error.getErrorCode()).becauseOf(error.getMessage("name")).build());
ret = false;
}
if (action == Action.CREATE) {
securityZone.setId(-1L);
existingZone = getSecurityZone(zoneName);
if (existingZone != null) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_NAME_CONFLICT;
failures.add(new ValidationFailureDetailsBuilder().becauseOf("security zone name exists").field("name").errorCode(error.getErrorCode()).becauseOf(error.getMessage(existingZone.getId())).build());
ret = false;
}
} else {
Long zoneId = securityZone.getId();
existingZone = getSecurityZone(zoneId);
if (existingZone == null) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_ZONE_ID;
failures.add(new ValidationFailureDetailsBuilder().becauseOf("security zone with id does not exist").field("id").errorCode(error.getErrorCode()).becauseOf(error.getMessage(zoneId)).build());
ret = false;
} else if (StringUtils.isNotEmpty(StringUtils.trim(zoneName)) && !StringUtils.equals(zoneName, existingZone.getName())) {
existingZone = getSecurityZone(zoneName);
if (existingZone != null) {
if (!StringUtils.equals(existingZone.getName(), zoneName)) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_NAME_CONFLICT;
failures.add(new ValidationFailureDetailsBuilder().becauseOf("security zone name").field("name").errorCode(error.getErrorCode()).becauseOf(error.getMessage(existingZone.getId())).build());
ret = false;
}
}
}
}
ret = ret && validateWithinSecurityZone(securityZone, action, failures);
ret = ret && validateAgainstAllSecurityZones(securityZone, action, failures);
if(LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerPolicyValidator.isValid(%s, %s, %s) : %s", securityZone, action, failures, ret));
}
return ret;
}
private boolean validateWithinSecurityZone(RangerSecurityZone securityZone, Action action, List<ValidationFailureDetails> failures) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerPolicyValidator.validateWithinSecurityZone(%s, %s, %s)", securityZone, action, failures));
}
boolean ret = true;
// Validate each service for existence, not being tag-service and each resource-spec for validity
if (MapUtils.isNotEmpty(securityZone.getServices())) {
for (Map.Entry<String, RangerSecurityZone.RangerSecurityZoneService> serviceSpecification : securityZone.getServices().entrySet()) {
String serviceName = serviceSpecification.getKey();
RangerSecurityZone.RangerSecurityZoneService securityZoneService = serviceSpecification.getValue();
ret = ret && validateSecurityZoneService(serviceName, securityZoneService, failures);
}
} else {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_SERVICES;
failures.add(new ValidationFailureDetailsBuilder().becauseOf("security zone services").isMissing().field("services").errorCode(error.getErrorCode()).becauseOf(error.getMessage(securityZone.getName())).build());
ret = false;
}
// both admin users and user-groups collections can't be empty
if (CollectionUtils.isEmpty(securityZone.getAdminUsers()) && CollectionUtils.isEmpty(securityZone.getAdminUserGroups())) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_USER_AND_GROUPS;
failures.add(new ValidationFailureDetailsBuilder().field("security zone admin users/user-groups").isMissing().becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build());
ret = false;
}
// both audit users and user-groups collections can't be empty
if (CollectionUtils.isEmpty(securityZone.getAuditUsers()) && CollectionUtils.isEmpty(securityZone.getAuditUserGroups())) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_USER_AND_GROUPS;
failures.add(new ValidationFailureDetailsBuilder().field("security zone audit users/user-groups").isMissing().becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build());
ret = false;
}
if (securityZone.getServices() != null) {
for (Map.Entry<String, RangerSecurityZoneService> serviceResouceMapEntry : securityZone.getServices()
.entrySet()) {
if (serviceResouceMapEntry.getValue().getResources() != null) {
for (Map<String, List<String>> resource : serviceResouceMapEntry.getValue().getResources()) {
if (resource != null) {
for (Map.Entry<String, List<String>> entry : resource.entrySet()) {
if (CollectionUtils.isEmpty(entry.getValue())) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_RESOURCES;
failures.add(new ValidationFailureDetailsBuilder().field("security zone resources")
.subField("resources").isMissing()
.becauseOf(error.getMessage(serviceResouceMapEntry.getKey()))
.errorCode(error.getErrorCode()).build());
ret = false;
}
}
}
}
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerPolicyValidator.validateWithinSecurityZone(%s, %s, %s) : %s", securityZone, action, failures, ret));
}
return ret;
}
private boolean validateAgainstAllSecurityZones(RangerSecurityZone securityZone, Action action, List<ValidationFailureDetails> failures) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerPolicyValidator.validateAgainstAllSecurityZones(%s, %s, %s)", securityZone, action, failures));
}
boolean ret = true;
final String zoneName;
if (securityZone.getId() != -1L) {
RangerSecurityZone existingZone = getSecurityZone(securityZone.getId());
zoneName = existingZone.getName();
} else {
zoneName = securityZone.getName();
}
for (Map.Entry<String, RangerSecurityZone.RangerSecurityZoneService> entry: securityZone.getServices().entrySet()) {
String serviceName = entry.getKey();
RangerSecurityZone.RangerSecurityZoneService serviceResources = entry.getValue();
if (CollectionUtils.isNotEmpty(serviceResources.getResources())) {
SearchFilter filter = new SearchFilter();
List<RangerSecurityZone> zones = null;
filter.setParam(SearchFilter.SERVICE_NAME, serviceName);
filter.setParam(SearchFilter.ZONE_NAME, zoneName);
try {
zones = securityZoneStore.getSecurityZones(filter);
} catch (Exception excp) {
LOG.error("Failed to get Security-Zones", excp);
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INTERNAL_ERROR;
failures.add(new ValidationFailureDetailsBuilder().becauseOf(error.getMessage(excp.getMessage())).errorCode(error.getErrorCode()).build());
ret = false;
}
if (CollectionUtils.isNotEmpty(zones)) {
RangerService service = getService(serviceName);
RangerServiceDef serviceDef = service != null ? getServiceDef(service.getType()) : null;
if (serviceDef == null) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INTERNAL_ERROR;
failures.add(new ValidationFailureDetailsBuilder().becauseOf(error.getMessage(serviceName)).errorCode(error.getErrorCode()).build());
ret = false;
} else {
zones.add(securityZone);
ret = ret && validateZoneServiceInAllZones(zones, serviceName, serviceDef, failures);
}
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerPolicyValidator.validateAgainstAllSecurityZones(%s, %s, %s) : %s", securityZone, action, failures, ret));
}
return ret;
}
private boolean validateZoneServiceInAllZones(List<RangerSecurityZone> zones, String serviceName, RangerServiceDef serviceDef, List<ValidationFailureDetails> failures) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerPolicyValidator.validateZoneServiceInAllZones(%s, %s, %s, %s)", zones, serviceName, serviceDef, failures));
}
boolean ret = true;
// For each zone, get list-of-resources corresponding to serviceName.
// For each list-of-resources:
// get one resource (this is a map of <String, List<String>>); convert it into map of <String, RangerPolicyResource>. excludes is always false, recursive true only for HDFS
// build a subclass of RangerPolicyResourceEvaluator with id of zone, zoneName as a member, and RangerDefaultResourceMatcher as matcher.
// add this to list-of-evaluators
Map<String, List<RangerZoneResourceMatcher>> matchersForResourceDef = new HashMap<>();
for (RangerSecurityZone zone : zones) {
List<HashMap<String, List<String>>> resources = zone.getServices().get(serviceName).getResources();
for (Map<String, List<String>> resource : resources) {
Map<String, RangerPolicy.RangerPolicyResource> policyResources = new HashMap<>();
for (Map.Entry<String, List<String>> entry : resource.entrySet()) {
String resourceDefName = entry.getKey();
List<String> resourceValues = entry.getValue();
RangerPolicy.RangerPolicyResource policyResource = new RangerPolicy.RangerPolicyResource();
policyResource.setIsExcludes(false);
policyResource.setIsRecursive(StringUtils.equals(serviceDef.getName(), EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HDFS_NAME));
policyResource.setValues(resourceValues);
policyResources.put(resourceDefName, policyResource);
if (matchersForResourceDef.get(resourceDefName) == null) {
matchersForResourceDef.put(resourceDefName, new ArrayList<>());
}
}
RangerZoneResourceMatcher matcher = new RangerZoneResourceMatcher(zone.getName(), policyResources, serviceDef);
for (String resourceDefName : resource.keySet()) {
matchersForResourceDef.get(resourceDefName).add(matcher);
}
}
}
// Build a map of trie with list-of-evaluators with one entry corresponds to one resource-def if it exists in the list-of-resources
Map<String, RangerResourceTrie<RangerZoneResourceMatcher>> trieMap = new HashMap<>();
List<RangerServiceDef.RangerResourceDef> resourceDefs = serviceDef.getResources();
for (Map.Entry<String, List<RangerZoneResourceMatcher>> entry : matchersForResourceDef.entrySet()) {
String resourceDefName = entry.getKey();
List<RangerZoneResourceMatcher> matchers = entry.getValue();
RangerServiceDef.RangerResourceDef resourceDef = null;
for (RangerServiceDef.RangerResourceDef element : resourceDefs) {
if (StringUtils.equals(element.getName(), resourceDefName)) {
resourceDef = element;
break;
}
}
trieMap.put(entry.getKey(), new RangerResourceTrie<>(resourceDef, matchers));
}
// For each zone, get list-of-resources corresponding to serviceName
// For each list-of-resources:
// get one resource; for each level in the resource, run it through map of trie and get possible evaluators.
// check each evaluator to see if the resource-match actually happens. If yes then add the zone-evaluator to matching evaluators.
// flag error if there are more than one matching evaluators with different zone-ids.
//
for (RangerSecurityZone zone : zones) {
List<HashMap<String, List<String>>> resources = zone.getServices().get(serviceName).getResources();
for (Map<String, List<String>> resource : resources) {
List<Set<RangerZoneResourceMatcher>> zoneMatchersList = null;
Set<RangerZoneResourceMatcher> smallestList = null;
for (Map.Entry<String, List<String>> entry : resource.entrySet()) {
String resourceDefName = entry.getKey();
List<String> resourceValues = entry.getValue();
RangerResourceTrie<RangerZoneResourceMatcher> trie = trieMap.get(resourceDefName);
Set<RangerZoneResourceMatcher> matchedZones = trie.getEvaluatorsForResource(resourceValues);
if (LOG.isDebugEnabled()) {
LOG.debug("ResourceDefName:[" + resourceDefName +"], values:[" + resourceValues +"], matched-zones:[" + matchedZones +"]");
}
if (CollectionUtils.isEmpty(matchedZones)) { // no policies for this resource, bail out
zoneMatchersList = null;
smallestList = null;
break;
}
if (smallestList == null) {
smallestList = matchedZones;
} else {
if (zoneMatchersList == null) {
zoneMatchersList = new ArrayList<>();
zoneMatchersList.add(smallestList);
}
zoneMatchersList.add(matchedZones);
if (smallestList.size() > matchedZones.size()) {
smallestList = matchedZones;
}
}
}
if (smallestList == null) {
continue;
}
final Set<RangerZoneResourceMatcher> intersection;
if (zoneMatchersList != null) {
intersection = new HashSet<>(smallestList);
for (Set<RangerZoneResourceMatcher> zoneMatchers : zoneMatchersList) {
if (zoneMatchers != smallestList) {
// remove zones from intersection that are not in zoneMatchers
intersection.retainAll(zoneMatchers);
if (CollectionUtils.isEmpty(intersection)) { // if no zoneMatcher exists, bail out and return empty list
break;
}
}
}
} else {
intersection = smallestList;
}
if (LOG.isDebugEnabled()) {
LOG.debug("Resource:[" + resource +"], matched-zones:[" + intersection +"]");
}
if (intersection.size() <= 1) {
continue;
}
RangerAccessResourceImpl accessResource = new RangerAccessResourceImpl();
accessResource.setServiceDef(serviceDef);
for (Map.Entry<String, List<String>> entry : resource.entrySet()) {
accessResource.setValue(entry.getKey(), entry.getValue());
}
Set<String> matchedZoneNames = new HashSet<>();
for (RangerZoneResourceMatcher zoneMatcher : intersection) {
if (LOG.isDebugEnabled()) {
LOG.debug("Trying to match resource:[" + accessResource +"] using zoneMatcher:[" + zoneMatcher + "]");
}
// These are potential matches. Try to really match them
if (zoneMatcher.getPolicyResourceMatcher().isMatch(accessResource, RangerPolicyResourceMatcher.MatchScope.ANY, null)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Matched resource:[" + accessResource +"] using zoneMatcher:[" + zoneMatcher + "]");
}
// Actual match happened
matchedZoneNames.add(zoneMatcher.getSecurityZoneName());
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Did not match resource:[" + accessResource +"] using zoneMatcher:[" + zoneMatcher + "]");
}
}
}
LOG.info("The following zone-names matched resource:[" + resource + "]: " + matchedZoneNames);
if (matchedZoneNames.size() > 1) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT;
failures.add(new ValidationFailureDetailsBuilder().becauseOf(error.getMessage(matchedZoneNames, resource)).errorCode(error.getErrorCode()).build());
ret = false;
break;
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerPolicyValidator.validateZoneServiceInAllZones(%s, %s, %s, %s) : %s", zones, serviceName, serviceDef, failures, ret));
}
return ret;
}
private boolean validateSecurityZoneService(String serviceName, RangerSecurityZone.RangerSecurityZoneService securityZoneService, List<ValidationFailureDetails> failures) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerPolicyValidator.validateSecurityZoneService(%s, %s, %s)", serviceName, securityZoneService, failures));
}
boolean ret = true;
// Verify service with serviceName exists - get the service-type
RangerService service = getService(serviceName);
if (service == null) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_SERVICE_NAME;
failures.add(new ValidationFailureDetailsBuilder().field("security zone resource service-name").becauseOf(error.getMessage(serviceName)).errorCode(error.getErrorCode()).build());
ret = false;
} else {
RangerServiceDef serviceDef = getServiceDef(service.getType());
if (serviceDef == null) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_SERVICE_TYPE;
failures.add(new ValidationFailureDetailsBuilder().field("security zone resource service-type").becauseOf(error.getMessage(service.getType())).errorCode(error.getErrorCode()).build());
ret = false;
} else {
String serviceType = serviceDef.getName();
if (StringUtils.equals(serviceType, EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME)) {
if (CollectionUtils.isNotEmpty(securityZoneService.getResources())) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_UNEXPECTED_RESOURCES;
failures.add(new ValidationFailureDetailsBuilder().field("security zone resources").becauseOf(error.getMessage(serviceName)).errorCode(error.getErrorCode()).build());
ret = false;
}
} else {
if (CollectionUtils.isEmpty(securityZoneService.getResources())) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_RESOURCES;
failures.add(new ValidationFailureDetailsBuilder().field("security zone resources").isMissing().becauseOf(error.getMessage(serviceName)).errorCode(error.getErrorCode()).build());
ret = false;
} else {
// For each resource-spec, verify that it forms valid hierarchy for some policy-type
for (Map<String, List<String>> resource : securityZoneService.getResources()) {
Set<String> resourceDefNames = resource.keySet();
RangerServiceDefHelper serviceDefHelper = new RangerServiceDefHelper(serviceDef);
boolean isValidHierarchy = false;
for (int policyType : RangerPolicy.POLICY_TYPES) {
Set<List<RangerServiceDef.RangerResourceDef>> resourceHierarchies = serviceDefHelper.getResourceHierarchies(policyType, resourceDefNames);
if (LOG.isDebugEnabled()) {
LOG.debug("Size of resourceHierarchies for resourceDefNames:[" + resourceDefNames + ", policyType=" + policyType + "] = " + resourceHierarchies.size());
}
for (List<RangerServiceDef.RangerResourceDef> resourceHierarchy : resourceHierarchies) {
if (RangerDefaultPolicyResourceMatcher.isHierarchyValidForResources(resourceHierarchy, resource)) {
isValidHierarchy = true;
break;
} else {
LOG.info("gaps found in resource, skipping hierarchy:[" + resourceHierarchies + "]");
}
}
}
if (!isValidHierarchy) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_RESOURCE_HIERARCHY;
failures.add(new ValidationFailureDetailsBuilder().field("security zone resource hierarchy").becauseOf(error.getMessage(serviceName, resourceDefNames)).errorCode(error.getErrorCode()).build());
ret = false;
}
/*
* Ignore this check. It should be possible to have all wildcard resource in a zone if zone-admin so desires
*
boolean isValidResourceSpec = isAnyNonWildcardResource(resource, failures);
if (!isValidResourceSpec) {
ValidationErrorCode error = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ALL_WILDCARD_RESOURCE_VALUES;
failures.add(new ValidationFailureDetailsBuilder().field("security zone resource values").becauseOf(error.getMessage(serviceName)).errorCode(error.getErrorCode()).build());
ret = false;
LOG.warn("RangerPolicyValidator.validateSecurityZoneService() : All wildcard resource-values specified for service :[" + serviceName + "]");
}
*/
}
}
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerPolicyValidator.validateSecurityZoneService(%s, %s, %s) : %s", serviceName, securityZoneService, failures, ret));
}
return ret;
}
/*
private boolean isAnyNonWildcardResource(Map<String, List<String>> resource, List<ValidationFailureDetails> failures) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerPolicyValidator.isAnyNonWildcardResource(%s, %s)", resource, failures));
}
boolean ret = false;
for (Map.Entry<String, List<String>> resourceDefValue : resource.entrySet()) {
boolean wildCardResourceFound = false;
List<String> resourceValues = resourceDefValue.getValue();
for (String resourceValue : resourceValues) {
if (StringUtils.equals(resourceValue, RangerDefaultResourceMatcher.WILDCARD_ASTERISK)) {
wildCardResourceFound = true;
break;
}
}
if (!wildCardResourceFound) {
ret = true;
break;
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerPolicyValidator.isAnyNonWildcardResource(%s, %s) : %s", resource, failures, ret));
}
return ret;
}
*/
}