93 lines
2.9 KiB
Plaintext
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
|