Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add LinkRule linker #109

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ indent_style = space
indent_size = 4

[*.sh]
indent_style = tab
indent_style = space
indent_size = 2

[*.dot]
Expand Down
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* text=auto
pkg/crds/client linguist-generated=true
zz_generated*.go linguist-generated=true
1 change: 1 addition & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ linters:
issues:
exclude-dirs:
- tools
- pkg/crds/client
exclude-rules:
- path: pkg/util/errors
linters: [errorlint]
Expand Down
35 changes: 34 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ endif

LINKER_WORKER_COUNT ?= 1

CONTROLLERS ?= audit-consumer,audit-producer,audit-webhook,event-informer,annotation-linker,owner-linker,resource-object-tag,resource-event-tag,diff-decorator,diff-controller,diff-api,pprof,jaeger-storage-plugin,jaeger-redirect-server,kelemetrix
CONTROLLERS ?= audit-consumer,audit-producer,audit-webhook,event-informer,annotation-linker,owner-linker,rule-linker,resource-object-tag,resource-event-tag,diff-decorator,diff-controller,diff-api,pprof,jaeger-storage-plugin,jaeger-redirect-server,kelemetrix
ifeq ($(CONTROLLERS),)
ENABLE_ARGS ?=
else
Expand Down Expand Up @@ -146,6 +146,7 @@ kind:
docker network inspect kind -f '{{(index .IPAM.Config 0).Gateway}}' \
)/g" hack/tracing-config.yaml >hack/tracing-config.local.yaml
cd hack && kind create cluster --config kind-cluster.yaml
kubectl --context kind-tracetest create -f crds/config

COMPOSE_COMMAND ?= up --build -d --remove-orphans

Expand Down Expand Up @@ -204,3 +205,35 @@ e2e: local-docker-build
make quickstart COMPOSE_COMMAND='down --remove-orphans --volumes' KELEMETRY_IMAGE=kelemetry:local
make quickstart COMPOSE_COMMAND='up --build -d --remove-orphans' KELEMETRY_IMAGE=kelemetry:local
bash e2e/run-all.sh

generate:
go run sigs.k8s.io/controller-tools/cmd/controller-gen \
crd \
paths=./pkg/crds/apis/... \
output:crd:dir=./crds/config


go run k8s.io/code-generator/cmd/deepcopy-gen \
--bounding-dirs=./pkg/crds/apis/v1alpha1 \
--output-file=zz_generated.deepcopy \
--go-header-file ./hack/boilerplate.txt
go run k8s.io/code-generator/cmd/client-gen \
--input=pkg/crds/apis/v1alpha1 \
--input-base=$$(realpath .) \
--output-pkg=github.com/kubewharf/kelemetry/pkg/crds/client/clientset \
--output-dir=pkg/crds/client/clientset \
--clientset-name=versioned \
--go-header-file ./hack/boilerplate.txt
go run k8s.io/code-generator/cmd/lister-gen \
--output-pkg=github.com/kubewharf/kelemetry/pkg/crds/client/listers \
--output-dir=./pkg/crds/client/listers \
--go-header-file ./hack/boilerplate.txt \
github.com/kubewharf/kelemetry/pkg/crds/apis/v1alpha1
go run k8s.io/code-generator/cmd/informer-gen \
--output-pkg=github.com/kubewharf/kelemetry/pkg/crds/client/informers \
--output-dir=./pkg/crds/client/informers \
--versioned-clientset-package=github.com/kubewharf/kelemetry/pkg/crds/client/clientset/versioned \
--listers-package=github.com/kubewharf/kelemetry/pkg/crds/client/listers \
--go-header-file ./hack/boilerplate.txt \
github.com/kubewharf/kelemetry/pkg/crds/apis/v1alpha1
$(MAKE) fmt
1 change: 1 addition & 0 deletions charts/kelemetry/crds
1 change: 1 addition & 0 deletions charts/kelemetry/templates/_helpers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ span-cache-etcd-prefix: {{ .Values.aggregator.spanCache.etcd.prefix | toJson }}
linker-worker-count: {{ .Values.linkers.workerCount }}
annotation-linker-enable: {{ .Values.linkers.annotation }}
owner-linker-enable: {{ .Values.linkers.ownerReference }}
rule-linker-enable: {{ .Values.linkers.rule }}

{{/* TRACER */}}
tracer-otel-endpoint: {{.Release.Name}}-collector.{{.Release.Namespace}}.svc:4317
Expand Down
2 changes: 2 additions & 0 deletions charts/kelemetry/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ linkers:
ownerReference: true
# Enable the annotation linker, which links objects based on the `kelemetry.kubewharf.io/parent-link` annotation.
annotation: true
# Enable the rule linker, which links objects using rules in the `LinkRule` CRD in the corresponding cluster.
rule: true

# Object cache is an LRU cache for reusing lazily-fetched objects.
objectCache:
Expand Down
228 changes: 228 additions & 0 deletions crds/config/kelemetry.kubewharf.io_linkrules.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.15.0
name: linkrules.kelemetry.kubewharf.io
spec:
group: kelemetry.kubewharf.io
names:
kind: LinkRule
listKind: LinkRuleList
plural: linkrules
singular: linkrule
scope: Cluster
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: |-
LinkRule instructs Kelemetry to display multiple objects (the "source" and the "target") in the same trace
by looking up the "target" when the span of the "source" object gets created.


LinkRule is bidirectional.
Once the link is recorded, searching "source" or "target" would both display the other trace in the link
as long as the link is not filtered out by tfconfig.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
link:
description: Link specifies how the two objects are linked together.
properties:
class:
description: |-
If Class is non empty, a pseudospan named the given value is inserted in the hierarchy between the target and source objects.


Multiple links with the same nonempty Class share the same pseudospan.
type: string
targetRole:
default: Child
description: |-
TargetRole selects the display position of the target object.


One of the target objects will be arbitrarily selected if there are multiple links with preferTargetParent=true.
type: string
required:
- targetRole
type: object
metadata:
type: object
sourceFilter:
description: SourceFilter determines whether a source object matches this
rule.
properties:
resources:
description: Resources are the possible resource types that a child
object may belong to.
items:
description: |-
GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying
concepts during lookup stages without having partially valid types
properties:
group:
type: string
resource:
type: string
required:
- group
- resource
type: object
type: array
selector:
description: Selector selects matching child objects by label.
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements.
The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies
to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
type: object
targetTemplates:
description: TargetTemplate indicates how to find the target object from
a matched source object.
items:
description: LinkRuleTargetTemplate indicates how to find the target
object from a matched source object.
properties:
cluster:
description: |-
Cluster computes the cluster name of the target object.


If empty or unspecified, uses the cluster of the child object.
properties:
goTemplate:
description: Parsed as a Go `text/template`. May output multiple
comma-delimited values (trailing comma allowed).
type: string
jq:
description: Parsed as a gojq query string. May output a string
or an array of strings.
type: string
literal:
description: A string literal, resolved as-is.
type: string
type: object
name:
description: |-
The name of the target object.


Inherits the same name as the source object if unspecified.
properties:
goTemplate:
description: Parsed as a Go `text/template`. May output multiple
comma-delimited values (trailing comma allowed).
type: string
jq:
description: Parsed as a gojq query string. May output a string
or an array of strings.
type: string
literal:
description: A string literal, resolved as-is.
type: string
type: object
namespace:
description: |-
The namespace of the target object.


Cluster-scoped target objects should emit an empty namespace.
If the namespace is empty, the target object is expected to be cluster-scoped.


Inherits the same namespace as the source object if unspecified.
properties:
goTemplate:
description: Parsed as a Go `text/template`. May output multiple
comma-delimited values (trailing comma allowed).
type: string
jq:
description: Parsed as a gojq query string. May output a string
or an array of strings.
type: string
literal:
description: A string literal, resolved as-is.
type: string
type: object
type:
description: The type of the target object, in the form `{groupName}/{version}/{resource}`.
properties:
goTemplate:
description: Parsed as a Go `text/template`. May output multiple
comma-delimited values (trailing comma allowed).
type: string
jq:
description: Parsed as a gojq query string. May output a string
or an array of strings.
type: string
literal:
description: A string literal, resolved as-is.
type: string
type: object
required:
- type
type: object
type: array
required:
- link
- sourceFilter
- targetTemplates
type: object
served: true
storage: true
17 changes: 17 additions & 0 deletions crds/samples/helm-release-link-rule.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: kelemetry.kubewharf.io/v1alpha1
kind: LinkRule
metadata:
name: helm-release
sourceFilter:
selector:
matchLabels:
app.kubernetes.io/managed-by: Helm
targetTemplate:
group: ""
version: v1
resource: secrets
namespaceTemplate: '{{.metadata.annotations | index "meta.helm.sh/release-namespace"}}'
nameTemplate: '{{.metadata.annotations | index "meta.helm.sh/release-name"}}'
link:
targetRole: Parent
class: templates
24 changes: 24 additions & 0 deletions crds/samples/pod-volume.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: kelemetry.kubewharf.io/v1alpha1
kind: LinkRule
metadata:
name: pod-volume
sourceFilter:
resources:
- group: ""
resource: pods
targetTemplates:
- type:
literal: v1/secrets
name:
jq: |
(.spec.volumes[] | select(has("secret")).secret.secretName)
+ (.spec.volumes[] | select(has("projected")).projected.sources[] | select("secret").secret.name)
- type:
literal: v1/configmaps
name:
jq: |
(.spec.volumes[] | select(has("configMap")).configMap.name)
+ (.spec.volumes[] | select(has("projected")).projected.sources[] | select("configMap").configMap.name)
link:
targetRole: Child
class: volumes
2 changes: 2 additions & 0 deletions e2e/run-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ set -euo pipefail

cd $(dirname $0)

export REPO_PATH=$(realpath ..)

run_test() {
local test_name=$1

Expand Down
Loading
Loading