github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/monitor/internal/kubernetes/cache.go (about) 1 // +build !windows 2 3 package kubernetesmonitor 4 5 import ( 6 "sync" 7 8 "go.aporeto.io/trireme-lib/policy" 9 ) 10 11 // puidCacheEntry is a Kubernetes entry based on Docker as a key. 12 // This entry keeps track of the DockerMonitor properties that cannot be queried later on (such as the runtime) 13 type puidCacheEntry struct { 14 // podID is the reference to the Kubernetes pod that this container refers to 15 kubeIdentifier string 16 17 // The latest reference to the runtime as received from DockerMonitor 18 dockerRuntime policy.RuntimeReader 19 20 // The latest reference to the runtime as received from DockerMonitor 21 kubernetesRuntime policy.RuntimeReader 22 } 23 24 // podCacheEntry is a Kubernetes entry based on a Pod as Key. The main goal here is to keep a mapping to all 25 // existing Dockers PUIDs implementing this pod (as there might be multiple) 26 type podCacheEntry struct { 27 // puIDs us a map containing a link to all the containers currently known to be part of that pod. 28 puIDs map[string]bool 29 } 30 31 // Cache is a cache implementation specific to KubernetesMonitor. 32 // puidCache is centered on Docker and podCache is centered on Kubernetes 33 type cache struct { 34 // popuidCache keeps a mapping between a PUID and the corresponding puidCacheEntry. 35 puidCache map[string]*puidCacheEntry 36 37 // podCache keeps a mapping between a POD/Namespace name and the corresponding podCacheEntry. 38 podCache map[string]*podCacheEntry 39 40 // Lock for the whole cache 41 sync.RWMutex 42 } 43 44 // NewCache initialize a cache 45 func newCache() *cache { 46 return &cache{ 47 puidCache: map[string]*puidCacheEntry{}, 48 podCache: map[string]*podCacheEntry{}, 49 } 50 } 51 52 func kubePodIdentifier(podName string, podNamespace string) string { 53 return podNamespace + "/" + podName 54 } 55 56 // updatePUIDCache updates the cache with an entry coming from a container perspective 57 func (c *cache) updatePUIDCache(podNamespace string, podName string, puID string, dockerRuntime policy.RuntimeReader, kubernetesRuntime policy.RuntimeReader) { 58 if podNamespace == "" || podName == "" || puID == "" { 59 return 60 } 61 62 c.Lock() 63 defer c.Unlock() 64 65 kubeIdentifier := kubePodIdentifier(podName, podNamespace) 66 67 puidEntry, ok := c.puidCache[puID] 68 if !ok { 69 puidEntry = &puidCacheEntry{} 70 c.puidCache[puID] = puidEntry 71 } 72 puidEntry.kubeIdentifier = kubeIdentifier 73 puidEntry.dockerRuntime = dockerRuntime 74 puidEntry.kubernetesRuntime = kubernetesRuntime 75 76 podEntry, ok := c.podCache[kubeIdentifier] 77 if !ok { 78 podEntry = &podCacheEntry{} 79 podEntry.puIDs = map[string]bool{} 80 c.podCache[kubeIdentifier] = podEntry 81 } 82 podEntry.puIDs[puID] = true 83 84 } 85 86 // deletePUIDCache deletes puid corresponding entries from the cache. 87 func (c *cache) deletePUIDCache(puID string) { 88 c.Lock() 89 defer c.Unlock() 90 91 // Remove from pod cache. 92 puidEntry, ok := c.puidCache[puID] 93 if !ok { 94 return 95 } 96 kubeIdentifier := puidEntry.kubeIdentifier 97 98 podEntry, ok := c.podCache[kubeIdentifier] 99 if !ok { 100 return 101 } 102 103 delete(podEntry.puIDs, puID) 104 105 // if no more containers in the pod, delete the podEntry. 106 if len(podEntry.puIDs) == 0 { 107 delete(c.podCache, kubeIdentifier) 108 } 109 110 // delete entry in puidcache 111 delete(c.puidCache, puID) 112 } 113 114 // getOrCreatePodFromCache locks the cache in order to return the pod cache entry if found, or create it if not found 115 func (c *cache) getPUIDsbyPod(podNamespace string, podName string) []string { 116 c.RLock() 117 defer c.RUnlock() 118 119 kubeIdentifier := kubePodIdentifier(podName, podNamespace) 120 podEntry, ok := c.podCache[kubeIdentifier] 121 if !ok { 122 return []string{} 123 } 124 125 return keysFromMap(podEntry.puIDs) 126 } 127 128 // getRuntimeByPUID locks the cache in order to return the pod cache entry if found, or create it if not found 129 func (c *cache) getDockerRuntimeByPUID(puid string) policy.RuntimeReader { 130 c.RLock() 131 defer c.RUnlock() 132 133 puidEntry, ok := c.puidCache[puid] 134 if !ok { 135 return nil 136 } 137 138 return puidEntry.dockerRuntime 139 } 140 141 // getRuntimeByPUID locks the cache in order to return the pod cache entry if found, or create it if not found 142 func (c *cache) getKubernetesRuntimeByPUID(puid string) policy.RuntimeReader { 143 c.RLock() 144 defer c.RUnlock() 145 146 puidEntry, ok := c.puidCache[puid] 147 if !ok { 148 return nil 149 } 150 151 return puidEntry.kubernetesRuntime 152 } 153 154 // deletePodEntry locks the cache in order to deletes pod cache entry. 155 func (c *cache) deletePodEntry(podNamespace string, podName string) { 156 c.Lock() 157 defer c.Unlock() 158 159 kubeIdentifier := kubePodIdentifier(podName, podNamespace) 160 161 delete(c.podCache, kubeIdentifier) 162 } 163 164 // deletePUID locks the cache in order to delete the puid from puidcache. 165 func (c *cache) deletePUIDEntry(puid string) { 166 c.Lock() 167 defer c.Unlock() 168 169 delete(c.puidCache, puid) 170 } 171 172 func keysFromMap(m map[string]bool) []string { 173 keys := make([]string, len(m)) 174 175 i := 0 176 for k := range m { 177 keys[i] = k 178 i++ 179 } 180 181 return keys 182 }