Add attribute name and const names checks (#1209)
This commit is contained in:
parent
aea69f203f
commit
d182f9e66f
|
|
@ -108,3 +108,10 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
make generate-gh-issue-templates
|
make generate-gh-issue-templates
|
||||||
git diff --exit-code '.github/ISSUE_TEMPLATE' || (echo 'Dropdowns in issue templates is out of date, please run "make generate-gh-issue-templates" and commit the changes in this PR. Please note, if you are running it on Mac OS X, please make sure to use GNU version of sed instead of default "sed".' && exit 1)
|
git diff --exit-code '.github/ISSUE_TEMPLATE' || (echo 'Dropdowns in issue templates is out of date, please run "make generate-gh-issue-templates" and commit the changes in this PR. Please note, if you are running it on Mac OS X, please make sure to use GNU version of sed instead of default "sed".' && exit 1)
|
||||||
|
|
||||||
|
policies-check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: verify semantic conventions yaml definitions
|
||||||
|
run: make check-policies
|
||||||
|
|
|
||||||
8
Makefile
8
Makefile
|
|
@ -228,3 +228,11 @@ chlog-update: $(CHLOGGEN)
|
||||||
.PHONY: generate-gh-issue-templates
|
.PHONY: generate-gh-issue-templates
|
||||||
generate-gh-issue-templates:
|
generate-gh-issue-templates:
|
||||||
$(TOOLS_DIR)/scripts/update-issue-template-areas.sh
|
$(TOOLS_DIR)/scripts/update-issue-template-areas.sh
|
||||||
|
|
||||||
|
.PHONY: check-policies
|
||||||
|
check-policies:
|
||||||
|
docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec -v $(PWD)/policies:/policies \
|
||||||
|
otel/weaver:${WEAVER_VERSION} registry check \
|
||||||
|
--registry=/source \
|
||||||
|
--policy=/policies/registry.rego \
|
||||||
|
--policy=/policies/attribute_name_collisions.rego
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
package after_resolution
|
||||||
|
|
||||||
|
deny[attr_registry_collision(description, name)] {
|
||||||
|
names := attr_names_except(excluded_const_collisions)
|
||||||
|
name := names[_]
|
||||||
|
const_name := to_const_name(name)
|
||||||
|
collisions:= { n | n := attr_names_except(excluded_const_collisions)[_]; n != name; to_const_name(n) == const_name }
|
||||||
|
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])
|
||||||
|
}
|
||||||
|
|
||||||
|
deny[attr_registry_collision(description, name)] {
|
||||||
|
names := attr_names_except(excluded_namespace_collisions)
|
||||||
|
name := names[_]
|
||||||
|
|
||||||
|
collisions:= { n | n := input.groups[_].attributes[_].name; startswith(n, to_namespace_prefix(name)) }
|
||||||
|
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])
|
||||||
|
}
|
||||||
|
|
||||||
|
attr_registry_collision(description, attr_name) = violation {
|
||||||
|
violation := {
|
||||||
|
"id": description,
|
||||||
|
"type": "semconv_attribute",
|
||||||
|
"category": "naming_collision",
|
||||||
|
"attr": attr_name,
|
||||||
|
"group": "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
to_namespace_prefix(name) = namespace {
|
||||||
|
namespace := concat("", [name, "."])
|
||||||
|
}
|
||||||
|
|
||||||
|
to_const_name(name) = const_name {
|
||||||
|
const_name := replace(name, ".", "_")
|
||||||
|
}
|
||||||
|
|
||||||
|
attr_names_except(excluded) = names {
|
||||||
|
names := { n | n := input.groups[_].attributes[_].name } - excluded
|
||||||
|
}
|
||||||
|
|
||||||
|
# These lists contain exceptions for existing collisions that were introduced unintentionally.
|
||||||
|
# We'll have a way to specify how collision resolution happens in the schema -
|
||||||
|
# see phase 2 in https://github.com/open-telemetry/semantic-conventions/issues/1118#issuecomment-2173803006
|
||||||
|
# For now we'll exclude existing collisions from the checks.
|
||||||
|
# ADDING NEW EXCEPTIONS IS NOT ALLOWED.
|
||||||
|
|
||||||
|
# DO NOT ADD ATTRIBUTES TO THIS LIST
|
||||||
|
excluded_const_collisions := {"messaging.client_id"}
|
||||||
|
# DO NOT ADD ATTRIBUTES TO THIS LIST
|
||||||
|
excluded_namespace_collisions := {"messaging.operation", "db.operation", "deployment.environment"}
|
||||||
|
|
@ -5,10 +5,10 @@ package before_resolution
|
||||||
# used by semantic conventions.
|
# used by semantic conventions.
|
||||||
|
|
||||||
# Helper to create attribute registry violations.
|
# Helper to create attribute registry violations.
|
||||||
attr_registry_violation(violation_id, group_id, attr_id) = violation {
|
attr_registry_violation(description, group_id, attr_id) = violation {
|
||||||
violation := {
|
violation := {
|
||||||
"id": violation_id,
|
"id": description,
|
||||||
"type": "semantic_convention_policies",
|
"type": "semconv_attribute",
|
||||||
"category": "attribute_registry_checks",
|
"category": "attribute_registry_checks",
|
||||||
"group": group_id,
|
"group": group_id,
|
||||||
"attr": attr_id,
|
"attr": attr_id,
|
||||||
|
|
@ -16,27 +16,48 @@ attr_registry_violation(violation_id, group_id, attr_id) = violation {
|
||||||
}
|
}
|
||||||
|
|
||||||
# We only allow attribute groups in the attribute registry.
|
# We only allow attribute groups in the attribute registry.
|
||||||
deny[attr_registry_violation("attribute_registry_can_only_contain_attribute_groups", group.id, "")] {
|
deny[attr_registry_violation(description, group.id, "")] {
|
||||||
group := input.groups[_]
|
group := input.groups[_]
|
||||||
startswith(group.id, "registry.")
|
startswith(group.id, "registry.")
|
||||||
group.type != "attribute_group"
|
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
|
# Any group that is NOT in the attribute registry that has an attribute id is
|
||||||
# in violation of not using the attribute registry.
|
# in violation of not using the attribute registry.
|
||||||
deny[attr_registry_violation("attributes_must_be_defined_in_attribute_registry", group.id, attr.id)] {
|
deny[attr_registry_violation(description, group.id, attr.id)] {
|
||||||
group := input.groups[_]
|
group := input.groups[_]
|
||||||
not startswith(group.id, "registry.")
|
not startswith(group.id, "registry.")
|
||||||
attr := group.attributes[_]
|
attr := group.attributes[_]
|
||||||
attr.id != null
|
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 registy. Attributes can be defined in the registry group only.", [attr_name, group.id])
|
||||||
}
|
}
|
||||||
|
|
||||||
# A registry `attribute_group` containing at least one `ref` attribute is
|
# A registry `attribute_group` containing at least one `ref` attribute is
|
||||||
# considered invalid if it's not in the registry group.
|
# considered invalid if it's not in the registry group.
|
||||||
deny[attr_registry_violation("attributes_in_registry_cannot_reference_each_other", group.id, attr.ref)] {
|
deny[attr_registry_violation(description, group.id, attr.ref)] {
|
||||||
# TODO - this will need to be updated to support `embed` in the future.
|
# TODO - this will need to be updated to support `embed` in the future.
|
||||||
group := input.groups[_]
|
group := input.groups[_]
|
||||||
startswith(group.id, "registry.")
|
startswith(group.id, "registry.")
|
||||||
attr := group.attributes[_]
|
attr := group.attributes[_]
|
||||||
attr.ref != null
|
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("Registy group '%s' references attribute '%s'. Registry groups can only define new attributes.", [group.id, attr.ref])
|
||||||
|
}
|
||||||
|
|
||||||
|
get_attribute_name(attr, group) = name {
|
||||||
|
full_name = concat(".", [group.prefix, attr.id])
|
||||||
|
|
||||||
|
# if there was no prefix, we have a leading dot
|
||||||
|
name := trim(full_name, ".")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue