Ctrl K
ComunidadGuías…

internal/issues/conditions.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package issues

import (
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

	"github.com/sophotechlabs/spinoza/internal/unstr"
)

const detectorCondition = "condition"

var healthyWhenTrue = []string{"Ready", "Available", "Healthy", "Synced"}

var brokenWhenTrue = []string{"Stalled", "Degraded", "Failed"}

var ownedKinds = map[kindRef]bool{
	{group: "", kind: kindPod}:                      true,
	{group: "", kind: kindReplicationController}:    true,
	{group: appsGroup, kind: kindDeployment}:        true,
	{group: appsGroup, kind: kindReplicaSet}:        true,
	{group: appsGroup, kind: kindStatefulSet}:       true,
	{group: appsGroup, kind: kindDaemonSet}:         true,
	{group: batchGroup, kind: kindJob}:              true,
	{group: batchGroup, kind: kindCronJob}:          true,
	{group: autoscalingGroup, kind: autoscalerKind}: true,
	{group: argoGroup, kind: applicationsKind}:      true,
}

func conditionFindings(snap *snapshot) []finding {
	out := []finding{}
	for _, items := range snap.byKind {
		for _, item := range items {
			found, ok := conditionFinding(item)
			if !ok {
				continue
			}
			out = append(out, found)
		}
	}
	return out
}

func conditionFinding(item object) (finding, bool) {
	if ownedKinds[kindRef{group: item.desc.Group, kind: item.desc.Kind}] || isFluxGroup(item.desc.Group) {
		return finding{}, false
	}
	if item.obj.GetDeletionTimestamp() != nil {
		return finding{}, false
	}
	entry, ok := badCondition(item.obj)
	if !ok {
		return finding{}, false
	}
	name := unstr.At(entry, "type")
	return finding{
		detector:  detectorCondition,
		severity:  severityDegraded,
		title:     reasonOr(entry, name+"="+unstr.At(entry, "status")),
		detail:    messageOr(entry, item.desc.Kind+" reports "+name+"="+unstr.At(entry, "status")),
		action:    "open the object and read its conditions",
		uncertain: unstr.At(entry, "status") == "Unknown",
		kind:      item.desc.Kind,
		subject:   item,
		since:     conditionSince(item.obj, name),
	}, true
}

func badCondition(obj *unstructured.Unstructured) (map[string]any, bool) {
	for _, name := range healthyWhenTrue {
		entry, ok := conditionOf(obj, name)
		if !ok {
			continue
		}
		if unstr.At(entry, "status") == conditionTrue {
			return nil, false
		}
		return entry, true
	}
	for _, name := range brokenWhenTrue {
		entry, ok := conditionOf(obj, name)
		if !ok {
			continue
		}
		if unstr.At(entry, "status") != conditionTrue {
			continue
		}
		return entry, true
	}
	return nil, false
}