98 lines
4.3 KiB
Plaintext
98 lines
4.3 KiB
Plaintext
package before_resolution
|
|
import rego.v1
|
|
|
|
# This file enforces policies requiring all attributes to be defined within
|
|
# a semantic convention "registry". This is a naming/structure convention
|
|
# used by semantic conventions.
|
|
|
|
# Helper to create attribute registry violations.
|
|
attr_registry_violation(description, group_id, attr_id) = violation if {
|
|
violation := {
|
|
"id": description,
|
|
"type": "semconv_attribute",
|
|
"category": "attribute_registry_checks",
|
|
"group": group_id,
|
|
"attr": attr_id,
|
|
}
|
|
}
|
|
|
|
# We only allow attribute groups in the attribute registry.
|
|
deny contains attr_registry_violation(description, group.id, "") if {
|
|
group := input.groups[_]
|
|
startswith(group.id, "registry.")
|
|
group.type != "attribute_group"
|
|
|
|
# TODO (https://github.com/open-telemetry/weaver/issues/279): provide other violation properties once weaver supports it.
|
|
# violation_id := "attribute_registry_can_only_contain_attribute_groups"
|
|
description := sprintf("Registry group '%s' has invalid type '%s'. Groups in attribute registry must have `attribute_group` type.", [group.id, group.type])
|
|
}
|
|
|
|
# Any group that is NOT in the attribute registry that has an attribute id is
|
|
# in violation of not using the attribute registry.
|
|
deny contains attr_registry_violation(description, group.id, attr.id) if {
|
|
group := input.groups[_]
|
|
not startswith(group.id, "registry.")
|
|
attr := group.attributes[_]
|
|
attr.id != null
|
|
|
|
attr_name := get_attribute_name(attr, group)
|
|
|
|
# TODO (https://github.com/open-telemetry/weaver/issues/279): provide other violation properties once weaver supports it.
|
|
# violation_id := "attributes_must_be_defined_in_attribute_registry"
|
|
description := sprintf("Attribute '%s' is defined in the group '%s' which is not part of the attribute registry. Attributes can be defined in the registry group only.", [attr_name, group.id])
|
|
}
|
|
|
|
# A registry `attribute_group` containing at least one `ref` attribute is
|
|
# considered invalid if it's not in the registry group.
|
|
deny contains attr_registry_violation(description, group.id, attr.ref) if {
|
|
# TODO - this will need to be updated to support `embed` in the future.
|
|
group := input.groups[_]
|
|
startswith(group.id, "registry.")
|
|
attr := group.attributes[_]
|
|
attr.ref != null
|
|
|
|
# TODO (https://github.com/open-telemetry/weaver/issues/279): provide other violation properties once weaver supports it.
|
|
# violation_id := "attributes_in_registry_cannot_reference_each_other"
|
|
description := sprintf("Registry group '%s' references attribute '%s'. Registry groups can only define new attributes.", [group.id, attr.ref])
|
|
}
|
|
|
|
# We don't allow attribute definitions to have requirement_level
|
|
deny contains attr_registry_violation(description, group.id, attr.id) if {
|
|
group := input.groups[_]
|
|
startswith(group.id, "registry.")
|
|
|
|
attr := group.attributes[_]
|
|
|
|
# TODO: requirement_level defaults to recommended - no way to check if it's not set.
|
|
attr.requirement_level != "recommended"
|
|
|
|
# TODO (https://github.com/open-telemetry/weaver/issues/279): provide other violation properties once weaver supports it.
|
|
description := sprintf("Attribute definition '%s' has requirement_level set to %s. Only attribute references can set requirement_level.", [attr.id, attr.requirement_level])
|
|
}
|
|
|
|
# We require attribute definitions to have stability
|
|
deny contains attr_registry_violation(description, group.id, attr.id) if {
|
|
group := input.groups[_]
|
|
attr := group.attributes[_]
|
|
not attr.stability
|
|
description := sprintf("Attribute definition '%s' does not contain stability field. All attribute definitions must include stability level.", [attr.id])
|
|
}
|
|
|
|
# We require span, metrics, events, resources definitions to have stability
|
|
deny contains attr_registry_violation(description, group.id, "") if {
|
|
semconv_types := {"span", "metric", "event", "resource"}
|
|
group := input.groups[_]
|
|
|
|
semconv_types[group.type] != null
|
|
|
|
not group.stability
|
|
description := sprintf("Semconv group '%s' does not contain stability field. All semconv definitions must include stability level.", [group.id])
|
|
}
|
|
|
|
get_attribute_name(attr, group) := name if {
|
|
full_name := concat(".", [group.prefix, attr.id])
|
|
|
|
# if there was no prefix, we have a leading dot
|
|
name := trim(full_name, ".")
|
|
}
|