From c1ef0e7e64be260ace1d21f53406b438d89d1b22 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 27 Jun 2024 09:09:20 -0700 Subject: [PATCH 01/16] rego --- Makefile | 7 ++++++ policies/before_resolution/registry.rego | 29 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 policies/before_resolution/registry.rego diff --git a/Makefile b/Makefile index 06e7b7d1b1..3aadd137a4 100644 --- a/Makefile +++ b/Makefile @@ -228,3 +228,10 @@ chlog-update: $(CHLOGGEN) .PHONY: generate-gh-issue-templates generate-gh-issue-templates: $(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 \ + --before-resolution-policies=/policies/before_resolution/registry.rego \ No newline at end of file diff --git a/policies/before_resolution/registry.rego b/policies/before_resolution/registry.rego new file mode 100644 index 0000000000..192c01d434 --- /dev/null +++ b/policies/before_resolution/registry.rego @@ -0,0 +1,29 @@ +package otel + +to_const_name(prefix, id) = const_name { + const_name := replace(trim(concat(".", [prefix, id]), "."), ".", "_") +} + +deny[schema_evolution_violation("foobar", group.id, attr.id)] { + group := input.groups[_] + attr := group.attributes[_] + + group.type == "attribute_group" + not attr.ref + + const_names := [n | g := input.groups[_]; a := g.attributes[_]; n := to_const_name(g.prefix, a.id)] + + const_name := to_const_name(group.prefix, attr.id) + count({i | const_names[i] == const_name}) > 1 +} + +attr_registry_violation(violation_id, group_id, attr_id) = violation { + violation := { + "id": violation_id, + "type": "semconv_attribute", + "category": "attribute_registry", + "group": group_id, + "attr": attr_id, + } +} + From 81c09a09c98457b270e70f8bd1e459c58fa7455f Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 3 Jul 2024 14:53:21 -0700 Subject: [PATCH 02/16] up --- Makefile | 2 +- policies/before_resolution/registry.rego | 29 ------------------------ 2 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 policies/before_resolution/registry.rego diff --git a/Makefile b/Makefile index 3aadd137a4..6dd2193679 100644 --- a/Makefile +++ b/Makefile @@ -234,4 +234,4 @@ 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 \ - --before-resolution-policies=/policies/before_resolution/registry.rego \ No newline at end of file + --policy=/policies/attribute_name_collisions.rego diff --git a/policies/before_resolution/registry.rego b/policies/before_resolution/registry.rego deleted file mode 100644 index 192c01d434..0000000000 --- a/policies/before_resolution/registry.rego +++ /dev/null @@ -1,29 +0,0 @@ -package otel - -to_const_name(prefix, id) = const_name { - const_name := replace(trim(concat(".", [prefix, id]), "."), ".", "_") -} - -deny[schema_evolution_violation("foobar", group.id, attr.id)] { - group := input.groups[_] - attr := group.attributes[_] - - group.type == "attribute_group" - not attr.ref - - const_names := [n | g := input.groups[_]; a := g.attributes[_]; n := to_const_name(g.prefix, a.id)] - - const_name := to_const_name(group.prefix, attr.id) - count({i | const_names[i] == const_name}) > 1 -} - -attr_registry_violation(violation_id, group_id, attr_id) = violation { - violation := { - "id": violation_id, - "type": "semconv_attribute", - "category": "attribute_registry", - "group": group_id, - "attr": attr_id, - } -} - From 8c69c08e44bf327580b7b1f758c24be803f3f8df Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 3 Jul 2024 14:54:19 -0700 Subject: [PATCH 03/16] add policy --- policies/attribute_name_collisions.rego | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 policies/attribute_name_collisions.rego diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego new file mode 100644 index 0000000000..74b55822ce --- /dev/null +++ b/policies/attribute_name_collisions.rego @@ -0,0 +1,47 @@ +package after_resolution + +# TODO: https://github.com/open-telemetry/semantic-conventions/issues/1118 +# we need to specify exclusions in the schema +excluded_const_collisions := {"messaging.client_id"} +excluded_namespace_collisions := {"messaging.operation", "db.operation"} + +deny[attr_registry_collision(description, "", attr.name)] { + attr := attr_names_except(excluded_const_collisions)[_] + const_name := to_const_name(attr.name) + + collisions:= [ n | n := attr_names_except(excluded_const_collisions)[_]; n != attr.name; to_const_name(n) == const_name] + count(collisions) > 0 + + description := sprintf("Attribute '%s' has the same constant name '%s' as %s", [attr.name, const_name, collisions]) +} + +deny[attr_registry_collision(description, "", attr.name)] { + attr := attr_names_except(excluded_namespace_collisions)[_] + + collisions:= [ n | n := input.groups[_].attributes[_].name; startswith(n, to_namespace_prefix(attr.name))] + count(collisions) > 1 + + description := sprintf("Attribute '%s' is used as a namespace in attributes %s", [attr.name, collisions]) +} + +attr_registry_collision(violation_id, group_id, attr_name) = violation { + violation := { + "id": violation_id, + "type": "semconv_attribute", + "category": "", + "attr": attr_name, + "group": group_id, + } +} + +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 +} From 54531b664c491e3697d8f0b7f85b934bcfaadbc0 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 3 Jul 2024 14:56:17 -0700 Subject: [PATCH 04/16] up --- policies/attribute_name_collisions.rego | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index 74b55822ce..f381d30926 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -5,7 +5,7 @@ package after_resolution excluded_const_collisions := {"messaging.client_id"} excluded_namespace_collisions := {"messaging.operation", "db.operation"} -deny[attr_registry_collision(description, "", attr.name)] { +deny[attr_registry_collision(description, attr.name)] { attr := attr_names_except(excluded_const_collisions)[_] const_name := to_const_name(attr.name) @@ -15,7 +15,7 @@ deny[attr_registry_collision(description, "", attr.name)] { description := sprintf("Attribute '%s' has the same constant name '%s' as %s", [attr.name, const_name, collisions]) } -deny[attr_registry_collision(description, "", attr.name)] { +deny[attr_registry_collision(description, attr.name)] { attr := attr_names_except(excluded_namespace_collisions)[_] collisions:= [ n | n := input.groups[_].attributes[_].name; startswith(n, to_namespace_prefix(attr.name))] @@ -24,13 +24,13 @@ deny[attr_registry_collision(description, "", attr.name)] { description := sprintf("Attribute '%s' is used as a namespace in attributes %s", [attr.name, collisions]) } -attr_registry_collision(violation_id, group_id, attr_name) = violation { +attr_registry_collision(violation_id, attr_name) = violation { violation := { "id": violation_id, "type": "semconv_attribute", "category": "", "attr": attr_name, - "group": group_id, + "group": "", } } From fbf3391380d7ac4dc6f9860c4d99e14f52693fa9 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 3 Jul 2024 14:56:35 -0700 Subject: [PATCH 05/16] test me --- policies/attribute_name_collisions.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index f381d30926..97e94eeab5 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -2,8 +2,8 @@ package after_resolution # TODO: https://github.com/open-telemetry/semantic-conventions/issues/1118 # we need to specify exclusions in the schema -excluded_const_collisions := {"messaging.client_id"} -excluded_namespace_collisions := {"messaging.operation", "db.operation"} +excluded_const_collisions := {} +excluded_namespace_collisions := {} deny[attr_registry_collision(description, attr.name)] { attr := attr_names_except(excluded_const_collisions)[_] From 7779a71c0768b0ba8c8a5ff1211ca3d45f6739bf Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 3 Jul 2024 14:58:06 -0700 Subject: [PATCH 06/16] tabs --- policies/attribute_name_collisions.rego | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index 97e94eeab5..407cde66cd 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -9,29 +9,29 @@ deny[attr_registry_collision(description, attr.name)] { attr := attr_names_except(excluded_const_collisions)[_] const_name := to_const_name(attr.name) - collisions:= [ n | n := attr_names_except(excluded_const_collisions)[_]; n != attr.name; to_const_name(n) == const_name] - count(collisions) > 0 + collisions:= [ n | n := attr_names_except(excluded_const_collisions)[_]; n != attr.name; to_const_name(n) == const_name] + count(collisions) > 0 - description := sprintf("Attribute '%s' has the same constant name '%s' as %s", [attr.name, const_name, collisions]) + description := sprintf("Attribute '%s' has the same constant name '%s' as %s", [attr.name, const_name, collisions]) } deny[attr_registry_collision(description, attr.name)] { attr := attr_names_except(excluded_namespace_collisions)[_] - collisions:= [ n | n := input.groups[_].attributes[_].name; startswith(n, to_namespace_prefix(attr.name))] - count(collisions) > 1 + collisions:= [ n | n := input.groups[_].attributes[_].name; startswith(n, to_namespace_prefix(attr.name))] + count(collisions) > 1 - description := sprintf("Attribute '%s' is used as a namespace in attributes %s", [attr.name, collisions]) + description := sprintf("Attribute '%s' is used as a namespace in attributes %s", [attr.name, collisions]) } attr_registry_collision(violation_id, attr_name) = violation { - violation := { - "id": violation_id, - "type": "semconv_attribute", - "category": "", - "attr": attr_name, - "group": "", - } + violation := { + "id": violation_id, + "type": "semconv_attribute", + "category": "", + "attr": attr_name, + "group": "", + } } to_namespace_prefix(name) = namespace { @@ -43,5 +43,5 @@ to_const_name(name) = const_name { } attr_names_except(excluded) = names { - names := {n | n := input.groups[_].attributes[_].name} - excluded + names := {n | n := input.groups[_].attributes[_].name} - excluded } From 54538ea5b8773c7e270cbefea9f7bd30969da601 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 3 Jul 2024 15:18:47 -0700 Subject: [PATCH 07/16] oops --- policies/attribute_name_collisions.rego | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index 407cde66cd..c0d23e3023 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -1,29 +1,26 @@ package after_resolution -# TODO: https://github.com/open-telemetry/semantic-conventions/issues/1118 -# we need to specify exclusions in the schema -excluded_const_collisions := {} -excluded_namespace_collisions := {} - -deny[attr_registry_collision(description, attr.name)] { - attr := attr_names_except(excluded_const_collisions)[_] - const_name := to_const_name(attr.name) - - collisions:= [ n | n := attr_names_except(excluded_const_collisions)[_]; n != attr.name; to_const_name(n) == const_name] +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 - description := sprintf("Attribute '%s' has the same constant name '%s' as %s", [attr.name, const_name, collisions]) + description := sprintf("Attribute '%s' has the same constant name '%s' as %s", [name, const_name, collisions]) } -deny[attr_registry_collision(description, attr.name)] { - attr := attr_names_except(excluded_namespace_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(attr.name))] + collisions:= [ n | n := input.groups[_].attributes[_].name; startswith(n, to_namespace_prefix(name))] count(collisions) > 1 - description := sprintf("Attribute '%s' is used as a namespace in attributes %s", [attr.name, collisions]) + description := sprintf("Attribute '%s' is used as a namespace in attributes %s", [name, collisions]) } + attr_registry_collision(violation_id, attr_name) = violation { violation := { "id": violation_id, @@ -45,3 +42,6 @@ to_const_name(name) = const_name { attr_names_except(excluded) = names { names := {n | n := input.groups[_].attributes[_].name} - excluded } + +excluded_const_collisions := {"messaging.client_id"} +excluded_namespace_collisions := {"messaging.operation", "db.operation"} \ No newline at end of file From 484fb428530924dac962b315d63d2a704470e698 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 3 Jul 2024 15:21:13 -0700 Subject: [PATCH 08/16] workflow --- .github/workflows/checks.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index a889670d86..3609ee261f 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -108,3 +108,10 @@ jobs: run: | 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) + + policies-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: policies checks + run: make check-policies From bb810f03705b34d08fc8be7c3de43eb5ebac28b1 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 3 Jul 2024 15:22:04 -0700 Subject: [PATCH 09/16] test me --- policies/attribute_name_collisions.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index c0d23e3023..36284ea389 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -43,5 +43,5 @@ attr_names_except(excluded) = names { names := {n | n := input.groups[_].attributes[_].name} - excluded } -excluded_const_collisions := {"messaging.client_id"} -excluded_namespace_collisions := {"messaging.operation", "db.operation"} \ No newline at end of file +excluded_const_collisions := {"m1essaging.client_id"} +excluded_namespace_collisions := {"m1essaging.operation", "db.operation"} \ No newline at end of file From df4594cde8c9127412eddab79b34964c003ccfc4 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 3 Jul 2024 15:28:35 -0700 Subject: [PATCH 10/16] up --- policies/attribute_name_collisions.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index 36284ea389..ae3925a5fa 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -4,7 +4,7 @@ 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] + collisions:= { n | n := attr_names_except(excluded_const_collisions)[_]; n != name; to_const_name(n) == const_name} count(collisions) > 0 description := sprintf("Attribute '%s' has the same constant name '%s' as %s", [name, const_name, collisions]) @@ -14,7 +14,7 @@ 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))] + collisions:= { n | n := input.groups[_].attributes[_].name; startswith(n, to_namespace_prefix(name))} count(collisions) > 1 description := sprintf("Attribute '%s' is used as a namespace in attributes %s", [name, collisions]) From 7be587ef49f1d8dd23a5619294b62dd5be2d968d Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 3 Jul 2024 15:47:31 -0700 Subject: [PATCH 11/16] up --- policies/attribute_name_collisions.rego | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index ae3925a5fa..cc6fad5b03 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -15,15 +15,14 @@ deny[attr_registry_collision(description, name)] { name := names[_] collisions:= { n | n := input.groups[_].attributes[_].name; startswith(n, to_namespace_prefix(name))} - count(collisions) > 1 + count(collisions) > 0 description := sprintf("Attribute '%s' is used as a namespace in attributes %s", [name, collisions]) } - -attr_registry_collision(violation_id, attr_name) = violation { +attr_registry_collision(description, attr_name) = violation { violation := { - "id": violation_id, + "id": description, "type": "semconv_attribute", "category": "", "attr": attr_name, From bbae02e008113d91c14729c74848e2038eb18c5e Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 23 Jul 2024 23:26:33 -0700 Subject: [PATCH 12/16] cleuan up --- .github/workflows/checks.yml | 2 +- Makefile | 1 + policies/attribute_name_collisions.rego | 6 +++--- policies/registry.rego | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 3609ee261f..ceaf8ef7f6 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -113,5 +113,5 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - - name: policies checks + - name: verify semantic conventions yaml definitions run: make check-policies diff --git a/Makefile b/Makefile index 6dd2193679..80772401b4 100644 --- a/Makefile +++ b/Makefile @@ -234,4 +234,5 @@ 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 diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index cc6fad5b03..62f67cea45 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -24,7 +24,7 @@ attr_registry_collision(description, attr_name) = violation { violation := { "id": description, "type": "semconv_attribute", - "category": "", + "category": "naming_collision", "attr": attr_name, "group": "", } @@ -42,5 +42,5 @@ attr_names_except(excluded) = names { names := {n | n := input.groups[_].attributes[_].name} - excluded } -excluded_const_collisions := {"m1essaging.client_id"} -excluded_namespace_collisions := {"m1essaging.operation", "db.operation"} \ No newline at end of file +excluded_const_collisions := {"messaging.client_id"} +excluded_namespace_collisions := {"messaging.operation", "db.operation", "deployment.environment"} \ No newline at end of file diff --git a/policies/registry.rego b/policies/registry.rego index cc30c75f48..632279015c 100644 --- a/policies/registry.rego +++ b/policies/registry.rego @@ -8,7 +8,7 @@ package before_resolution attr_registry_violation(violation_id, group_id, attr_id) = violation { violation := { "id": violation_id, - "type": "semantic_convention_policies", + "type": "semconv_attribute", "category": "attribute_registry_checks", "group": group_id, "attr": attr_id, From be541725aab73ef829cecade43d5a3e30a5ee811 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 23 Jul 2024 23:27:46 -0700 Subject: [PATCH 13/16] cleuan up --- policies/attribute_name_collisions.rego | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index 62f67cea45..7047fa9363 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -43,4 +43,4 @@ attr_names_except(excluded) = names { } excluded_const_collisions := {"messaging.client_id"} -excluded_namespace_collisions := {"messaging.operation", "db.operation", "deployment.environment"} \ No newline at end of file +excluded_namespace_collisions := {"messaging.operation", "db.operation", "deployment.environment"} From 96672f6aa20fef97b6dc2c0a05aabec14a048b7b Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 24 Jul 2024 11:29:49 -0700 Subject: [PATCH 14/16] clean up --- policies/attribute_name_collisions.rego | 13 +++++++---- policies/registry.rego | 31 +++++++++++++++++++++---- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index 7047fa9363..bbe2157a3b 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -4,20 +4,20 @@ 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} + collisions:= { n | n := attr_names_except(excluded_const_collisions)[_]; n != name; to_const_name(n) == const_name } count(collisions) > 0 - description := sprintf("Attribute '%s' has the same constant name '%s' as %s", [name, const_name, collisions]) + 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))} + collisions:= { n | n := input.groups[_].attributes[_].name; startswith(n, to_namespace_prefix(name)) } count(collisions) > 0 - description := sprintf("Attribute '%s' is used as a namespace in attributes %s", [name, collisions]) + description := sprintf("Attribute '%s' name is used as a namespace in the following attributes '%s'.", [name, collisions]) } attr_registry_collision(description, attr_name) = violation { @@ -39,8 +39,11 @@ to_const_name(name) = const_name { } attr_names_except(excluded) = names { - names := {n | n := input.groups[_].attributes[_].name} - excluded + names := { n | n := input.groups[_].attributes[_].name } - excluded } +# TODO - we'll need 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 just allow current collisions. excluded_const_collisions := {"messaging.client_id"} excluded_namespace_collisions := {"messaging.operation", "db.operation", "deployment.environment"} diff --git a/policies/registry.rego b/policies/registry.rego index 632279015c..19de331a48 100644 --- a/policies/registry.rego +++ b/policies/registry.rego @@ -5,9 +5,9 @@ package before_resolution # used by semantic conventions. # 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 := { - "id": violation_id, + "id": description, "type": "semconv_attribute", "category": "attribute_registry_checks", "group": group_id, @@ -16,27 +16,48 @@ attr_registry_violation(violation_id, group_id, attr_id) = violation { } # 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[_] startswith(group.id, "registry.") group.type != "attribute_group" + + # TODO - separate violation_id and description 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[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[_] not startswith(group.id, "registry.") attr := group.attributes[_] attr.id != null + + attr_name := get_attribute_name(attr, group) + + # TODO - separate violation_id and description 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 # 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. group := input.groups[_] startswith(group.id, "registry.") attr := group.attributes[_] attr.ref != null + + # TODO - separate violation_id and description 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, ".") } From 9dc259237568e9920c57081644b837d2010e7c70 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 31 Jul 2024 12:53:43 -0700 Subject: [PATCH 15/16] clarify that new attributes cannot be added to exceptions --- policies/attribute_name_collisions.rego | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index bbe2157a3b..d546f408c6 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -42,8 +42,13 @@ attr_names_except(excluded) = names { names := { n | n := input.groups[_].attributes[_].name } - excluded } -# TODO - we'll need to specify how collision resolution happens in the schema - +# 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 just allow current collisions. +# 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"} From 739d5a40c61ae6ec263879ca8798abffb6346167 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 31 Jul 2024 13:25:42 -0700 Subject: [PATCH 16/16] link violation issue --- policies/attribute_name_collisions.rego | 2 ++ policies/registry.rego | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/policies/attribute_name_collisions.rego b/policies/attribute_name_collisions.rego index d546f408c6..3d38dab177 100644 --- a/policies/attribute_name_collisions.rego +++ b/policies/attribute_name_collisions.rego @@ -7,6 +7,7 @@ deny[attr_registry_collision(description, 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]) } @@ -17,6 +18,7 @@ deny[attr_registry_collision(description, name)] { 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]) } diff --git a/policies/registry.rego b/policies/registry.rego index 19de331a48..a1925c0887 100644 --- a/policies/registry.rego +++ b/policies/registry.rego @@ -21,7 +21,7 @@ deny[attr_registry_violation(description, group.id, "")] { startswith(group.id, "registry.") group.type != "attribute_group" - # TODO - separate violation_id and description once weaver supports it. + # 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]) } @@ -36,7 +36,7 @@ deny[attr_registry_violation(description, group.id, attr.id)] { attr_name := get_attribute_name(attr, group) - # TODO - separate violation_id and description once weaver supports it. + # 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]) } @@ -50,7 +50,7 @@ deny[attr_registry_violation(description, group.id, attr.ref)] { attr := group.attributes[_] attr.ref != null - # TODO - separate violation_id and description once weaver supports it. + # 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]) }