semantic-conventions/policies/attribute_name_collisions.rego

93 lines
2.9 KiB
Plaintext

package after_resolution
import rego.v1
# Data structures to make checking things faster.
attribute_names := { obj |
group := input.groups[_];
attr := group.attributes[_];
obj := { "name": attr.name, "const_name": to_const_name(attr.name), "namespace_prefix": to_namespace_prefix(attr.name), "deprecated": is_property_set(attr, "deprecated"), "annotations": property_or_null(attr, "annotations") }
}
# check that attribute constant names do not collide
deny contains attr_registry_collision(description, name) if {
some i
name := attribute_names[i].name
const_name := attribute_names[i].const_name
annotations := attribute_names[i].annotations
not annotations["code_generation"]["exclude"]
collisions := [other.name |
other := attribute_names[_]
other.name != name
other.const_name == const_name
not other.annotations["code_generation"]["exclude"]
]
count(collisions) > 0
# TODO (https://github.com/open-telemetry/weaver/issues/279): provide other violation properties once weaver supports it.
description := sprintf("Attribute '%s' has the same constant name '%s' as '%s'.", [name, const_name, collisions])
}
# check that attribute names do not collide with namespaces
deny contains attr_registry_collision(description, name) if {
some i
# ignore deprecated attributes
not attribute_names[i].deprecated
name := attribute_names[i].name
prefix := attribute_names[i].namespace_prefix
collisions := [other.name |
other := attribute_names[_]
not other.deprecated
other.name != name
startswith(other.name, prefix)
]
count(collisions) > 0
# TODO (https://github.com/open-telemetry/weaver/issues/279): provide other violation properties once weaver supports it.
description := sprintf("Attribute '%s' name is used as a namespace in the following attributes '%s'.", [name, collisions])
}
# check that attribute is not defined or referenced more than once within the same group
deny contains attr_registry_collision(description, name) if {
group := input.groups[_]
attr := group.attributes[_]
name := attr.name
collisions := [n | n := group.attributes[_].name; n == name ]
count(collisions) > 1
description := sprintf("Attribute '%s' is already defined in the group '%s'. Attributes must be unique.", [name, group.id])
}
attr_registry_collision(description, attr_name) = violation if {
violation := {
"id": description,
"type": "semconv_attribute",
"category": "naming_collision",
"attr": attr_name,
"group": "",
}
}
to_namespace_prefix(name) = namespace if {
namespace := concat("", [name, "."])
}
to_const_name(name) = const_name if {
const_name := replace(name, ".", "_")
}
is_property_set(obj, property) = true if {
obj[property] != null
} else = false
property_or_null(obj, property) := obj[property] if {
obj[property]
} else = null