youtubebeat/vendor/github.com/elastic/beats/libbeat/common/kubernetes/metadata.go

158 lines
4.6 KiB
Go

// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package kubernetes
import (
"strings"
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/common/safemapstr"
)
// MetaGenerator builds metadata objects for pods and containers
type MetaGenerator interface {
// ResourceMetadata generates metadata for the given kubernetes object taking to account certain filters
ResourceMetadata(obj Resource) common.MapStr
// PodMetadata generates metadata for the given pod taking to account certain filters
PodMetadata(pod *Pod) common.MapStr
// Containermetadata generates metadata for the given container of a pod
ContainerMetadata(pod *Pod, container string) common.MapStr
}
// MetaGeneratorConfig settings
type MetaGeneratorConfig struct {
IncludeLabels []string `config:"include_labels"`
ExcludeLabels []string `config:"exclude_labels"`
IncludeAnnotations []string `config:"include_annotations"`
// Undocumented settings, to be deprecated in favor of `drop_fields` processor:
IncludePodUID bool `config:"include_pod_uid"`
IncludeCreatorMetadata bool `config:"include_creator_metadata"`
}
type metaGenerator = MetaGeneratorConfig
// NewMetaGenerator initializes and returns a new kubernetes metadata generator
func NewMetaGenerator(cfg *common.Config) (MetaGenerator, error) {
// default settings:
generator := metaGenerator{
IncludeCreatorMetadata: true,
}
err := cfg.Unpack(&generator)
return &generator, err
}
// NewMetaGeneratorFromConfig initializes and returns a new kubernetes metadata generator
func NewMetaGeneratorFromConfig(cfg *MetaGeneratorConfig) MetaGenerator {
return cfg
}
// ResourceMetadata generates metadata for the given kubernetes object taking to account certain filters
func (g *metaGenerator) ResourceMetadata(obj Resource) common.MapStr {
objMeta := obj.GetMetadata()
labelMap := common.MapStr{}
if len(g.IncludeLabels) == 0 {
for k, v := range obj.GetMetadata().Labels {
safemapstr.Put(labelMap, k, v)
}
} else {
labelMap = generateMapSubset(objMeta.Labels, g.IncludeLabels)
}
// Exclude any labels that are present in the exclude_labels config
for _, label := range g.ExcludeLabels {
delete(labelMap, label)
}
annotationsMap := generateMapSubset(objMeta.Annotations, g.IncludeAnnotations)
meta := common.MapStr{}
if objMeta.GetNamespace() != "" {
meta["namespace"] = objMeta.GetNamespace()
}
// Add controller metadata if present
if g.IncludeCreatorMetadata {
for _, ref := range objMeta.OwnerReferences {
if ref.GetController() {
switch ref.GetKind() {
// TODO grow this list as we keep adding more `state_*` metricsets
case "Deployment",
"ReplicaSet",
"StatefulSet":
safemapstr.Put(meta, strings.ToLower(ref.GetKind())+".name", ref.GetName())
}
}
}
}
if len(labelMap) != 0 {
meta["labels"] = labelMap
}
if len(annotationsMap) != 0 {
meta["annotations"] = annotationsMap
}
return meta
}
// PodMetadata generates metadata for the given pod taking to account certain filters
func (g *metaGenerator) PodMetadata(pod *Pod) common.MapStr {
podMeta := g.ResourceMetadata(pod)
// Add UID metadata if enabled
if g.IncludePodUID {
safemapstr.Put(podMeta, "pod.uid", pod.GetMetadata().GetUid())
}
safemapstr.Put(podMeta, "pod.name", pod.GetMetadata().GetName())
safemapstr.Put(podMeta, "node.name", pod.Spec.GetNodeName())
return podMeta
}
// Containermetadata generates metadata for the given container of a pod
func (g *metaGenerator) ContainerMetadata(pod *Pod, container string) common.MapStr {
podMeta := g.PodMetadata(pod)
// Add container details
podMeta["container"] = common.MapStr{
"name": container,
}
return podMeta
}
func generateMapSubset(input map[string]string, keys []string) common.MapStr {
output := common.MapStr{}
if input == nil {
return output
}
for _, key := range keys {
value, ok := input[key]
if ok {
safemapstr.Put(output, key, value)
}
}
return output
}