Ctrl K
ComunidadGuías…

internal/resources/failing.go

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

Archivo original ↗Preguntar a KiBot
package resources

import (
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/tools/cache"

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

type watchedType struct {
	kind   string
	lister cache.GenericLister
}

func (m *Manager) failingFromCaches() map[string]int {
	watched := m.watchedTypes()
	out := map[string]int{}
	for key, entry := range watched {
		count := failingInCache(entry)
		if count == 0 {
			continue
		}
		out[key] = count
	}
	return out
}

func (m *Manager) watchedTypes() map[string]watchedType {
	out := map[string]watchedType{}
	for key, entry := range m.syncedTypes() {
		if entry.kind == "Pod" {
			continue
		}
		out[key] = entry
	}
	return out
}

func (m *Manager) syncedTypes() map[string]watchedType {
	m.mu.Lock()
	defer m.mu.Unlock()
	out := map[string]watchedType{}
	for key, st := range m.streams {
		if key.namespace != "" || !st.informer.HasSynced() {
			continue
		}
		out[gvrKey(key.gvr)] = watchedType{kind: st.kind, lister: st.lister}
	}
	return out
}

func (m *Manager) Syncing() bool {
	m.mu.Lock()
	defer m.mu.Unlock()
	for _, st := range m.streams {
		if !st.informer.HasSynced() {
			return true
		}
	}
	return false
}

func (m *Manager) Cached() []api.ResourceDescriptor {
	synced := m.syncedTypes()
	descs := m.descriptors()
	out := make([]api.ResourceDescriptor, 0, len(synced))
	for key := range synced {
		desc, ok := descs[key]
		if !ok {
			continue
		}
		out = append(out, desc)
	}
	return out
}

func gvrKey(gvr schema.GroupVersionResource) string {
	return gvr.Group + "/" + gvr.Version + "/" + gvr.Resource
}

func failingInCache(entry watchedType) int {
	listed, err := entry.lister.List(labels.Everything())
	if err != nil {
		return 0
	}
	count := 0
	for _, obj := range listed {
		u, ok := obj.(*unstructured.Unstructured)
		if !ok {
			continue
		}
		if unhealthy(u, entry.kind) {
			count++
		}
	}
	return count
}

func unhealthy(obj *unstructured.Unstructured, kind string) bool {
	switch kind {
	case "Pod":
		return false
	case "Deployment", "StatefulSet", "ReplicaSet", "ReplicationController", "DaemonSet", "Job":
		return issues.WorkloadUnhealthy(obj, kind)
	default:
		status, _ := unstr.Ready(obj)
		if status == "" {
			return false
		}
		return status != "True"
	}
}