Add the health engine: through-proxy probes, thresholds, channel-fed transitions
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
@@ -11,8 +12,9 @@ import (
|
||||
crawlv1alpha1 "gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/api/v1alpha1"
|
||||
)
|
||||
|
||||
// Reasons used on the Provisioned condition. The Healthy condition is owned
|
||||
// by the health engine (internal/health) and only represented here.
|
||||
// Reasons used on the Provisioned condition, plus the two the reconciler
|
||||
// writes on the Healthy condition when representing the health engine's
|
||||
// verdict (the engine owns the state; only the reconciler writes status).
|
||||
const (
|
||||
ReasonProvisioning = "Provisioning"
|
||||
ReasonCreated = "Created"
|
||||
@@ -23,6 +25,9 @@ const (
|
||||
ReasonCloudInitError = "CloudInitError"
|
||||
ReasonExternalEndpoint = "ExternalEndpoint"
|
||||
ReasonDeleting = "Deleting"
|
||||
|
||||
ReasonProbeSucceeded = "ProbeSucceeded"
|
||||
ReasonProbeFailed = "ProbeFailed"
|
||||
)
|
||||
|
||||
// setProvisioned stages the Provisioned condition on p. Nothing is written
|
||||
@@ -39,6 +44,39 @@ func setProvisioned(p *crawlv1alpha1.Proxy, status metav1.ConditionStatus, reaso
|
||||
})
|
||||
}
|
||||
|
||||
// applyHealth stages the Healthy condition and the latency fields from the
|
||||
// health engine's current snapshot. Called only from states where the proxy
|
||||
// is reachable (Running, External); everywhere else the condition is either
|
||||
// left as-is or removed by the create branch.
|
||||
func (r *ProxyReconciler) applyHealth(p *crawlv1alpha1.Proxy) {
|
||||
if r.Health == nil {
|
||||
return
|
||||
}
|
||||
snap, ok := r.Health.Snapshot(client.ObjectKeyFromObject(p))
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
cond := metav1.Condition{
|
||||
Type: crawlv1alpha1.ConditionHealthy,
|
||||
ObservedGeneration: p.Generation,
|
||||
}
|
||||
if snap.Healthy {
|
||||
cond.Status = metav1.ConditionTrue
|
||||
cond.Reason = ReasonProbeSucceeded
|
||||
cond.Message = "probe succeeded through the proxy"
|
||||
} else {
|
||||
cond.Status = metav1.ConditionFalse
|
||||
cond.Reason = ReasonProbeFailed
|
||||
cond.Message = fmt.Sprintf("%d consecutive probe failures; last: %s",
|
||||
snap.ConsecutiveFailures, snap.LastError)
|
||||
}
|
||||
apimeta.SetStatusCondition(&p.Status.Conditions, cond)
|
||||
p.Status.LatencyMillis = snap.Latency.Milliseconds()
|
||||
if !snap.LastProbe.IsZero() {
|
||||
p.Status.LastHealthCheckTime = &metav1.Time{Time: snap.LastProbe}
|
||||
}
|
||||
}
|
||||
|
||||
// computePhase derives status.phase from deletionTimestamp and the
|
||||
// Provisioned/Healthy conditions. Pure, so the truth table is unit-testable.
|
||||
func computePhase(p *crawlv1alpha1.Proxy) crawlv1alpha1.ProxyPhase {
|
||||
|
||||
Reference in New Issue
Block a user