@@ -10,35 +10,41 @@ import (
10
10
k8serrors "k8s.io/apimachinery/pkg/api/errors"
11
11
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12
12
"k8s.io/apimachinery/pkg/fields"
13
+ "k8s.io/apimachinery/pkg/watch"
13
14
"k8s.io/client-go/kubernetes"
14
15
restclient "k8s.io/client-go/rest"
15
16
)
16
17
18
+ const (
19
+ kubesharkConfigmapName = "kubeshark-config-map"
20
+ resolverHistoryAnnotation = "resolver.kubeshark.io/history"
21
+ )
22
+
17
23
type Watcher struct {
18
- clientConfig * restclient.Config
19
- clientSet * kubernetes.Clientset
20
- regex * regexp.Regexp
21
- namespaces []string
22
- isStarted bool
23
- errOut chan error
24
- callback func (pods []v1.Pod ) error
24
+ clientConfig * restclient.Config
25
+ clientSet * kubernetes.Clientset
26
+ regex * regexp.Regexp
27
+ namespaces []string
28
+ isStarted bool
29
+ lastUpdatedAt string
30
+ errOut chan error
31
+ callback func (pods []v1.Pod ) error
25
32
}
26
33
27
34
func (watcher * Watcher ) Start (ctx context.Context , clusterMode bool ) {
28
35
if ! watcher .isStarted {
29
36
watcher .isStarted = true
30
37
31
38
if clusterMode {
32
- go watcher .infiniteErrorHandleRetryFunc (ctx , watcher .watchConfigMap )
33
- go watcher .infiniteErrorHandleRetryFunc (ctx , watcher .watchPods )
39
+ go watcher .infiniteErrorHandleRetryFunc (ctx , watcher .watchKubesharkConfigMap )
34
40
}
35
41
}
36
42
}
37
43
38
- func (watcher * Watcher ) watchConfigMap (ctx context.Context ) error {
44
+ func (watcher * Watcher ) watchKubesharkConfigMap (ctx context.Context ) error {
39
45
w , err := watcher .clientSet .CoreV1 ().ConfigMaps (GetSelfNamespace ()).Watch (ctx , metav1.ListOptions {
40
46
Watch : true ,
41
- FieldSelector : fields .OneTermEqualSelector (metav1 .ObjectNameField , "kubeshark-config-map" ).String (),
47
+ FieldSelector : fields .OneTermEqualSelector (metav1 .ObjectNameField , kubesharkConfigmapName ).String (),
42
48
})
43
49
if err != nil {
44
50
return err
@@ -48,52 +54,16 @@ func (watcher *Watcher) watchConfigMap(ctx context.Context) error {
48
54
select {
49
55
case event := <- w .ResultChan ():
50
56
if event .Object == nil {
51
- return errors .New ("error in kubectl endpoint watch" )
52
- }
53
- watcher .regex , watcher .namespaces = SyncConfig (event .Object .(* v1.ConfigMap ))
54
-
55
- err = updateCurrentlyTargetedPods (ctx , watcher .clientSet , watcher .regex , watcher .namespaces , watcher .callback )
56
- if err != nil {
57
- log .Error ().Err (err ).Send ()
58
- }
59
- case <- ctx .Done ():
60
- w .Stop ()
61
- return nil
62
- }
63
- }
64
- }
65
-
66
- func (watcher * Watcher ) watchPods (ctx context.Context ) error {
67
- // empty namespace makes the client watch all namespaces
68
- kubesharkLabels := map [string ]string {"app.kubernetes.io/name" : "kubeshark" }
69
- w , err := watcher .clientSet .CoreV1 ().Pods (allNamespaces ).Watch (ctx , metav1.ListOptions {Watch : true })
70
- if err != nil {
71
- w , err = watcher .clientSet .CoreV1 ().Pods (GetSelfNamespace ()).Watch (ctx , metav1.ListOptions {Watch : true })
72
- if err != nil {
73
- return err
74
- }
75
- }
76
- if err != nil {
77
- return err
78
- }
79
- for {
80
- select {
81
- case event := <- w .ResultChan ():
82
- if event .Object == nil {
83
- return errors .New ("error in kubectl pod watch" )
84
- }
85
-
86
- pod := event .Object .(* v1.Pod )
87
- if mapsContain (pod .ObjectMeta .Labels , kubesharkLabels ) {
88
- // ignore kubeshark pods
89
- continue
57
+ return errors .New ("error in kubeshark configmap watch" )
90
58
}
59
+ if watcher .isHistoryUpdated (& event ) {
60
+ watcher .regex , watcher .namespaces = SyncConfig (event .Object .(* v1.ConfigMap ))
91
61
92
- log . Debug (). Str ( "event" , string ( event . Type )). Str ( "pod-name" , pod . Name ). Str ( "namespace" , pod . Namespace ). Send ( )
93
-
94
- err = updateCurrentlyTargetedPods ( ctx , watcher . clientSet , watcher . regex , watcher . namespaces , watcher . callback )
95
- if err != nil {
96
- log . Error (). Err ( err ). Send ()
62
+ err = updateCurrentlyTargetedPods ( ctx , watcher . clientSet , watcher . regex , watcher . namespaces , watcher . callback )
63
+ if err != nil {
64
+ log . Error (). Err ( err ). Send ( )
65
+ }
66
+ watcher . lastUpdatedAt = event . Object .( * v1. ConfigMap ). ObjectMeta . Annotations [ resolverHistoryAnnotation ]
97
67
}
98
68
case <- ctx .Done ():
99
69
w .Stop ()
@@ -121,3 +91,14 @@ func (watcher *Watcher) infiniteErrorHandleRetryFunc(ctx context.Context, fun fu
121
91
}
122
92
}
123
93
}
94
+
95
+ func (watcher * Watcher ) isHistoryUpdated (event * watch.Event ) bool {
96
+ cm := event .Object .(* v1.ConfigMap )
97
+ currentUpdatedAt := cm .ObjectMeta .Annotations [resolverHistoryAnnotation ]
98
+
99
+ if watcher .lastUpdatedAt != currentUpdatedAt || currentUpdatedAt == "" {
100
+ return true
101
+ }
102
+
103
+ return false
104
+ }
0 commit comments