diff --git a/lib/cloud/metadata.rego b/lib/cloud/metadata.rego new file mode 100644 index 00000000..93a670b1 --- /dev/null +++ b/lib/cloud/metadata.rego @@ -0,0 +1,18 @@ +# METADATA +# custom: +# library: true +package lib.cloud.metadata + +import rego.v1 + +# Returns the object found by the given path +# if child object is not found, returns the last found object +obj_by_path(obj, path) := res if { + occurrenses := {obj_path: child_object | + walk(obj, [obj_path, child_object]) + child_object.__defsec_metadata + object.subset(path, obj_path) + } + + res := occurrenses[max(object.keys(occurrenses))] +} else := obj diff --git a/lib/cloud/metadata_test.rego b/lib/cloud/metadata_test.rego new file mode 100644 index 00000000..f62adc38 --- /dev/null +++ b/lib/cloud/metadata_test.rego @@ -0,0 +1,34 @@ +package lib.cloud.metadata_test + +import rego.v1 + +import data.lib.cloud.metadata + +test_obj_by_path_happy if { + bar := with_meta({"value": 1}) + obj := with_meta({"foo": with_meta({"bar": bar})}) + + metadata.obj_by_path(obj, ["foo", "bar"]) == bar +} + +test_obj_by_path_when_target_not_found_then_return_last_found if { + foo := with_meta({"bar": with_meta({"value": 1})}) + obj := with_meta({"foo": foo}) + + metadata.obj_by_path(obj, ["foo", "baz"]) == foo +} + +test_obj_by_path_when_target_not_found_then_return_obj if { + foo := with_meta({"bar": with_meta({"value": 1})}) + obj := with_meta({"foo": foo}) + + metadata.obj_by_path(obj, "baz") == obj +} + +test_obj_by_path_skip_without_metadata if { + obj := with_meta({"foo": {"bar": with_meta({"value": 1})}}) + + metadata.obj_by_path(obj, ["foo", "baz"]) == obj +} + +with_meta(obj) := object.union(obj, {"__defsec_metadata": {}})