kubernetes/metadata/pod.go (105 lines of code) (raw):

// 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 metadata import ( k8s "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" "github.com/elastic/elastic-agent-autodiscover/kubernetes" "github.com/elastic/elastic-agent-libs/config" "github.com/elastic/elastic-agent-libs/mapstr" ) type pod struct { store cache.Store client k8s.Interface node MetaGen replicaset MetaGen job MetaGen resource *Resource addResourceMetadata *AddResourceMetadataConfig } // NewPodMetadataGenerator creates a metagen for pod resources func NewPodMetadataGenerator( cfg *config.C, pods cache.Store, client k8s.Interface, node MetaGen, namespace MetaGen, replicaset MetaGen, job MetaGen, addResourceMetadata *AddResourceMetadataConfig) MetaGen { return &pod{ resource: NewNamespaceAwareResourceMetadataGenerator(cfg, client, namespace), store: pods, node: node, replicaset: replicaset, job: job, client: client, addResourceMetadata: addResourceMetadata, } } // Generate generates pod metadata from a resource object // Metadata map is in the following form: // // { // "kubernetes": {}, // "some.ecs.field": "asdf" // } // // All Kubernetes fields that need to be stored under kubernetes. prefix are populated by // GenerateK8s method while fields that are part of ECS are generated by GenerateECS method func (p *pod) Generate(obj kubernetes.Resource, opts ...FieldOptions) mapstr.M { ecsFields := p.GenerateECS(obj) meta := mapstr.M{ "kubernetes": p.GenerateK8s(obj, opts...), } meta.DeepUpdate(ecsFields) return meta } // GenerateECS generates pod ECS metadata from a resource object func (p *pod) GenerateECS(obj kubernetes.Resource) mapstr.M { return p.resource.GenerateECS(obj) } // GenerateK8s generates pod metadata from a resource object func (p *pod) GenerateK8s(obj kubernetes.Resource, opts ...FieldOptions) mapstr.M { po, ok := obj.(*kubernetes.Pod) if !ok { return nil } out := p.resource.GenerateK8s("pod", obj, opts...) // check if Pod is handled by a ReplicaSet which is controlled by a Deployment. // The hierarchy there is Deployment->ReplicaSet->Pod. if p.addResourceMetadata.Deployment { if p.replicaset != nil { rsName, _ := out.GetValue("replicaset.name") if rsName, ok := rsName.(string); ok { meta := p.replicaset.GenerateFromName(po.Namespace + "/" + rsName) deploymentName, _ := meta.GetValue("deployment.name") if deploymentName != "" { _, _ = out.Put("deployment.name", deploymentName) } } } } // check if Pod is handled by a Job which is controlled by a CronJob. // The hierarchy there is CronJob->Job->Pod if p.addResourceMetadata.CronJob { if p.job != nil { jobName, _ := out.GetValue("job.name") if jobName, ok := jobName.(string); ok { meta := p.job.GenerateFromName(po.Namespace + "/" + jobName) cronjobName, _ := meta.GetValue("cronjob.name") if cronjobName != "" { _, _ = out.Put("cronjob.name", cronjobName) } } } } if p.node != nil { meta := p.node.GenerateFromName(po.Spec.NodeName, WithMetadata("node")) if meta != nil { _, _ = out.Put("node", meta["node"]) } else { _, _ = out.Put("node.name", po.Spec.NodeName) } } else { _, _ = out.Put("node.name", po.Spec.NodeName) } if po.Status.PodIP != "" { _, _ = out.Put("pod.ip", po.Status.PodIP) } return out } // GenerateFromName generates pod metadata from a pod name func (p *pod) GenerateFromName(name string, opts ...FieldOptions) mapstr.M { if p.store == nil { return nil } if obj, ok, _ := p.store.GetByKey(name); ok { po, ok := obj.(*kubernetes.Pod) if !ok { return nil } return p.GenerateK8s(po, opts...) } return nil }