pkg/process/finders/kubernetes/template.go (152 lines of code) (raw):

// Licensed to Apache Software Foundation (ASF) under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Apache Software Foundation (ASF) 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 ( "fmt" "strconv" "strings" "github.com/apache/skywalking-rover/pkg/process/finders/base" "github.com/shirou/gopsutil/process" "k8s.io/apimachinery/pkg/labels" ) func executeFilter(builders []*base.TemplateBuilder, p *process.Process, pc *PodContainer, finder *ProcessFinder) (bool, error) { if len(builders) == 0 { return true, nil } moduleManager := finder.manager.GetModuleManager() for _, b := range builders { result, err := b.Execute(&FilterContext{ Process: base.NewTemplateProcess(moduleManager, p), Pod: &TemplatePodJudgment{&TemplatePod{pc, finder}}, Container: &TemplateContainer{pc}, }) if err != nil { return false, err } success, err := strconv.ParseBool(result) if err != nil { return false, err } // must all filtering success // if have any false, just short circuit if !success { return false, nil } } return true, nil } func renderTemplate(builder *base.TemplateBuilder, p *process.Process, pc *PodContainer, finder *ProcessFinder) (string, error) { moduleManager := finder.manager.GetModuleManager() return builder.Execute(&EntityRenderContext{ Rover: base.NewTemplateRover(moduleManager), Process: base.NewTemplateProcess(moduleManager, p), Pod: &TemplatePod{pc, finder}, Container: &TemplateContainer{pc}, }) } type FilterContext struct { Process *base.TemplateProcess Pod *TemplatePodJudgment Container *TemplateContainer } type EntityRenderContext struct { Rover *base.TemplateRover Process *base.TemplateProcess Pod *TemplatePod Container *TemplateContainer } type TemplatePod struct { pc *PodContainer finder *ProcessFinder } func (p *TemplatePod) Name() string { return p.pc.Pod.Name } func (p *TemplatePod) Namespace() string { return p.pc.Pod.Namespace } func (p *TemplatePod) Node() string { return p.pc.Pod.Spec.NodeName } func (p *TemplatePod) FindContainer(name string) (*TemplateContainer, error) { container := p.pc.FindContainerFromSamePod(name) if container == nil { return nil, fmt.Errorf("could not found the container") } return &TemplateContainer{pc: container}, nil } func (p *TemplatePod) LabelValue(names, def string) (string, error) { namesArray := strings.Split(names, ",") for _, name := range namesArray { val := p.pc.Pod.Labels[name] if val != "" { return val, nil } } return def, nil } func (p *TemplatePod) ServiceName() string { return p.pc.ServiceName() } func (p *TemplatePod) OwnerName(kindNames string) (string, error) { kindNameArray := strings.Split(kindNames, ",") for _, name := range kindNameArray { if strings.EqualFold(name, "service") { if s := p.ServiceName(); s != "" { return s, nil } continue } if owner, err := p.pc.FindOwner(p.finder.ctx, name, p.finder.k8sConfig); err != nil { return "", err } else if owner != nil { return owner.Name, nil } } return "", fmt.Errorf("could not found owner in %v", kindNameArray) } type TemplatePodJudgment struct { *TemplatePod } func (t *TemplatePodJudgment) HasContainer(name string) bool { // nolint for _, c := range t.pc.Pod.Spec.Containers { if c.Name == name { return true } } return false } func (t *TemplatePodJudgment) LabelSelector(selector string) (bool, error) { labelsMap, err := labels.ConvertSelectorToLabelsMap(selector) if err != nil { return false, err } return labelsMap.AsSelector().Matches(labels.Set(t.pc.Pod.Labels)), nil } func (t *TemplatePodJudgment) HasServiceName() bool { return t.ServiceName() != "" } func (t *TemplatePodJudgment) HasOwnerName(names string) bool { name, err := t.OwnerName(names) return err == nil && name != "" } type TemplateContainer struct { pc *PodContainer } func (c *TemplateContainer) Name() string { return c.pc.ContainerSpec.Name } func (c *TemplateContainer) ID() string { return c.pc.ContainerStatus.ContainerID } func (c *TemplateContainer) EnvValue(names string) (string, error) { namesArray := strings.Split(names, ",") for _, e := range c.pc.ContainerSpec.Env { for _, needName := range namesArray { if e.Name == needName { return e.Value, nil } } } actualNames := make([]string, 0) for _, e := range c.pc.ContainerSpec.Env { actualNames = append(actualNames, e.Name) } return "", fmt.Errorf("could not found matches environment, want names: %v, actual names: %v", namesArray, actualNames) }