diff --git a/Makefile b/Makefile index 2a783c5b19..e897511f77 100644 --- a/Makefile +++ b/Makefile @@ -113,33 +113,44 @@ yamllint: # Generate markdown tables from YAML definitions .PHONY: table-generation table-generation: - docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec -v $(PWD)/templates:/weaver/templates \ + docker run --rm \ + -u $(id -u ${USER}):$(id -g ${USER}) \ + --mount 'type=bind,source=$(PWD)/templates,target=/home/weaver/templates,readonly' \ + --mount 'type=bind,source=$(PWD)/model,target=/home/weaver/source,readonly' \ + --mount 'type=bind,source=$(PWD)/docs,target=/home/weaver/target' \ $(WEAVER_CONTAINER) registry update-markdown \ - --registry=/source \ + --registry=/home/weaver/source \ --attribute-registry-base-url=/docs/attributes-registry \ - --templates=/weaver/templates \ + --templates=/home/weaver/templates \ --target=markdown \ - /spec + /home/weaver/target # Generate attribute registry markdown. .PHONY: attribute-registry-generation attribute-registry-generation: - docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec -v $(PWD)/templates:/weaver/templates \ + docker run --rm \ + -u $(id -u ${USER}):$(id -g ${USER}) \ + --mount 'type=bind,source=$(PWD)/templates,target=/home/weaver/templates,readonly' \ + --mount 'type=bind,source=$(PWD)/model,target=/home/weaver/source,readonly' \ + --mount 'type=bind,source=$(PWD)/docs,target=/home/weaver/target' \ $(WEAVER_CONTAINER) registry generate \ - --registry=/source \ - --templates=/weaver/templates \ + --registry=/home/weaver/source \ + --templates=/home/weaver/templates \ markdown \ - /spec/attributes-registry/ + /home/weaver/target/attributes-registry/ npm run fix:format # Check if current markdown tables differ from the ones that would be generated from YAML definitions (weaver). .PHONY: table-check table-check: - docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec -v $(PWD)/templates:/weaver/templates \ + docker run --rm \ + --mount 'type=bind,source=$(PWD)/templates,target=/home/weaver/templates,readonly' \ + --mount 'type=bind,source=$(PWD)/model,target=/home/weaver/source,readonly' \ + --mount 'type=bind,source=$(PWD)/docs,target=/home/weaver/target,readonly' \ $(WEAVER_CONTAINER) registry update-markdown \ - --registry=/source \ + --registry=/home/weaver/target \ --attribute-registry-base-url=/docs/attributes-registry \ - --templates=/weaver/templates \ + --templates=/home/weaver/templates \ --target=markdown \ --dry-run \ /spec @@ -215,11 +226,14 @@ generate-gh-issue-templates: LATEST_RELEASED_SEMCONV_VERSION := $(shell git ls-remote --tags https://github.com/open-telemetry/semantic-conventions.git | cut -f 2 | sort --reverse | head -n 1 | tr '/' ' ' | cut -d ' ' -f 3 | $(SED) 's/v//g') .PHONY: check-policies check-policies: - docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec -v $(PWD)/policies:/policies \ + docker run --rm \ + -u $(id -u ${USER}):$(id -g ${USER}) \ + --mount 'type=bind,source=$(PWD)/policies,target=/home/weaver/policies,readonly' \ + --mount 'type=bind,source=$(PWD)/model,target=/home/weaver/source,readonly' \ ${WEAVER_CONTAINER} registry check \ - --registry=/source \ + --registry=/home/weaver/source \ --baseline-registry=https://github.com/open-telemetry/semantic-conventions/archive/refs/tags/v$(LATEST_RELEASED_SEMCONV_VERSION).zip[model] \ - --policy=/policies + --policy=/home/weaver/policies # Test rego policies .PHONY: test-policies diff --git a/dependencies.Dockerfile b/dependencies.Dockerfile index 9afcb2db23..f0789225eb 100644 --- a/dependencies.Dockerfile +++ b/dependencies.Dockerfile @@ -3,7 +3,7 @@ # Dependabot can keep this file up to date with latest containers. # Weaver is used to generate markdown docs, and enforce policies on the model. -FROM otel/weaver:0.8.0 AS weaver +FROM otel/weaver:v0.9.1 AS weaver # OPA is used to test policies enforced by weaver. FROM openpolicyagent/opa:0.67.1 AS opa diff --git a/docs/attributes-registry/process.md b/docs/attributes-registry/process.md index 9c55c2a4b3..5b4bee8ba2 100644 --- a/docs/attributes-registry/process.md +++ b/docs/attributes-registry/process.md @@ -39,17 +39,17 @@ An operating system process. | `process.saved_user.id` | int | The saved user ID (SUID) of the process. | `1002` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.saved_user.name` | string | The username of the saved user. | `operator` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.session_leader.pid` | int | The PID of the process's session leader. This is also the session ID (SID) of the process. | `14` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.title` | string | Process title (proctitle) [2] | `cat /etc/hostname`; `xfce4-session`; `bash` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.user.id` | int | The effective user ID (EUID) of the process. | `1001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.user.name` | string | The username of the effective user of the process. | `root` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.vpid` | int | Virtual process identifier. [2] | `12` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `title` | string | Process title (proctitle) [3] | `cat /etc/hostname`; `xfce4-session`; `bash` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `working_directory` | string | The working directory of the process. | `/root` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.vpid` | int | Virtual process identifier. [3] | `12` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.working_directory` | string | The working directory of the process. | `/root` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This field can be useful for querying or performing bucket analysis on how many arguments were provided to start a process. More arguments may be an indication of suspicious activity. -**[2]:** The process ID within a PID namespace. This is not necessarily unique across all processes on the host but it is unique within the process namespace that the process exists within. +**[2]:** In many Unix-like systems, process title (proctitle), is the string that represents the name or command line of a running process, displayed by system monitoring tools like ps, top, and htop. -**[3]:** In many Unix-like systems, process title (proctitle), is the string that represents the name or command line of a running process, displayed by system monitoring tools like ps, top, and htop. +**[3]:** The process ID within a PID namespace. This is not necessarily unique across all processes on the host but it is unique within the process namespace that the process exists within. `process.context_switch_type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. diff --git a/model/registry/process.yaml b/model/registry/process.yaml index e070dc431b..1e583fc335 100644 --- a/model/registry/process.yaml +++ b/model/registry/process.yaml @@ -159,7 +159,7 @@ groups: An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0' - - id: title + - id: process.title type: string stability: experimental brief: > @@ -192,7 +192,7 @@ groups: stability: experimental brief: > Whether the process is connected to an interactive shell. - - id: working_directory + - id: process.working_directory type: string stability: experimental brief: > diff --git a/policies/yaml_schema.rego b/policies/yaml_schema.rego index 2dfe53d593..cd81b3c6ab 100644 --- a/policies/yaml_schema.rego +++ b/policies/yaml_schema.rego @@ -11,6 +11,20 @@ deny[yaml_schema_violation(description, group.id, name)] { description := sprintf("Attribute name '%s' is invalid. Attribute name %s", [name, invalid_name_helper]) } +# checks attribute name has a namespace +deny[yaml_schema_violation(description, group.id, name)] { + group := input.groups[_] + attr := group.attributes[_] + name := attr.id + + # some deprecated attributes have no namespace and need to be ignored + not attr.deprecated + not regex.match(has_namespace_regex, name) + + description := sprintf("Attribute name '%s' should have a namespace. Attribute name %s", [name, invalid_name_helper]) +} + + # checks metric name format deny[yaml_schema_violation(description, group.id, name)] { group := input.groups[_] @@ -71,4 +85,6 @@ yaml_schema_violation(description, group, attr) = violation { # valid: 'foo.bar', 'foo.1bar', 'foo.1_bar' name_regex := "^[a-z][a-z0-9]*([._][a-z0-9]+)*$" +has_namespace_regex := "^[a-z0-9_]+\\.([a-z0-9._]+)+$" + invalid_name_helper := "must consist of lowercase alphanumeric characters separated by '_' and '.'" diff --git a/policies/yaml_schema_test.rego b/policies/yaml_schema_test.rego index ebcd86f036..2fc33ceb07 100644 --- a/policies/yaml_schema_test.rego +++ b/policies/yaml_schema_test.rego @@ -4,19 +4,23 @@ import future.keywords test_fails_on_invalid_attribute_name if { every name in invalid_names { - count(deny) == 1 with input as {"groups": create_attribute_group(name)} + count(deny) >= 1 with input as {"groups": create_attribute_group(name)} } } +test_fails_on_attribute_name_without_namespace if { + count(deny) >= 1 with input as {"groups": create_attribute_group("foo")} +} + test_fails_on_invalid_metric_name if { every name in invalid_names { - count(deny) == 1 with input as {"groups": create_metric(name)} + count(deny) >= 1 with input as {"groups": create_metric(name)} } } test_fails_on_invalid_event_name if { every name in invalid_names { - count(deny) == 1 with input as {"groups": create_event(name)} + count(deny) >= 1 with input as {"groups": create_event(name)} } } @@ -52,9 +56,9 @@ invalid_names := [ "foo.bar.", "foo..bar", "foo._bar", - "foo__bar", + "foo.bar__baz", "foo_.bar", - "foo,bar", + "foo.bar,baz", "fü.bär", ] diff --git a/policies_test/registry_test.rego b/policies_test/registry_test.rego index 4880af7b0f..72d042e6e9 100644 --- a/policies_test/registry_test.rego +++ b/policies_test/registry_test.rego @@ -11,10 +11,10 @@ test_registry_attribute_groups if { test_attribute_ids if { # This requires a prefix for use with opa, but weaver will fill in. - count(before_resolution.deny) > 0 with input as {"groups": [{"id": "not_registry", "prefix": "", "attributes": [{"id": "foo"}]}]} + count(before_resolution.deny) > 0 with input as {"groups": [{"id": "not_registry", "prefix": "", "attributes": [{"id": "foo.bar"}]}]} count(before_resolution.deny) == 0 with input as {"groups": [ - {"id": "registry.test", "prefix": "", "attributes": [{"id": "foo"}]}, - {"id": "not_registry", "prefix": "", "attributes": [{"ref": "foo"}]}, + {"id": "registry.test", "prefix": "", "attributes": [{"id": "foo.bar"}]}, + {"id": "not_registry", "prefix": "", "attributes": [{"ref": "foo.bar"}]}, ]} }