Skip to content

Commit 62958d0

Browse files
gizastetianakravchenkordner
authored
[Elastic Agent]-PR- Introduce log message for not supported annotations for Hints based autodiscover (#4360)
* first commit with checks for hints vocabulary * updating to elastic-agent-autodiscovery v.0.6.13 * adding test TestGenerateHints * adding test TestGenerateHints * adding function to override sonarcube --------- Co-authored-by: Tetiana Kravchenko <tetiana.kravchenko@elastic.co> Co-authored-by: Denis <denis.rechkunov@elastic.co>
1 parent f25124a commit 62958d0

File tree

8 files changed

+235
-9
lines changed

8 files changed

+235
-9
lines changed

NOTICE.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -722,11 +722,11 @@ these terms.
722722

723723
--------------------------------------------------------------------------------
724724
Dependency : github.com/elastic/elastic-agent-autodiscover
725-
Version: v0.6.8
725+
Version: v0.6.13
726726
Licence type (autodetected): Apache-2.0
727727
--------------------------------------------------------------------------------
728728

729-
Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-autodiscover@v0.6.8/LICENSE:
729+
Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-autodiscover@v0.6.13/LICENSE:
730730

731731
Apache License
732732
Version 2.0, January 2004
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Kind can be one of:
2+
# - breaking-change: a change to previously-documented behavior
3+
# - deprecation: functionality that is being removed in a later release
4+
# - bug-fix: fixes a problem in a previous version
5+
# - enhancement: extends functionality but does not break or fix existing behavior
6+
# - feature: new functionality
7+
# - known-issue: problems that we are aware of in a given version
8+
# - security: impacts on the security of a product or a user’s deployment.
9+
# - upgrade: important information for someone upgrading from a prior version
10+
# - other: does not fit into any of the other categories
11+
kind: enhancement
12+
13+
# Change summary; a 80ish characters long description of the change.
14+
summary: Introduce log message for not supported annotations for Hints based autodiscover
15+
16+
# Long description; in case the summary is not enough to describe the change
17+
# this field accommodate a description without length limits.
18+
# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment.
19+
#description:
20+
21+
# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc.
22+
component: elastic-agent
23+
24+
# PR URL; optional; the PR number that added the changeset.
25+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
26+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
27+
# Please provide it if you are adding a fragment for a different PR.
28+
pr: https://github.com/elastic/elastic-agent/pull/4360
29+
30+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
31+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
32+
issue: https://github.com/elastic/elastic-agent/issues/3064

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ require (
1414
github.com/docker/go-units v0.5.0
1515
github.com/dolmen-go/contextio v0.0.0-20200217195037-68fc5150bcd5
1616
github.com/elastic/e2e-testing v1.2.1
17-
github.com/elastic/elastic-agent-autodiscover v0.6.8
17+
github.com/elastic/elastic-agent-autodiscover v0.6.13
1818
github.com/elastic/elastic-agent-client/v7 v7.8.1
1919
github.com/elastic/elastic-agent-libs v0.9.7
2020
github.com/elastic/elastic-agent-system-metrics v0.9.2

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -791,8 +791,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
791791
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
792792
github.com/elastic/e2e-testing v1.2.1 h1:jIuikohPtTxtO+bfoVEyKAWmcsAl21lxiiTK8Fj+G8U=
793793
github.com/elastic/e2e-testing v1.2.1/go.mod h1:8q2d8dmwavJXISowwaoreHFBnbR/uK4qanfRGhC/W9A=
794-
github.com/elastic/elastic-agent-autodiscover v0.6.8 h1:BSXz+QwjZAEt08G+T3GDGl14Bh9a6zD8luNCvZut/b8=
795-
github.com/elastic/elastic-agent-autodiscover v0.6.8/go.mod h1:hFeFqneS2r4jD0/QzGkrNk0YVdN0JGh7lCWdsH7zcI4=
794+
github.com/elastic/elastic-agent-autodiscover v0.6.13 h1:zBeTxV+o2efEKntY+o6iMMNJ1AVjDXUqY3o6uzIkKaw=
795+
github.com/elastic/elastic-agent-autodiscover v0.6.13/go.mod h1:7P6YVKxuBT0qE/VxuA87obwZUAEU0O44mCN3r4/6x8w=
796796
github.com/elastic/elastic-agent-client/v7 v7.8.1 h1:J9wZc/0mUvSEok0X5iR5+n60Jgb+AWooKddb3XgPWqM=
797797
github.com/elastic/elastic-agent-client/v7 v7.8.1/go.mod h1:axl1nkdqc84YRFkeJGD9jExKNPUrOrzf3DFo2m653nY=
798798
github.com/elastic/elastic-agent-libs v0.9.7 h1:LZdfxbq724Y1zAdE3COp+OIPwU8SquOCLIXpI/twcdQ=

internal/pkg/composable/providers/kubernetes/hints.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ const (
3030
processors = "processors"
3131
)
3232

33+
var allSupportedHints = []string{"enabled", integration, datastreams, host, period, timeout, metricspath, username, password, stream, processors}
34+
3335
type hintsBuilder struct {
3436
Key string
3537

@@ -288,7 +290,7 @@ func GetHintsMapping(k8sMapping map[string]interface{}, logger *logp.Logger, pre
288290
}
289291
}
290292

291-
hintsExtracted := utils.GenerateHints(annotations, cName, prefix)
293+
hintsExtracted, _ := utils.GenerateHints(annotations, cName, prefix, false, allSupportedHints)
292294
if len(hintsExtracted) == 0 {
293295
return hintData
294296
}

internal/pkg/composable/providers/kubernetes/hints_test.go

+131
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,137 @@ func TestGenerateHintsMappingWithLogStream(t *testing.T) {
367367
assert.Equal(t, expected, hintsMapping)
368368
}
369369

370+
func TestGenerateHintsMappingWithDefaultsandTypo(t *testing.T) {
371+
logger := getLogger()
372+
pod := &kubernetes.Pod{
373+
ObjectMeta: metav1.ObjectMeta{
374+
Name: "testpod",
375+
UID: types.UID(uid),
376+
Namespace: "testns",
377+
Labels: map[string]string{
378+
"foo": "bar",
379+
},
380+
Annotations: map[string]string{
381+
"app": "production",
382+
},
383+
},
384+
TypeMeta: metav1.TypeMeta{
385+
Kind: "Pod",
386+
APIVersion: "v1",
387+
},
388+
Spec: kubernetes.PodSpec{
389+
NodeName: "testnode",
390+
},
391+
Status: kubernetes.PodStatus{PodIP: "127.0.0.5"},
392+
}
393+
394+
mapping := map[string]interface{}{
395+
"namespace": pod.GetNamespace(),
396+
"pod": mapstr.M{
397+
"uid": string(pod.GetUID()),
398+
"name": pod.GetName(),
399+
"ip": pod.Status.PodIP,
400+
},
401+
"namespace_annotations": mapstr.M{
402+
"nsa": "nsb",
403+
},
404+
"labels": mapstr.M{
405+
"foo": "bar",
406+
},
407+
"annotations": mapstr.M{
408+
"app": "production",
409+
},
410+
}
411+
hints := mapstr.M{
412+
"hints": mapstr.M{
413+
"host": "${kubernetes.pod.ip}:6379",
414+
"package": "redis",
415+
"notsupportedhint": "/metrics", // on purpose we have introduced a typo
416+
"timeout": "42s",
417+
"period": "42s",
418+
},
419+
}
420+
421+
expected := mapstr.M{
422+
"redis": mapstr.M{
423+
"enabled": true,
424+
"host": "127.0.0.5:6379",
425+
"timeout": "42s",
426+
"period": "42s",
427+
},
428+
}
429+
430+
hintsMapping := GenerateHintsMapping(hints, mapping, logger, "")
431+
432+
assert.Equal(t, expected, hintsMapping)
433+
}
434+
435+
func TestGenerateHintsMappingWithInfoandTypo(t *testing.T) {
436+
logger := getLogger()
437+
pod := &kubernetes.Pod{
438+
ObjectMeta: metav1.ObjectMeta{
439+
Name: "testpod",
440+
UID: types.UID(uid),
441+
Namespace: "testns",
442+
Labels: map[string]string{
443+
"foo": "bar",
444+
},
445+
Annotations: map[string]string{
446+
"app": "production",
447+
},
448+
},
449+
TypeMeta: metav1.TypeMeta{
450+
Kind: "Pod",
451+
APIVersion: "v1",
452+
},
453+
Spec: kubernetes.PodSpec{
454+
NodeName: "testnode",
455+
},
456+
Status: kubernetes.PodStatus{PodIP: "127.0.0.5"},
457+
}
458+
459+
mapping := map[string]interface{}{
460+
"namespace": pod.GetNamespace(),
461+
"pod": mapstr.M{
462+
"uid": string(pod.GetUID()),
463+
"name": pod.GetName(),
464+
"ip": pod.Status.PodIP,
465+
},
466+
"namespace_annotations": mapstr.M{
467+
"nsa": "nsb",
468+
},
469+
"labels": mapstr.M{
470+
"foo": "bar",
471+
},
472+
"annotations": mapstr.M{
473+
"app": "production",
474+
},
475+
}
476+
hints := mapstr.M{
477+
"hints": mapstr.M{
478+
"package": "redis",
479+
"data_streams": "info",
480+
"info": mapstr.M{
481+
"period": "5m",
482+
"notsupportedhint": "stdout", // On purpose we have added this typo
483+
},
484+
},
485+
}
486+
487+
expected := mapstr.M{
488+
"redis": mapstr.M{
489+
"info": mapstr.M{
490+
"enabled": true,
491+
"period": "5m",
492+
},
493+
},
494+
}
495+
496+
hintsMapping := GenerateHintsMapping(hints, mapping, logger, "")
497+
498+
assert.Equal(t, expected, hintsMapping)
499+
}
500+
370501
func TestGenerateHintsMappingWithProcessors(t *testing.T) {
371502
logger := getLogger()
372503
pod := &kubernetes.Pod{

internal/pkg/composable/providers/kubernetes/pod.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ import (
99
"sync"
1010
"time"
1111

12-
"github.com/elastic/elastic-agent-autodiscover/utils"
13-
1412
"github.com/elastic/elastic-agent-autodiscover/kubernetes"
1513
"github.com/elastic/elastic-agent-autodiscover/kubernetes/metadata"
14+
"github.com/elastic/elastic-agent-autodiscover/utils"
1615
c "github.com/elastic/elastic-agent-libs/config"
1716
"github.com/elastic/elastic-agent-libs/logp"
1817
"github.com/elastic/elastic-agent-libs/mapstr"
@@ -217,7 +216,7 @@ func (p *pod) emitRunning(pod *kubernetes.Pod) {
217216
if !p.managed {
218217
if ann, ok := data.mapping["annotations"]; ok {
219218
annotations, _ := ann.(mapstr.M)
220-
hints := utils.GenerateHints(annotations, "", p.config.Prefix)
219+
hints, _ := hintsCheck(annotations, "", p.config.Prefix, true, allSupportedHints, p.logger, pod)
221220
if len(hints) > 0 {
222221
p.logger.Debugf("Extracted hints are :%v", hints)
223222
hintsMapping := GenerateHintsMapping(hints, data.mapping, p.logger, "")
@@ -525,3 +524,12 @@ func updateProcessors(newprocessors []mapstr.M, processors []map[string]interfac
525524

526525
return processors
527526
}
527+
528+
// HintsCheck geenrates hints from provided annotations of the pod and logs any possible incorrect annotations that have been provided in the pod
529+
func hintsCheck(annotations mapstr.M, container string, prefix string, validate bool, allSupportedHints []string, logger *logp.Logger, pod *kubernetes.Pod) (mapstr.M, []string) {
530+
hints, incorrecthints := utils.GenerateHints(annotations, container, prefix, validate, allSupportedHints)
531+
for _, value := range incorrecthints { //We check whether the provided annotation follows the supported format and vocabulary. The check happens for annotations that have prefix co.elastic
532+
logger.Warnf("provided hint: %s/%s is not recognised as supported annotation for pod %s in namespace %s", prefix, value, pod.Name, pod.ObjectMeta.Namespace)
533+
}
534+
return hints, incorrecthints
535+
}

internal/pkg/composable/providers/kubernetes/pod_test.go

+53
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,59 @@ func TestEphemeralContainers(t *testing.T) {
375375

376376
}
377377

378+
func TestGenerateHints(t *testing.T) {
379+
pod := &kubernetes.Pod{
380+
ObjectMeta: metav1.ObjectMeta{
381+
Name: "testpod",
382+
UID: types.UID(uid),
383+
Namespace: "testns",
384+
Labels: map[string]string{
385+
"foo": "bar",
386+
},
387+
Annotations: map[string]string{
388+
"app": "production",
389+
"co.elastic.hints/host": "${kubernetes.pod.ip}:6379",
390+
"co.elastic.hints/package": "redis",
391+
"co.elastic.hints/metricssssssspath": "/metrics",
392+
"co.elastic.hints/period": "42s",
393+
},
394+
},
395+
TypeMeta: metav1.TypeMeta{
396+
Kind: "Pod",
397+
APIVersion: "v1",
398+
},
399+
Spec: kubernetes.PodSpec{
400+
NodeName: "testnode",
401+
},
402+
Status: kubernetes.PodStatus{PodIP: "127.0.0.5"},
403+
}
404+
405+
data := generatePodData(pod, &podMeta{}, mapstr.M{})
406+
407+
hints_result := mapstr.M{
408+
"hints": mapstr.M{
409+
"host": "${kubernetes.pod.ip}:6379",
410+
"package": "redis",
411+
"metricssssssspath": "/metrics", // on purpose we have introduced a typo
412+
"period": "42s",
413+
},
414+
}
415+
incorrecthints_results := []string{"hints/metricssssssspath"}
416+
417+
ann := data.mapping["annotations"]
418+
annotations, _ := ann.(mapstr.M)
419+
prefix := "co.elastic"
420+
421+
log, err := logger.New("hint-test", true)
422+
assert.NoError(t, err)
423+
424+
hints, incorrecthints := hintsCheck(annotations, "", prefix, true, allSupportedHints, log, pod)
425+
426+
assert.Equal(t, string(pod.GetUID()), data.uid)
427+
assert.Equal(t, hints, hints_result)
428+
assert.Equal(t, incorrecthints, incorrecthints_results)
429+
}
430+
378431
func TestPodEventer_Namespace_Node_Watcher(t *testing.T) {
379432
client := k8sfake.NewSimpleClientset()
380433

0 commit comments

Comments
 (0)