-
Notifications
You must be signed in to change notification settings - Fork 51
/
kubernetes.go
103 lines (79 loc) · 3.78 KB
/
kubernetes.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
package extractors
import (
"fmt"
"strings"
"go.aporeto.io/trireme-lib/policy"
"go.uber.org/zap"
api "k8s.io/api/core/v1"
)
// KubernetesPodNameIdentifier is the label used by Docker for the K8S pod name.
const KubernetesPodNameIdentifier = "@usr:io.kubernetes.pod.name"
// KubernetesPodNamespaceIdentifier is the label used by Docker for the K8S namespace.
const KubernetesPodNamespaceIdentifier = "@usr:io.kubernetes.pod.namespace"
// KubernetesContainerNameIdentifier is the label used by Docker for the K8S container name.
const KubernetesContainerNameIdentifier = "@usr:io.kubernetes.container.name"
// KubernetesInfraContainerName is the name of the infra POD.
const KubernetesInfraContainerName = "POD"
// UpstreamOldNameIdentifier is the identifier used to identify the nane on the resulting PU
// TODO: Remove OLDTAGS
const UpstreamOldNameIdentifier = "@k8s:name"
// UpstreamNameIdentifier is the identifier used to identify the nane on the resulting PU
const UpstreamNameIdentifier = "@app:k8s:name"
// UpstreamOldNamespaceIdentifier is the identifier used to identify the nanespace on the resulting PU
const UpstreamOldNamespaceIdentifier = "@k8s:namespace"
// UpstreamNamespaceIdentifier is the identifier used to identify the nanespace on the resulting PU
const UpstreamNamespaceIdentifier = "@app:k8s:namespace"
// UserLabelPrefix is the label prefix for all user defined labels
const UserLabelPrefix = "@usr:"
// KubernetesMetadataExtractorType is an extractor function for Kubernetes.
// It takes as parameter a standard Docker runtime and a Pod Kubernetes definition and return a PolicyRuntime
// This extractor also provides an extra boolean parameter that is used as a token to decide if activation is required.
type KubernetesMetadataExtractorType func(runtime policy.RuntimeReader, pod *api.Pod) (*policy.PURuntime, bool, error)
// DefaultKubernetesMetadataExtractor is a default implementation for the medatadata extractor for Kubernetes
// It only activates the POD//INFRA containers and strips all the labels from docker to only keep the ones from Kubernetes
func DefaultKubernetesMetadataExtractor(runtime policy.RuntimeReader, pod *api.Pod) (*policy.PURuntime, bool, error) {
if runtime == nil {
return nil, false, fmt.Errorf("empty runtime")
}
if pod == nil {
return nil, false, fmt.Errorf("empty pod")
}
// In this specific metadataExtractor we only want to activate the Infra Container for each pod.
if !isPodInfraContainer(runtime) {
return nil, false, nil
}
podLabels := pod.GetLabels()
if podLabels == nil {
podLabels = make(map[string]string)
}
for key, value := range podLabels {
if len(strings.TrimSpace(key)) == 0 {
delete(podLabels, key)
}
if len(value) == 0 {
podLabels[key] = "<empty>"
}
}
tags := policy.NewTagStoreFromMap(podLabels)
tags.AppendKeyValue(UpstreamOldNameIdentifier, pod.GetName())
tags.AppendKeyValue(UpstreamNameIdentifier, pod.GetName())
tags.AppendKeyValue(UpstreamOldNamespaceIdentifier, pod.GetNamespace())
tags.AppendKeyValue(UpstreamNamespaceIdentifier, pod.GetNamespace())
originalRuntime, ok := runtime.(*policy.PURuntime)
if !ok {
return nil, false, fmt.Errorf("Error casting puruntime")
}
newRuntime := originalRuntime.Clone()
newRuntime.SetTags(tags)
zap.L().Debug("kubernetes runtime tags", zap.String("name", pod.GetName()), zap.String("namespace", pod.GetNamespace()), zap.Strings("tags", newRuntime.Tags().GetSlice()))
return newRuntime, true, nil
}
// isPodInfraContainer returns true if the runtime represents the infra container for the POD
func isPodInfraContainer(runtime policy.RuntimeReader) bool {
// The Infra container can be found by checking env. variable.
tagContent, ok := runtime.Tag(KubernetesContainerNameIdentifier)
if !ok || tagContent != KubernetesInfraContainerName {
return false
}
return true
}