pkg/prom/workload_identity.go
Rama main · réplica de lectura del repositorio original.
package prom
import (
"fmt"
"regexp"
"sort"
"strconv"
"strings"
)
type WorkloadPodIdentity struct {
Name string
UID string
}
var podIdentityUID = regexp.MustCompile(`^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$`)
var cgroupPodUID = regexp.MustCompile(`pod([a-f0-9]{8}[-_][a-f0-9]{4}[-_][a-f0-9]{4}[-_][a-f0-9]{4}[-_][a-f0-9]{12})`)
var podCgroupFormats = []struct{ prefix, separator, suffix string }{
{`/kubepods(/(burstable|besteffort))?/pod`, "-", `/.*`},
{`/kubepods\.slice/(kubepods-(burstable|besteffort)\.slice/)?kubepods(-(burstable|besteffort))?-pod`, "_", `\.slice/.*`},
{`/kubelet\.slice/kubelet-kubepods\.slice/(kubelet-kubepods-(burstable|besteffort)\.slice/)?kubelet-kubepods(-(burstable|besteffort))?-pod`, "_", `\.slice/.*`},
}
func PodUIDFromCgroupID(id string) string {
match := cgroupPodUID.FindStringSubmatch(id)
if len(match) == 0 {
return ""
}
uid := strings.ReplaceAll(match[1], "_", "-")
pattern, err := PodCgroupPattern(uid)
if err != nil || !regexp.MustCompile("^(?:"+pattern+")$").MatchString(id) {
return ""
}
return uid
}
// PodCgroupPattern matches the Pod segment, never a UID appearing in a container name.
func PodCgroupPattern(uid string) (string, error) {
if !podIdentityUID.MatchString(uid) {
return "", fmt.Errorf("invalid Kubernetes Pod UID")
}
patterns := make([]string, 0, len(podCgroupFormats))
for _, format := range podCgroupFormats {
patterns = append(patterns, format.prefix+strings.ReplaceAll(uid, "-", format.separator)+format.suffix)
}
return "(" + strings.Join(patterns, "|") + ")", nil
}
type workloadIdentityFilter struct {
pairs string
beyla bool
}
func workloadMetricExpression(metric, scope, target string, identity *workloadIdentityFilter, window string) string {
expression := workloadMetricSelector(metric, scope, target)
if window != "" {
expression = "rate(" + expression + "[" + window + "])"
}
if identity == nil {
return expression
}
podLabel, uidLabel := "k8s_pod_name", "k8s_pod_uid"
if !identity.beyla {
podLabel, uidLabel = "pod", "__radar_uid"
expression = `label_replace(` + expression + `,"__radar_uid","","",".*")`
for _, driver := range podCgroupFormats {
prefix := strings.ReplaceAll(driver.prefix, "(", "(?:")
uid := `([a-f0-9]{8})` + driver.separator + `([a-f0-9]{4})` + driver.separator + `([a-f0-9]{4})` + driver.separator + `([a-f0-9]{4})` + driver.separator + `([a-f0-9]{12})`
expression = `label_replace(` + expression + `,"__radar_uid","$1-$2-$3-$4-$5","id",` + strconv.Quote(prefix+uid+driver.suffix) + `)`
}
}
expression = `label_join(` + expression + `,"__radar_pair","/","` + podLabel + `","` + uidLabel + `")`
// Clear a preexisting source label before using it as the match sentinel.
expression = `label_replace(` + expression + `,"__radar_keep","","",".*")`
return `(label_replace(` + expression + `,"__radar_keep","1","__radar_pair",` + strconv.Quote(identity.pairs) + `) and on(__radar_keep) label_replace(vector(1),"__radar_keep","1","",".*"))`
}
func buildWorkloadIdentityFilter(pods []WorkloadPodIdentity, source RequestSource) (*workloadIdentityFilter, error) {
if len(pods) == 0 || len(pods) > 100 {
return nil, fmt.Errorf("workload identity requires between 1 and 100 Pods")
}
if source != RequestSourceBeyla && source != "" {
return nil, fmt.Errorf("source does not expose a supported Pod UID")
}
seen := map[string]bool{}
pairs := make([]string, 0, len(pods))
for _, pod := range pods {
if pod.Name == "" || !podIdentityUID.MatchString(pod.UID) || seen[pod.Name] {
return nil, fmt.Errorf("invalid or duplicate workload Pod identity")
}
seen[pod.Name] = true
pairs = append(pairs, regexp.QuoteMeta(pod.Name+"/"+pod.UID))
}
sort.Strings(pairs)
return &workloadIdentityFilter{pairs: "^(" + strings.Join(pairs, "|") + ")$", beyla: source == RequestSourceBeyla}, nil
}