diff --git a/lib/cloud/metadata.rego b/lib/cloud/metadata.rego new file mode 100644 index 00000000..a858635d --- /dev/null +++ b/lib/cloud/metadata.rego @@ -0,0 +1,19 @@ +# 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, str_path) := res if { + path := split(str_path, ".") + 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..4e284132 --- /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": {}})