github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/monitor/extractors/kubernetes.go (about)

     1  package extractors
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"go.aporeto.io/trireme-lib/policy"
     8  	"go.uber.org/zap"
     9  	api "k8s.io/api/core/v1"
    10  )
    11  
    12  // KubernetesPodNameIdentifier is the label used by Docker for the K8S pod name.
    13  const KubernetesPodNameIdentifier = "@usr:io.kubernetes.pod.name"
    14  
    15  // KubernetesPodNamespaceIdentifier is the label used by Docker for the K8S namespace.
    16  const KubernetesPodNamespaceIdentifier = "@usr:io.kubernetes.pod.namespace"
    17  
    18  // KubernetesContainerNameIdentifier is the label used by Docker for the K8S container name.
    19  const KubernetesContainerNameIdentifier = "@usr:io.kubernetes.container.name"
    20  
    21  // KubernetesInfraContainerName is the name of the infra POD.
    22  const KubernetesInfraContainerName = "POD"
    23  
    24  // UpstreamOldNameIdentifier is the identifier used to identify the nane on the resulting PU
    25  // TODO: Remove OLDTAGS
    26  const UpstreamOldNameIdentifier = "@k8s:name"
    27  
    28  // UpstreamNameIdentifier is the identifier used to identify the nane on the resulting PU
    29  const UpstreamNameIdentifier = "@app:k8s:name"
    30  
    31  // UpstreamOldNamespaceIdentifier is the identifier used to identify the nanespace on the resulting PU
    32  const UpstreamOldNamespaceIdentifier = "@k8s:namespace"
    33  
    34  // UpstreamNamespaceIdentifier is the identifier used to identify the nanespace on the resulting PU
    35  const UpstreamNamespaceIdentifier = "@app:k8s:namespace"
    36  
    37  // UserLabelPrefix is the label prefix for all user defined labels
    38  const UserLabelPrefix = "@usr:"
    39  
    40  // KubernetesMetadataExtractorType is an extractor function for Kubernetes.
    41  // It takes as parameter a standard Docker runtime and a Pod Kubernetes definition and return a PolicyRuntime
    42  // This extractor also provides an extra boolean parameter that is used as a token to decide if activation is required.
    43  type KubernetesMetadataExtractorType func(runtime policy.RuntimeReader, pod *api.Pod) (*policy.PURuntime, bool, error)
    44  
    45  // DefaultKubernetesMetadataExtractor is a default implementation for the medatadata extractor for Kubernetes
    46  // It only activates the POD//INFRA containers and strips all the labels from docker to only keep the ones from Kubernetes
    47  func DefaultKubernetesMetadataExtractor(runtime policy.RuntimeReader, pod *api.Pod) (*policy.PURuntime, bool, error) {
    48  
    49  	if runtime == nil {
    50  		return nil, false, fmt.Errorf("empty runtime")
    51  	}
    52  
    53  	if pod == nil {
    54  		return nil, false, fmt.Errorf("empty pod")
    55  	}
    56  
    57  	// In this specific metadataExtractor we only want to activate the Infra Container for each pod.
    58  	if !isPodInfraContainer(runtime) {
    59  		return nil, false, nil
    60  	}
    61  
    62  	podLabels := pod.GetLabels()
    63  	if podLabels == nil {
    64  		podLabels = make(map[string]string)
    65  	}
    66  	for key, value := range podLabels {
    67  		if len(strings.TrimSpace(key)) == 0 {
    68  			delete(podLabels, key)
    69  		}
    70  		if len(value) == 0 {
    71  			podLabels[key] = "<empty>"
    72  		}
    73  	}
    74  
    75  	tags := policy.NewTagStoreFromMap(podLabels)
    76  	tags.AppendKeyValue(UpstreamOldNameIdentifier, pod.GetName())
    77  	tags.AppendKeyValue(UpstreamNameIdentifier, pod.GetName())
    78  	tags.AppendKeyValue(UpstreamOldNamespaceIdentifier, pod.GetNamespace())
    79  	tags.AppendKeyValue(UpstreamNamespaceIdentifier, pod.GetNamespace())
    80  
    81  	originalRuntime, ok := runtime.(*policy.PURuntime)
    82  	if !ok {
    83  		return nil, false, fmt.Errorf("Error casting puruntime")
    84  	}
    85  
    86  	newRuntime := originalRuntime.Clone()
    87  	newRuntime.SetTags(tags)
    88  
    89  	zap.L().Debug("kubernetes runtime tags", zap.String("name", pod.GetName()), zap.String("namespace", pod.GetNamespace()), zap.Strings("tags", newRuntime.Tags().GetSlice()))
    90  
    91  	return newRuntime, true, nil
    92  }
    93  
    94  // isPodInfraContainer returns true if the runtime represents the infra container for the POD
    95  func isPodInfraContainer(runtime policy.RuntimeReader) bool {
    96  	// The Infra container can be found by checking env. variable.
    97  	tagContent, ok := runtime.Tag(KubernetesContainerNameIdentifier)
    98  	if !ok || tagContent != KubernetesInfraContainerName {
    99  		return false
   100  	}
   101  
   102  	return true
   103  }