in detection_rules/beats.py [0:0]
def _flatten_schema(schema: list, prefix="") -> list:
if schema is None:
# sometimes we see `fields: null` in the yaml
return []
flattened = []
for s in schema:
if s.get("type") == "group":
nested_prefix = prefix + s["name"] + "."
# beats is complicated. it seems like we would expect a zoom.webhook.*, for the zoom.webhook dataset,
# but instead it's just at zoom.* directly.
#
# we have what looks like zoom.zoom.*, but should actually just be zoom.*.
# this is one quick heuristic to determine if a submodule nests fields at the parent.
# it's probably not perfect, but we can fix other bugs as we run into them later
if len(schema) == 1 and nested_prefix.startswith(prefix + prefix):
nested_prefix = s["name"] + "."
if "field" in s:
# integrations sometimes have a group with a single field
flattened.extend(_flatten_schema(s["field"], prefix=nested_prefix))
continue
elif "fields" not in s:
# integrations sometimes have a group with no fields
continue
flattened.extend(_flatten_schema(s["fields"], prefix=nested_prefix))
elif "fields" in s:
flattened.extend(_flatten_schema(s["fields"], prefix=prefix))
elif "name" in s:
s = s.copy()
# type is implicitly keyword if not defined
# example: https://github.com/elastic/beats/blob/main/packetbeat/_meta/fields.common.yml#L7-L12
s.setdefault("type", "keyword")
s["name"] = prefix + s["name"]
flattened.append(s)
return flattened