diff --git a/kernelci/api/helper.py b/kernelci/api/helper.py index 8dfb9cb475..6a1c667651 100644 --- a/kernelci/api/helper.py +++ b/kernelci/api/helper.py @@ -162,12 +162,25 @@ def _is_allowed(self, rules, key, node): # Find the node (or ancestor node) attribute corresponding to the # rule we're applying base = self._find_container(key, node) - if not base: - return True deny = [f.lstrip('!') for f in rules[key] if f.startswith('!')] allow = [f for f in rules[key] if not f.startswith('!')] + # If the parameter (key) associated to a given rule cannot be found + # in the current hierarchy, there are two cases: + # * the rule only excludes certain values (no allowed value, only + # denied ones): as the parameter doesn't exist, it can't use a + # denied value, so we can proceed with creating the node + # * the rule does have an allow-list: here we can assume that the + # parameter is REQUIRED to have one of the allowed values, and + # therefore MUST exist; if it doesn't, then we shouldn't create + # the node on the basis that its rules aren; t fulfilled + if not base: + if len(allow) > 0: + print(f"rules[{key}]: attribute '{key}' not found in node hierarchy") + return False + return True + # Rules are appied depending on how the data is initially stored: # * if it's a list (e.g. config fragments), then it must contain # at least one element from the allow-list; additionally, none @@ -185,18 +198,18 @@ def _is_allowed(self, rules, key, node): for item in base[key]: if item in deny: - print(f"rules{key}: {key.capitalize()} {item} not allowed due {deny}") + print(f"rules[{key}]: {key.capitalize()} {item} not allowed due !{deny}") return False if item in allow: found = True if not found: - print(f"rules: {key.capitalize()} missing one of {allow}") + print(f"rules[{key}]: {key.capitalize()} missing one of {allow}") return False else: if base[key] in deny or (len(allow) > 0 and base[key] not in allow): - print(f"rule[{key}]: {key.capitalize()} {base[key]} not allowed due {deny}") + print(f"rules[{key}]: {key.capitalize()} {base[key]} not allowed due !{deny}") return False return True @@ -277,20 +290,20 @@ def _is_tree_branch_allowed(self, node, rules): break match = self._match_combos(node, deny_combos) if match: - print(f"Tree/branch combination " + print(f"rules[{key}]: Tree/branch combination " f"{match['tree']}/{match['branch']} not allowed") return False # Get back to regular allow/deny list processing if node[key] in deny: - print(f"{key.capitalize()} {node[key]} not allowed due {deny}") + print(f"rules[{key}]: {key.capitalize()} {node[key]} not allowed due !{deny}") return False if (len(allow) == 0 and len(allow_combos) > 0): - print(f"{key.capitalize()} {node[key]} not allowed due" + print(f"rules[{key}]: {key.capitalize()} {node[key]} not allowed due" f" to tree/branch rules") return False if (len(allow) > 0 and node[key] not in allow): - print(f"{key.capitalize()} {node[key]} not allowed due {allow}") + print(f"rules[{key}]: {key.capitalize()} {node[key]} not allowed due {allow}") return False return True @@ -379,13 +392,13 @@ def should_create_node(self, rules, node): if (key.startswith('min') and ((major < rule_major) or (major == rule_major and minor < rule_minor))): - print(f"rules: Version {major}.{minor} older than minimum version " + print(f"rules[{key}]: Version {major}.{minor} older than minimum version " f"({rule_major}.{rule_minor})") return False if (key.startswith('max') and ((major > rule_major) or (major == rule_major and minor > rule_minor))): - print(f"rules: Version {major}.{minor} more recent than maximum version " + print(f"rules[{key}]: Version {major}.{minor} newer than maximum version " f"({rule_major}.{rule_minor})") return False