use of org.apache.ranger.plugin.errors.ValidationErrorCode in project ranger by apache.
the class RangerPolicyValidator method isValidResourceNames.
boolean isValidResourceNames(final RangerPolicy policy, final List<ValidationFailureDetails> failures, final RangerServiceDef serviceDef) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerPolicyValidator.isValidResourceNames(%s, %s, %s)", policy, failures, serviceDef));
}
boolean valid = true;
Set<String> policyResources = getPolicyResources(policy);
RangerServiceDefHelper defHelper = new RangerServiceDefHelper(serviceDef);
// this can be empty but not null!
Set<List<RangerResourceDef>> hierarchies = defHelper.getResourceHierarchies(policy.getPolicyType());
if (hierarchies.isEmpty()) {
if (LOG.isDebugEnabled()) {
LOG.debug("RangerPolicyValidator.isValidResourceNames: serviceDef does not have any resource hierarchies, possibly due to invalid service def!!");
}
ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_RESOURCE_NO_COMPATIBLE_HIERARCHY;
failures.add(new ValidationFailureDetailsBuilder().field("service def resource hierarchies").subField("incompatible").isSemanticallyIncorrect().becauseOf(error.getMessage(serviceDef.getName(), " does not have any resource hierarchies")).errorCode(error.getErrorCode()).build());
valid = false;
} else {
/*
* A policy is for a single hierarchy however, it doesn't specify which one. So we have to guess which hierarchy(s) it possibly be for. First, see if the policy could be for
* any of the known hierarchies? A candidate hierarchy is one whose resource levels are a superset of those in the policy.
* Why? What we want to catch at this stage is policies that straddles multiple hierarchies, e.g. db, udf and column for a hive policy.
* This has the side effect of catch spurious levels specified on the policy, e.g. having a level "blah" on a hive policy.
*/
Set<List<RangerResourceDef>> candidateHierarchies = filterHierarchies_hierarchyHasAllPolicyResources(policyResources, hierarchies, defHelper);
if (candidateHierarchies.isEmpty()) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("No compatible resource hierarchies found: resource[%s], service-def[%s], valid-resource-hierarchies[%s]", policyResources.toString(), serviceDef.getName(), toStringHierarchies_all(hierarchies, defHelper)));
}
ValidationErrorCode error;
if (hierarchies.size() == 1) {
// we can give a simpler message for single hierarchy service-defs which is the majority of cases
error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_RESOURCE_NO_COMPATIBLE_HIERARCHY_SINGLE;
} else {
error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_RESOURCE_NO_COMPATIBLE_HIERARCHY;
}
failures.add(new ValidationFailureDetailsBuilder().field("policy resources").subField("incompatible").isSemanticallyIncorrect().becauseOf(error.getMessage(serviceDef.getName(), toStringHierarchies_all(hierarchies, defHelper))).errorCode(error.getErrorCode()).build());
valid = false;
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("isValidResourceNames: Found [" + candidateHierarchies.size() + "] compatible hierarchies: " + toStringHierarchies_all(candidateHierarchies, defHelper));
}
/*
* Among the candidate hierarchies there should be at least one for which policy specifies all of the mandatory resources. Note that there could be multiple
* hierarchies that meet that criteria, e.g. a hive policy that specified only DB. It is not clear if it belongs to DB->UDF or DB->TBL->COL hierarchy.
* However, if both UDF and TBL were required then we can detect that policy does not specify mandatory levels for any of the candidate hierarchies.
*/
Set<List<RangerResourceDef>> validHierarchies = filterHierarchies_mandatoryResourcesSpecifiedInPolicy(policyResources, candidateHierarchies, defHelper);
if (validHierarchies.isEmpty()) {
ValidationErrorCode error;
if (candidateHierarchies.size() == 1) {
// we can provide better message if there is a single candidate hierarchy
error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_RESOURCE_MISSING_MANDATORY_SINGLE;
} else {
error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_RESOURCE_MISSING_MANDATORY;
}
failures.add(new ValidationFailureDetailsBuilder().field("policy resources").subField("missing mandatory").isSemanticallyIncorrect().becauseOf(error.getMessage(serviceDef.getName(), toStringHierarchies_mandatory(candidateHierarchies, defHelper))).errorCode(error.getErrorCode()).build());
valid = false;
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("isValidResourceNames: Found hierarchies with all mandatory fields specified: " + toStringHierarchies_mandatory(validHierarchies, defHelper));
}
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerPolicyValidator.isValidResourceNames(%s, %s, %s): %s", policy, failures, serviceDef, valid));
}
return valid;
}
use of org.apache.ranger.plugin.errors.ValidationErrorCode in project ranger by apache.
the class RangerPolicyValidator method isPolicyResourceUnique.
boolean isPolicyResourceUnique(RangerPolicy policy, final List<ValidationFailureDetails> failures, Action action) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerPolicyValidator.isPolicyResourceUnique(%s, %s, %s)", policy, failures, action));
}
boolean valid = true;
if (!Boolean.TRUE.equals(policy.getIsEnabled())) {
LOG.debug("Policy is disabled. Skipping resource uniqueness validation.");
} else {
RangerPolicyResourceSignature policySignature = _factory.createPolicyResourceSignature(policy);
String signature = policySignature.getSignature();
List<RangerPolicy> policies = getPoliciesForResourceSignature(policy.getService(), signature);
if (CollectionUtils.isNotEmpty(policies)) {
ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_DUPLICATE_POLICY_RESOURCE;
RangerPolicy matchedPolicy = policies.iterator().next();
// there shouldn't be a matching policy for create. During update only match should be to itself
if (action == Action.CREATE || (action == Action.UPDATE && (policies.size() > 1 || !matchedPolicy.getId().equals(policy.getId())))) {
failures.add(new ValidationFailureDetailsBuilder().field("resources").isSemanticallyIncorrect().becauseOf(error.getMessage(matchedPolicy.getName(), policy.getService())).errorCode(error.getErrorCode()).build());
valid = false;
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerPolicyValidator.isPolicyResourceUnique(%s, %s, %s): %s", policy, failures, action, valid));
}
return valid;
}
use of org.apache.ranger.plugin.errors.ValidationErrorCode in project ranger by apache.
the class RangerServiceDefValidator method isValid.
boolean isValid(final Long id, final Action action, final List<ValidationFailureDetails> failures) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerServiceDefValidator.isValid(" + id + ")");
}
boolean valid = true;
if (action != Action.DELETE) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_UNSUPPORTED_ACTION;
failures.add(new ValidationFailureDetailsBuilder().isAnInternalError().errorCode(error.getErrorCode()).becauseOf(error.getMessage(action)).build());
valid = false;
} else if (id == null) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_MISSING_FIELD;
failures.add(new ValidationFailureDetailsBuilder().field("id").isMissing().errorCode(error.getErrorCode()).becauseOf(error.getMessage("id")).build());
valid = false;
} else if (getServiceDef(id) == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("No service found for id[" + id + "]! ok!");
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerServiceDefValidator.isValid(" + id + "): " + valid);
}
return valid;
}
use of org.apache.ranger.plugin.errors.ValidationErrorCode in project ranger by apache.
the class RangerServiceDefValidator method isValidResources.
boolean isValidResources(RangerServiceDef serviceDef, List<ValidationFailureDetails> failures) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerServiceDefValidator.isValidResources(%s, %s)", serviceDef, failures));
}
boolean valid = true;
List<RangerResourceDef> resources = serviceDef.getResources();
if (CollectionUtils.isEmpty(resources)) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_MISSING_FIELD;
failures.add(new ValidationFailureDetailsBuilder().field("resources").isMissing().errorCode(error.getErrorCode()).becauseOf(error.getMessage("resources")).build());
valid = false;
} else {
Set<String> names = new HashSet<String>(resources.size());
Set<Long> ids = new HashSet<Long>(resources.size());
for (RangerResourceDef resource : resources) {
/*
* While id is the natural key, name is a surrogate key. At several places code expects resource name to be unique within a service.
*/
valid = isUnique(resource.getName(), names, "resource name", "resources", failures) && valid;
valid = isUnique(resource.getItemId(), ids, "resource itemId", "resources", failures) && valid;
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerServiceDefValidator.isValidResources(%s, %s): %s", serviceDef, failures, valid));
}
return valid;
}
use of org.apache.ranger.plugin.errors.ValidationErrorCode in project ranger by apache.
the class RangerServiceDefValidator method isValidEnums.
boolean isValidEnums(List<RangerEnumDef> enumDefs, List<ValidationFailureDetails> failures) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==> RangerServiceDefValidator.isValidEnums(%s, %s)", enumDefs, failures));
}
boolean valid = true;
if (CollectionUtils.isEmpty(enumDefs)) {
LOG.debug("enum def collection passed in was null/empty. Ok.");
} else {
Set<String> names = new HashSet<>();
Set<Long> ids = new HashSet<>();
for (RangerEnumDef enumDef : enumDefs) {
if (enumDef == null) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_ENUM_DEF_NULL_OBJECT;
failures.add(new ValidationFailureDetailsBuilder().field("enum def").isMissing().errorCode(error.getErrorCode()).becauseOf(error.getMessage()).build());
valid = false;
} else {
// enum-names and ids must non-blank and be unique to a service definition
String enumName = enumDef.getName();
valid = isUnique(enumName, names, "enum def name", "enum defs", failures) && valid;
valid = isUnique(enumDef.getItemId(), ids, "enum def itemId", "enum defs", failures) && valid;
// enum must contain at least one valid value and those values should be non-blank and distinct
if (CollectionUtils.isEmpty(enumDef.getElements())) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_ENUM_DEF_NO_VALUES;
failures.add(new ValidationFailureDetailsBuilder().field("enum values").subField(enumName).isMissing().errorCode(error.getErrorCode()).becauseOf(error.getMessage(enumName)).build());
valid = false;
} else {
valid = isValidEnumElements(enumDef.getElements(), failures, enumName) && valid;
// default index should be valid
int defaultIndex = getEnumDefaultIndex(enumDef);
if (defaultIndex < 0 || defaultIndex >= enumDef.getElements().size()) {
// max index is one less than the size of the elements list
ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_ENUM_DEF_INVALID_DEFAULT_INDEX;
failures.add(new ValidationFailureDetailsBuilder().field("enum default index").subField(enumName).isSemanticallyIncorrect().errorCode(error.getErrorCode()).becauseOf(error.getMessage(defaultIndex, enumName)).build());
valid = false;
}
}
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("<== RangerServiceDefValidator.isValidEnums(%s, %s): %s", enumDefs, failures, valid));
}
return valid;
}
Aggregations