...
1 package bsl
2
3 import (
4 "context"
5 "reflect"
6
7 "github.com/go-logr/logr"
8
9 v1 "k8s.io/api/core/v1"
10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11 "k8s.io/apimachinery/pkg/fields"
12 kwatch "k8s.io/apimachinery/pkg/watch"
13
14 "sigs.k8s.io/controller-runtime/pkg/client"
15 )
16
17
18
19 func OnConfigMapUpdate(ctx context.Context, cl client.WithWatch, logger logr.Logger, fn func(cfg *BSLInfo), filters ...string) (kwatch.Interface, error) {
20 list := &v1.ConfigMapList{}
21 watch, err := cl.Watch(ctx, list, &client.ListOptions{
22 FieldSelector: fields.OneTermEqualSelector("metadata.name", BSLInfoConfigMapName),
23 Namespace: metav1.NamespacePublic,
24 })
25 if err != nil {
26 return nil, err
27 }
28 go func() {
29 var old *v1.ConfigMap
30 for event := range watch.ResultChan() {
31 switch event.Type {
32 case kwatch.Added, kwatch.Modified:
33 updatedConfigmap := event.Object.(*v1.ConfigMap)
34 edgeInfoUpdated, err := FromConfigMap(updatedConfigmap)
35 if err != nil {
36 logger.Error(err, "fail to parse bsl info ConfigMap, will watch for update")
37 continue
38 }
39 if old == nil {
40 old = updatedConfigmap
41 fn(edgeInfoUpdated)
42 continue
43 }
44 previousBslInfo, _ := FromConfigMap(old)
45 configMapChanged := !reflect.DeepEqual(previousBslInfo, edgeInfoUpdated)
46 matchedOnFilters := cfgValuesMatches(old, updatedConfigmap, filters)
47 if configMapChanged && matchedOnFilters {
48 old = updatedConfigmap
49 fn(edgeInfoUpdated)
50 }
51 }
52 }
53 }()
54 return watch, err
55 }
56
57 func cfgValuesMatches(old, updated *v1.ConfigMap, filters []string) bool {
58 for _, f := range filters {
59 if old.Data[f] != updated.Data[f] {
60 return true
61 }
62 }
63 return len(filters) == 0
64 }
65
View as plain text