internal/podcount/podcount.go
Rama main · réplica de lectura del repositorio original.
package podcount
import (
"context"
"errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/metadata"
)
var errRepeatedContinue = errors.New("the apiserver repeated a continuation token while counting pods")
const (
probeLimit = 1
pageSize = 500
maxPages = 20
)
var podsGVR = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}
type Result struct {
Total int
Complete bool
}
func Count(ctx context.Context, client metadata.Interface, selector string) (Result, error) {
probe, err := client.Resource(podsGVR).Namespace(metav1.NamespaceAll).List(ctx, metav1.ListOptions{
Limit: probeSize(selector),
FieldSelector: selector,
})
if err != nil {
return Result{}, err
}
if probe.GetContinue() == "" {
return Result{Total: len(probe.Items), Complete: true}, nil
}
return walk(ctx, client, selector, len(probe.Items), probe.GetContinue())
}
func probeSize(selector string) int64 {
if selector == "" {
return probeLimit
}
return pageSize
}
func walk(
ctx context.Context,
client metadata.Interface,
selector string,
counted int,
from string,
) (Result, error) {
total := counted
seen := map[string]bool{from: true}
opts := metav1.ListOptions{Limit: pageSize, FieldSelector: selector, Continue: from}
for range maxPages {
list, err := client.Resource(podsGVR).Namespace(metav1.NamespaceAll).List(ctx, opts)
if err != nil {
return Result{}, err
}
total += len(list.Items)
next := list.GetContinue()
if next == "" {
return Result{Total: total, Complete: true}, nil
}
if seen[next] {
return Result{}, errRepeatedContinue
}
seen[next] = true
opts.Continue = next
}
if total > Limit() {
total = Limit()
}
return Result{Total: total, Complete: false}, nil
}
func Limit() int {
return pageSize * maxPages
}