-
Notifications
You must be signed in to change notification settings - Fork 24
/
cache.go
100 lines (90 loc) · 3.37 KB
/
cache.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
package k8s
import (
"log"
"time"
"github.com/jetstack/preflight/api"
"github.com/pmylund/go-cache"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
// time interface, this is used to fetch the current time
// whenever a k8s resource is deleted
type timeInterface interface {
now() time.Time
}
var clock timeInterface = &realTime{}
type realTime struct {
}
func (*realTime) now() time.Time {
return time.Now()
}
// onAdd handles the informer creation events, adding the created runtime.Object
// to the data gatherer's cache. The cache key is the uid of the object
func onAdd(obj interface{}, dgCache *cache.Cache) {
item := obj.(*unstructured.Unstructured)
if metadata, ok := item.Object["metadata"]; ok {
data := metadata.(map[string]interface{})
if uid, ok := data["uid"]; ok {
cacheObject := &api.GatheredResource{
Resource: obj,
}
dgCache.Set(uid.(string), cacheObject, cache.DefaultExpiration)
} else {
log.Printf("could not %q resource %q to the cache, missing uid field", "add", data["name"].(string))
}
} else {
log.Printf("could not %q resource to the cache, missing metadata", "add")
}
}
// onUpdate handles the informer update events, replacing the old object with the new one
// if it's present in the data gatherer's cache, (if the object isn't present, it gets added).
// The cache key is the uid of the object
func onUpdate(old, new interface{}, dgCache *cache.Cache) {
item := old.(*unstructured.Unstructured)
if metadata, ok := item.Object["metadata"]; ok {
data := metadata.(map[string]interface{})
if uid, ok := data["uid"]; ok {
cacheObject := updateCacheGatheredResource(uid.(string), new, dgCache)
dgCache.Set(uid.(string), cacheObject, cache.DefaultExpiration)
} else {
log.Printf("could not %q resource %q to the cache, missing uid field", "update", data["name"].(string))
}
} else {
log.Printf("could not %q resource to the cache, missing metadata", "update")
}
}
// onDelete handles the informer deletion events, updating the object's properties with the deletion
// time of the object (but not removing the object from the cache).
// The cache key is the uid of the object
func onDelete(obj interface{}, dgCache *cache.Cache) {
item := obj.(*unstructured.Unstructured)
if metadata, ok := item.Object["metadata"]; ok {
data := metadata.(map[string]interface{})
if uid, ok := data["uid"]; ok {
cacheObject := updateCacheGatheredResource(uid.(string), obj, dgCache)
cacheObject.DeletedAt = api.Time{Time: clock.now()}
dgCache.Set(uid.(string), cacheObject, cache.DefaultExpiration)
} else {
log.Printf("could not %q resource %q to the cache, missing uid field", "delete", data["name"].(string))
}
} else {
log.Printf("could not %q resource to the cache, missing metadata", "delete")
}
}
// creates a new updated instance of a cache object, with the resource
// argument. If the object is present in the cache it fetches the object's
// properties.
func updateCacheGatheredResource(cacheKey string, resource interface{},
dgCache *cache.Cache) *api.GatheredResource {
// updated cache object
cacheObject := &api.GatheredResource{
Resource: resource,
}
// update the object's properties, if it's already in the cache
if o, ok := dgCache.Get(cacheKey); ok {
deletedAt := o.(*api.GatheredResource).DeletedAt
if deletedAt.IsZero() && !deletedAt.IsZero() {
cacheObject.DeletedAt = deletedAt
}
}
return cacheObject
}