Skip to content

Commit

Permalink
Expose more health info as well as counts in Apply results
Browse files Browse the repository at this point in the history
  • Loading branch information
barney-s committed Jun 6, 2024
1 parent b758057 commit 5f0e9dd
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 20 deletions.
5 changes: 3 additions & 2 deletions applylib/applyset/applyset.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,9 @@ func (a *ApplySet) ApplyOnce(ctx context.Context) (*ApplyResults, error) {
visitedUids.Insert(lastApplied.GetUID())
tracker.lastApplied = lastApplied
results.applySuccess(gvk, nn)
tracker.isHealthy = isHealthy(lastApplied)
results.reportHealth(gvk, nn, tracker.isHealthy)
message := ""
tracker.isHealthy, message = isHealthy(lastApplied)
results.reportHealth(gvk, nn, tracker.isHealthy, message)
}

// We want to be more cautions on pruning and only do it if all manifests are applied.
Expand Down
50 changes: 32 additions & 18 deletions applylib/applyset/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,70 +22,84 @@ import (
"k8s.io/klog/v2"
)

type ObjectStatus struct {
GVK schema.GroupVersionKind
NameNamespace types.NamespacedName
IsHealthy bool
Message string
}

// ApplyResults contains the results of an Apply operation.
type ApplyResults struct {
total int
applySuccessCount int
applyFailCount int
pruneSuccessCount int
pruneFailCount int
healthyCount int
unhealthyCount int
Total int
ApplySuccessCount int
ApplyFailCount int
PruneSuccessCount int
PruneFailCount int
HealthyCount int
UnhealthyCount int
Objects []ObjectStatus
}

// AllApplied is true if the desired state has been successfully applied for all objects.
// Note: you likely also want to check AllHealthy, if you want to be sure the objects are "ready".
func (r *ApplyResults) AllApplied() bool {
r.checkInvariants()

return r.applyFailCount == 0 && r.pruneFailCount == 0
return r.ApplyFailCount == 0 && r.PruneFailCount == 0
}

// AllHealthy is true if all the objects have been applied and have converged to a "ready" state.
// Note that this is only meaningful if AllApplied is true.
func (r *ApplyResults) AllHealthy() bool {
r.checkInvariants()

return r.unhealthyCount == 0
return r.UnhealthyCount == 0
}

// checkInvariants is an internal function that warns if the object doesn't match the expected invariants.
func (r *ApplyResults) checkInvariants() {
if r.total != (r.applySuccessCount + r.applyFailCount) {
if r.Total != (r.ApplySuccessCount + r.ApplyFailCount) {
klog.Warningf("consistency error (apply counts): %#v", r)
} else if r.total != (r.healthyCount + r.unhealthyCount) {
} else if r.Total != (r.HealthyCount + r.UnhealthyCount) {
// This "invariant" only holds when all objects could be applied
klog.Warningf("consistency error (healthy counts): %#v", r)
}
}

// applyError records that the apply of an object failed with an error.
func (r *ApplyResults) applyError(gvk schema.GroupVersionKind, nn types.NamespacedName, err error) {
r.applyFailCount++
r.ApplyFailCount++
klog.Warningf("error from apply on %s %s: %v", gvk, nn, err)
}

// applySuccess records that an object was applied and this succeeded.
func (r *ApplyResults) applySuccess(gvk schema.GroupVersionKind, nn types.NamespacedName) {
r.applySuccessCount++
r.ApplySuccessCount++
}

// pruneError records that the prune of an object failed with an error.
func (r *ApplyResults) pruneError(gvk schema.GroupVersionKind, nn types.NamespacedName, err error) {
r.pruneFailCount++
r.PruneFailCount++
klog.Warningf("error from pruning on %s %s: %v", gvk, nn, err)
}

// pruneSuccess records that an object was pruned and this succeeded.
func (r *ApplyResults) pruneSuccess(gvk schema.GroupVersionKind, nn types.NamespacedName) {
r.pruneSuccessCount++
r.PruneSuccessCount++
}

// reportHealth records the health of an object.
func (r *ApplyResults) reportHealth(gvk schema.GroupVersionKind, nn types.NamespacedName, isHealthy bool) {
func (r *ApplyResults) reportHealth(gvk schema.GroupVersionKind, nn types.NamespacedName, isHealthy bool, message string) {
r.Objects = append(r.Objects, ObjectStatus{
GVK: gvk,
NameNamespace: nn,
IsHealthy: isHealthy,
Message: message,
})
if isHealthy {
r.healthyCount++
r.HealthyCount++
} else {
r.unhealthyCount++
r.UnhealthyCount++
}
}

0 comments on commit 5f0e9dd

Please sign in to comment.