forked from kyma-project/kyma
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sbu_tracer.go
115 lines (94 loc) · 3.6 KB
/
sbu_tracer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package controller
import (
"encoding/json"
"github.com/pkg/errors"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
tracingAnnotationKey = "servicebindingusages.servicecatalog.kyma.cx/tracing-information"
)
//go:generate mockery -name=usageBindingAnnotationTracer -output=automock -outpkg=automock -case=underscore
type usageBindingAnnotationTracer interface {
GetInjectedLabels(objMeta metaV1.ObjectMeta, usageName string) (map[string]string, error)
DeleteAnnotationAboutBindingUsage(objMeta *metaV1.ObjectMeta, usageName string) error
SetAnnotationAboutBindingUsage(objMeta *metaV1.ObjectMeta, usageName string, labels map[string]string) error
}
// usageAnnotationTracer adds information in Kubernetes resources that they have been modified
// by given ServiceBindingUsage
type usageAnnotationTracer struct{}
// GetInjectedLabels returns all labels that have been added to given resources
func (c *usageAnnotationTracer) GetInjectedLabels(objMeta metaV1.ObjectMeta, usageName string) (map[string]string, error) {
if objMeta.Annotations == nil {
return map[string]string{}, nil
}
data, found, err := c.readAnnotationData(&objMeta)
if err != nil {
return map[string]string{}, errors.Wrapf(err, "while reading binding usage annotation tracing data")
}
if !found {
return map[string]string{}, nil
}
info, found := data[usageName]
if !found {
return map[string]string{}, nil
}
return info.InjectedLabelKeys, nil
}
func (c *usageAnnotationTracer) DeleteAnnotationAboutBindingUsage(objMeta *metaV1.ObjectMeta, usageName string) error {
data, found, err := c.readAnnotationData(objMeta)
if err != nil {
return errors.Wrap(err, "while reading annotation tracing data")
}
if !found {
return nil
}
delete(data, usageName)
err = c.saveAnnotationData(objMeta, data)
if err != nil {
return errors.Wrap(err, "while saving annotation tracing data")
}
return nil
}
// SetAnnotationAboutBindingUsage sets annotations about injected labels keys
func (c *usageAnnotationTracer) SetAnnotationAboutBindingUsage(objMeta *metaV1.ObjectMeta, usageName string, labels map[string]string) error {
data, _, err := c.readAnnotationData(objMeta)
if err != nil {
return errors.Wrap(err, "while reading annotation tracing data")
}
info := data[usageName]
info.InjectedLabelKeys = labels
data[usageName] = info
err = c.saveAnnotationData(objMeta, data)
if err != nil {
return errors.Wrap(err, "while saving annotation tracing data")
}
return nil
}
// sbuTracingInfo represents stored (in annotation) data about applied service binding usage
type sbuTracingInfo struct {
InjectedLabelKeys map[string]string `json:"injectedLabels"`
}
func (c *usageAnnotationTracer) readAnnotationData(objMeta *metaV1.ObjectMeta) (map[string]sbuTracingInfo, bool, error) {
value, found := objMeta.Annotations[tracingAnnotationKey]
if !found {
return map[string]sbuTracingInfo{}, false, nil
}
var data map[string]sbuTracingInfo
err := json.Unmarshal([]byte(value), &data)
if err != nil {
return map[string]sbuTracingInfo{}, false, errors.Wrapf(err, "while unmarshalling annotation tracing data")
}
return data, true, nil
}
func (c *usageAnnotationTracer) saveAnnotationData(objMeta *metaV1.ObjectMeta, info map[string]sbuTracingInfo) error {
bytes, err := json.Marshal(info)
if err != nil {
return errors.Wrapf(err, "while marshalling annotation tracing data %+v for object (%s/%s)", info, objMeta.Namespace, objMeta.Name)
}
objMeta.Annotations = EnsureMapIsInitiated(objMeta.Annotations)
objMeta.Annotations[tracingAnnotationKey] = string(bytes)
if len(info) == 0 {
delete(objMeta.Annotations, tracingAnnotationKey)
}
return nil
}