Skip to content

Commit

Permalink
Created annotations filter (open-telemetry#2692)
Browse files Browse the repository at this point in the history
* Created annotations filter

Signed-off-by: Yuri Sa <[email protected]>

* Created annotations filters test

Signed-off-by: Yuri Sa <[email protected]>

* Adjusted linters

Signed-off-by: Yuri Sa <[email protected]>

* Added Annotations Filter for OpAMP and TA

Signed-off-by: Yuri Sa <[email protected]>

* Added e2e tests for Labels and Annotations

Signed-off-by: Yuri Sa <[email protected]>

* Added e2e tests for Labels and Annotations

Signed-off-by: Yuri Sa <[email protected]>

* Added e2e tests for Labels and Annotations

Signed-off-by: Yuri Sa <[email protected]>

* Added e2e tests for Labels and Annotations

Signed-off-by: Yuri Sa <[email protected]>

* Fixed tests

Signed-off-by: Yuri Sa <[email protected]>

* Reverting kustomization

Signed-off-by: Yuri Sa <[email protected]>

* Reverting kustomization

Signed-off-by: Yuri Sa <[email protected]>

* Improved annotations

Signed-off-by: Yuri Sa <[email protected]>

* Changed description

Signed-off-by: Yuri Sa <[email protected]>

---------

Signed-off-by: Yuri Sa <[email protected]>
  • Loading branch information
yuriolisa authored Mar 7, 2024
1 parent c6734e2 commit 08b33a5
Show file tree
Hide file tree
Showing 46 changed files with 675 additions and 205 deletions.
16 changes: 16 additions & 0 deletions .chloggen/annotations-filter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: 'enhancement'

# The name of the component, or a single word describing the area of concern, (e.g. operator, target allocator, github action)
component: operator

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Created ability to filter out Annotations

# One or more tracking issues related to the change
issues: [2627]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
3 changes: 3 additions & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ jobs:
- e2e-targetallocator
- e2e-upgrade
- e2e-multi-instrumentation
- e2e-metadata-filters
include:
- group: e2e-prometheuscr
setup: "prepare-e2e-with-featuregates FEATUREGATES=+operator.observability.prometheus"
- group: e2e-multi-instrumentation
setup: "add-operator-arg OPERATOR_ARG=--enable-multi-instrumentation prepare-e2e"
- group: e2e-metadata-filters
setup: "add-operator-arg OPERATOR_ARG='--annotations-filter=*filter.out --labels=*filter.out' prepare-e2e"

steps:
- name: Check out code into the Go module directory
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ e2e-prometheuscr: chainsaw
e2e-targetallocator: chainsaw
$(CHAINSAW) test --test-dir ./tests/e2e-targetallocator

# end-to-end-test for Annotations/Labels Filters
.PHONY: e2e-metadata-filters
e2e-metadata-filters: chainsaw
$(CHAINSAW) test --test-dir ./tests/e2e-metadata-filters

# end-to-end-test for testing upgrading
.PHONY: e2e-upgrade
e2e-upgrade: undeploy chainsaw
Expand Down
3 changes: 3 additions & 0 deletions controllers/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,9 @@ func TestBuildAll_OpAMPBridge(t *testing.T) {
"app.kubernetes.io/part-of": "opentelemetry",
"app.kubernetes.io/version": "latest",
},
Annotations: map[string]string{
"opentelemetry-opampbridge-config/hash": "bd5cfc0df684966e25597a2847d5a3bae2c2b037d8bf10e7ea402ebe4d41c9f0",
},
},
Spec: appsv1.DeploymentSpec{
Replicas: &one,
Expand Down
7 changes: 7 additions & 0 deletions internal/config/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type Config struct {
autoInstrumentationJavaImage string
openshiftRoutesAvailability openshift.RoutesAvailability
labelsFilter []string
annotationsFilter []string
}

// New constructs a new configuration based on the given options.
Expand Down Expand Up @@ -95,6 +96,7 @@ func New(opts ...Option) Config {
autoInstrumentationApacheHttpdImage: o.autoInstrumentationApacheHttpdImage,
autoInstrumentationNginxImage: o.autoInstrumentationNginxImage,
labelsFilter: o.labelsFilter,
annotationsFilter: o.annotationsFilter,
}
}

Expand Down Expand Up @@ -204,3 +206,8 @@ func (c *Config) AutoInstrumentationNginxImage() string {
func (c *Config) LabelsFilter() []string {
return c.labelsFilter
}

// AnnotationsFilter Returns the filters converted to regex strings used to filter out unwanted labels from propagations.
func (c *Config) AnnotationsFilter() []string {
return c.annotationsFilter
}
26 changes: 24 additions & 2 deletions internal/config/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type options struct {
operatorOpAMPBridgeImage string
openshiftRoutesAvailability openshift.RoutesAvailability
labelsFilter []string
annotationsFilter []string
}

func WithAutoDetect(a autodetect.AutoDetect) Option {
Expand Down Expand Up @@ -180,14 +181,35 @@ func WithLabelFilters(labelFilters []string) Option {
if i > 0 {
result.WriteString(".*")
}

// Quote any regular expression meta characters in the
// literal text.
result.WriteString(regexp.QuoteMeta(literal))
}
filters = append(filters, result.String())
}

o.labelsFilter = filters
}
}

func WithAnnotationFilters(annotationFilters []string) Option {
return func(o *options) {

filters := []string{}
for _, pattern := range annotationFilters {
var result strings.Builder

for i, literal := range strings.Split(pattern, "*") {

// Replace * with .*
if i > 0 {
result.WriteString(".*")
}
// Quote any regular expression meta characters in the
// literal text.
result.WriteString(regexp.QuoteMeta(literal))
}
filters = append(filters, result.String())
}
o.annotationsFilter = filters
}
}
5 changes: 3 additions & 2 deletions internal/manifests/collector/daemonset.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ func DaemonSet(params manifests.Params) (*appsv1.DaemonSet, error) {
name := naming.Collector(params.OtelCol.Name)
labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter())

annotations, err := Annotations(params.OtelCol)
annotations, err := manifestutils.Annotations(params.OtelCol, params.Config.AnnotationsFilter())
if err != nil {
return nil, err
}
podAnnotations, err := PodAnnotations(params.OtelCol)

podAnnotations, err := manifestutils.PodAnnotations(params.OtelCol, params.Config.AnnotationsFilter())
if err != nil {
return nil, err
}
Expand Down
31 changes: 31 additions & 0 deletions internal/manifests/collector/daemonset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,37 @@ func TestDaemonsetFilterLabels(t *testing.T) {
}
}

func TestDaemonsetFilterAnnotations(t *testing.T) {
excludedAnnotations := map[string]string{
"foo": "1",
"app.foo.bar": "1",
}

otelcol := v1beta1.OpenTelemetryCollector{
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance",
Annotations: excludedAnnotations,
},
Spec: v1beta1.OpenTelemetryCollectorSpec{},
}

cfg := config.New(config.WithAnnotationFilters([]string{"foo*", "app.*.bar"}))

params := manifests.Params{
Config: cfg,
OtelCol: otelcol,
Log: logger,
}

d, err := DaemonSet(params)
require.NoError(t, err)

assert.Len(t, d.ObjectMeta.Annotations, 4)
for k := range excludedAnnotations {
assert.NotContains(t, d.ObjectMeta.Annotations, k)
}
}

func TestDaemonSetNodeSelector(t *testing.T) {
// Test default
otelcol1 := v1beta1.OpenTelemetryCollector{
Expand Down
5 changes: 2 additions & 3 deletions internal/manifests/collector/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,12 @@ import (
func Deployment(params manifests.Params) (*appsv1.Deployment, error) {
name := naming.Collector(params.OtelCol.Name)
labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter())

annotations, err := Annotations(params.OtelCol)
annotations, err := manifestutils.Annotations(params.OtelCol, params.Config.AnnotationsFilter())
if err != nil {
return nil, err
}

podAnnotations, err := PodAnnotations(params.OtelCol)
podAnnotations, err := manifestutils.PodAnnotations(params.OtelCol, params.Config.AnnotationsFilter())
if err != nil {
return nil, err
}
Expand Down
31 changes: 31 additions & 0 deletions internal/manifests/collector/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,37 @@ func TestDeploymentFilterLabels(t *testing.T) {
}
}

func TestDeploymentFilterAnnotations(t *testing.T) {
excludedAnnotations := map[string]string{
"foo": "1",
"app.foo.bar": "1",
}

otelcol := v1beta1.OpenTelemetryCollector{
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance",
Annotations: excludedAnnotations,
},
Spec: v1beta1.OpenTelemetryCollectorSpec{},
}

cfg := config.New(config.WithAnnotationFilters([]string{"foo*", "app.*.bar"}))

params := manifests.Params{
Config: cfg,
OtelCol: otelcol,
Log: logger,
}

d, err := Deployment(params)
require.NoError(t, err)

assert.Len(t, d.ObjectMeta.Annotations, 4)
for k := range excludedAnnotations {
assert.NotContains(t, d.ObjectMeta.Annotations, k)
}
}

func TestDeploymentNodeSelector(t *testing.T) {
// Test default
otelcol1 := v1beta1.OpenTelemetryCollector{
Expand Down
2 changes: 1 addition & 1 deletion internal/manifests/collector/horizontalpodautoscaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
func HorizontalPodAutoscaler(params manifests.Params) (*autoscalingv2.HorizontalPodAutoscaler, error) {
name := naming.Collector(params.OtelCol.Name)
labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter())
annotations, err := Annotations(params.OtelCol)
annotations, err := manifestutils.Annotations(params.OtelCol, params.Config.AnnotationsFilter())
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/manifests/collector/poddisruptionbudget.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func PodDisruptionBudget(params manifests.Params) (*policyV1.PodDisruptionBudget

name := naming.Collector(params.OtelCol.Name)
labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter())
annotations, err := Annotations(params.OtelCol)
annotations, err := manifestutils.Annotations(params.OtelCol, params.Config.AnnotationsFilter())
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions internal/manifests/collector/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ func StatefulSet(params manifests.Params) (*appsv1.StatefulSet, error) {
name := naming.Collector(params.OtelCol.Name)
labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter())

annotations, err := Annotations(params.OtelCol)
annotations, err := manifestutils.Annotations(params.OtelCol, params.Config.AnnotationsFilter())
if err != nil {
return nil, err
}

podAnnotations, err := PodAnnotations(params.OtelCol)
podAnnotations, err := manifestutils.PodAnnotations(params.OtelCol, params.Config.AnnotationsFilter())
if err != nil {
return nil, err
}
Expand Down
31 changes: 31 additions & 0 deletions internal/manifests/collector/statefulset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,37 @@ func TestStatefulSetFilterLabels(t *testing.T) {
}
}

func TestStatefulSetFilterAnnotations(t *testing.T) {
excludedAnnotations := map[string]string{
"foo": "1",
"app.foo.bar": "1",
}

otelcol := v1beta1.OpenTelemetryCollector{
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance",
Annotations: excludedAnnotations,
},
Spec: v1beta1.OpenTelemetryCollectorSpec{},
}

cfg := config.New(config.WithAnnotationFilters([]string{"foo*", "app.*.bar"}))

params := manifests.Params{
OtelCol: otelcol,
Config: cfg,
Log: logger,
}

d, err := StatefulSet(params)
require.NoError(t, err)

assert.Len(t, d.ObjectMeta.Annotations, 4)
for k := range excludedAnnotations {
assert.NotContains(t, d.ObjectMeta.Annotations, k)
}
}

func TestStatefulSetNodeSelector(t *testing.T) {
// Test default
otelcol1 := v1beta1.OpenTelemetryCollector{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package collector
package manifestutils

import (
"crypto/sha256"
Expand All @@ -23,7 +23,7 @@ import (
)

// Annotations return the annotations for OpenTelemetryCollector pod.
func Annotations(instance v1beta1.OpenTelemetryCollector) (map[string]string, error) {
func Annotations(instance v1beta1.OpenTelemetryCollector, filterAnnotations []string) (map[string]string, error) {
// new map every time, so that we don't touch the instance's annotations
annotations := map[string]string{}

Expand All @@ -36,9 +36,11 @@ func Annotations(instance v1beta1.OpenTelemetryCollector) (map[string]string, er
}

// allow override of prometheus annotations
if nil != instance.Annotations {
for k, v := range instance.Annotations {
annotations[k] = v
if nil != instance.ObjectMeta.Annotations {
for k, v := range instance.ObjectMeta.Annotations {
if !IsFilteredSet(k, filterAnnotations) {
annotations[k] = v
}
}
}

Expand All @@ -54,16 +56,18 @@ func Annotations(instance v1beta1.OpenTelemetryCollector) (map[string]string, er
}

// PodAnnotations return the spec annotations for OpenTelemetryCollector pod.
func PodAnnotations(instance v1beta1.OpenTelemetryCollector) (map[string]string, error) {
func PodAnnotations(instance v1beta1.OpenTelemetryCollector, filterAnnotations []string) (map[string]string, error) {
// new map every time, so that we don't touch the instance's annotations
podAnnotations := map[string]string{}

// allow override of pod annotations
for k, v := range instance.Spec.PodAnnotations {
podAnnotations[k] = v
if nil != instance.Spec.PodAnnotations {
for k, v := range instance.Spec.PodAnnotations {
if !IsFilteredSet(k, filterAnnotations) {
podAnnotations[k] = v
}
}
}

annotations, err := Annotations(instance)
annotations, err := Annotations(instance, filterAnnotations)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 08b33a5

Please sign in to comment.