Checker is an optional interface next to Provider: Check returns one verdict per target and never fails as a whole. The kubernetes provider lists at most one managed Pod cluster-wide (the verb and scope GC relies on); the GCP provider fetches a single page of at most one managed instance through a new Probe seam method, since the SDK treats MaxResults as a page size and the existing AggregatedList drains every page. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
54 lines
1.6 KiB
Go
54 lines
1.6 KiB
Go
package kubernetes
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
|
|
"gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/internal/provider"
|
|
)
|
|
|
|
var _ provider.Checker = (*Provider)(nil)
|
|
|
|
// Check lists at most one managed Pod across the cluster: the same client,
|
|
// verb and scope ListByTag and orphan GC rely on, so a pass means the API
|
|
// server answers and the operator's RBAC still covers them. It does not
|
|
// prove create or delete rights.
|
|
func (p *Provider) Check(ctx context.Context) []provider.TargetStatus {
|
|
start := time.Now()
|
|
var pods corev1.PodList
|
|
err := p.client.List(ctx, &pods, client.MatchingLabels{
|
|
provider.LabelManaged: provider.LabelManagedYes,
|
|
}, client.Limit(1))
|
|
ts := provider.TargetStatus{Name: "apiserver", Address: p.apiHost, Latency: time.Since(start)}
|
|
if err != nil {
|
|
ts.Reason = checkReason(ctx, err)
|
|
ts.Message = err.Error()
|
|
return []provider.TargetStatus{ts}
|
|
}
|
|
ts.Ready = true
|
|
ts.Reason = provider.ReasonReachable
|
|
return []provider.TargetStatus{ts}
|
|
}
|
|
|
|
func checkReason(ctx context.Context, err error) string {
|
|
var status apierrors.APIStatus
|
|
switch {
|
|
case ctx.Err() != nil, errors.Is(err, context.DeadlineExceeded),
|
|
apierrors.IsTimeout(err), apierrors.IsServerTimeout(err):
|
|
return provider.ReasonTimeout
|
|
case apierrors.IsUnauthorized(err):
|
|
return provider.ReasonUnauthorized
|
|
case apierrors.IsForbidden(err):
|
|
return provider.ReasonForbidden
|
|
case errors.As(err, &status):
|
|
return provider.ReasonAPIError
|
|
default:
|
|
return provider.ReasonUnreachable
|
|
}
|
|
}
|