Files
pulse/internal/unifiedresources/status.go
T
2026-07-24 12:40:05 +01:00

389 lines
9.9 KiB
Go

package unifiedresources
import (
"strings"
"github.com/rcourtman/pulse-go-rewrite/internal/models"
)
func statusFromString(status string) ResourceStatus {
switch strings.ToLower(strings.TrimSpace(status)) {
case "online", "running", "ok":
return StatusOnline
case "offline", "down", "stopped":
return StatusOffline
case "warning", "degraded":
return StatusWarning
default:
return StatusUnknown
}
}
func statusFromGuest(status string) ResourceStatus {
switch strings.ToLower(strings.TrimSpace(status)) {
case "running", "online":
return StatusOnline
case "stopped", "offline", "paused":
return StatusOffline
case "warning", "degraded":
return StatusWarning
default:
return StatusUnknown
}
}
func statusFromStorage(storage models.Storage) ResourceStatus {
switch strings.ToLower(strings.TrimSpace(storage.Status)) {
case "online", "running", "available", "active", "ok":
return StatusOnline
case "warning", "degraded":
return StatusWarning
case "offline", "down", "unavailable", "error":
return StatusOffline
}
if !storage.Active {
return StatusOffline
}
if !storage.Enabled {
return StatusWarning
}
return StatusOnline
}
func statusFromPhysicalDisk(health string) ResourceStatus {
switch strings.ToUpper(strings.TrimSpace(health)) {
case "PASSED", "OK":
return StatusOnline
case "FAILED":
return StatusOffline
default:
return StatusUnknown
}
}
func statusFromCephHealth(health string) ResourceStatus {
switch strings.ToUpper(strings.TrimSpace(health)) {
case "HEALTH_OK", "OK":
return StatusOnline
case "HEALTH_WARN", "WARN":
return StatusWarning
case "HEALTH_ERR", "ERR":
return StatusOffline
default:
return StatusUnknown
}
}
func statusFromDockerState(state string) ResourceStatus {
switch strings.ToLower(strings.TrimSpace(state)) {
case "running":
return StatusOnline
case "created", "exited", "dead", "paused":
return StatusOffline
case "restarting":
return StatusWarning
default:
return StatusUnknown
}
}
func statusFromDockerService(service models.DockerService) ResourceStatus {
desired := service.DesiredTasks
running := service.RunningTasks
if desired <= 0 {
if running > 0 {
return StatusOnline
}
return StatusUnknown
}
if running >= desired {
return StatusOnline
}
if running == 0 {
return StatusOffline
}
return StatusWarning
}
func statusFromDockerTask(task models.DockerTask) ResourceStatus {
current := strings.ToLower(strings.TrimSpace(task.CurrentState))
desired := strings.ToLower(strings.TrimSpace(task.DesiredState))
switch {
case strings.Contains(current, "running"):
return StatusOnline
case strings.Contains(current, "failed"), strings.Contains(current, "rejected"), strings.TrimSpace(task.Error) != "":
return StatusOffline
case strings.Contains(current, "pending"), strings.Contains(current, "starting"), strings.Contains(current, "preparing"), strings.Contains(current, "accepted"):
return StatusWarning
case desired == "shutdown" || strings.Contains(current, "complete"):
return StatusOffline
default:
return StatusUnknown
}
}
func statusFromDockerSwarmNode(node models.DockerNode) ResourceStatus {
state := strings.ToLower(strings.TrimSpace(node.State))
reachability := strings.ToLower(strings.TrimSpace(node.ManagerReachability))
availability := strings.ToLower(strings.TrimSpace(node.Availability))
switch {
case state == "ready" || state == "active":
if reachability == "unreachable" || availability == "pause" || availability == "drain" {
return StatusWarning
}
return StatusOnline
case state == "down" || state == "disconnected":
return StatusOffline
case state == "unknown":
return StatusUnknown
case reachability == "unreachable":
return StatusWarning
default:
return StatusUnknown
}
}
func statusFromPBSInstance(instance models.PBSInstance) ResourceStatus {
primary := strings.ToLower(strings.TrimSpace(instance.Status))
health := strings.ToLower(strings.TrimSpace(instance.ConnectionHealth))
switch {
case primary == "online" || primary == "running" || primary == "ok" || primary == "healthy":
return StatusOnline
case primary == "warning" || primary == "degraded":
return StatusWarning
case primary == "offline" || primary == "down" || primary == "stopped" || primary == "error":
return StatusOffline
}
switch health {
case "online", "running", "ok", "healthy", "connected":
return StatusOnline
case "warning", "degraded":
return StatusWarning
case "offline", "down", "stopped", "error", "disconnected":
return StatusOffline
default:
return StatusUnknown
}
}
func statusFromPMGInstance(instance models.PMGInstance) ResourceStatus {
primary := strings.ToLower(strings.TrimSpace(instance.Status))
health := strings.ToLower(strings.TrimSpace(instance.ConnectionHealth))
switch {
case primary == "online" || primary == "running" || primary == "ok" || primary == "healthy":
return StatusOnline
case primary == "warning" || primary == "degraded":
return StatusWarning
case primary == "offline" || primary == "down" || primary == "stopped" || primary == "error":
return StatusOffline
}
switch health {
case "online", "running", "ok", "healthy", "connected":
return StatusOnline
case "warning", "degraded":
return StatusWarning
case "offline", "down", "stopped", "error", "disconnected":
return StatusOffline
default:
return StatusUnknown
}
}
func statusFromKubernetesCluster(cluster models.KubernetesCluster) ResourceStatus {
switch strings.ToLower(strings.TrimSpace(cluster.Status)) {
case "online", "running", "ready", "healthy":
return StatusOnline
case "warning", "degraded":
return StatusWarning
case "offline", "disconnected", "error":
return StatusOffline
}
if len(cluster.Nodes) == 0 {
return StatusUnknown
}
ready := 0
for _, node := range cluster.Nodes {
if node.Ready {
ready++
}
}
switch {
case ready == len(cluster.Nodes):
return StatusOnline
case ready == 0:
return StatusOffline
default:
return StatusWarning
}
}
func statusFromKubernetesNode(node models.KubernetesNode) ResourceStatus {
if !node.Ready {
return StatusOffline
}
if node.Unschedulable {
return StatusWarning
}
return StatusOnline
}
func statusFromKubernetesPod(pod models.KubernetesPod) ResourceStatus {
phase := strings.ToLower(strings.TrimSpace(pod.Phase))
switch phase {
case "failed", "succeeded":
return StatusOffline
case "running":
if len(pod.Containers) == 0 {
return StatusOnline
}
for _, container := range pod.Containers {
if !container.Ready {
return StatusWarning
}
state := strings.ToLower(strings.TrimSpace(container.State))
if state != "" && state != "running" {
return StatusWarning
}
}
return StatusOnline
case "pending", "unknown":
return StatusWarning
default:
return StatusUnknown
}
}
func statusFromKubernetesDeployment(deployment models.KubernetesDeployment) ResourceStatus {
desired := deployment.DesiredReplicas
available := deployment.AvailableReplicas
if desired <= 0 {
if available > 0 {
return StatusOnline
}
return StatusUnknown
}
if available >= desired {
return StatusOnline
}
if available == 0 {
return StatusOffline
}
return StatusWarning
}
func statusFromKubernetesReplicaSet(replicaSet models.KubernetesReplicaSet) ResourceStatus {
return statusFromReplicaAvailability(replicaSet.DesiredReplicas, replicaSet.ReadyReplicas)
}
func statusFromKubernetesStatefulSet(statefulSet models.KubernetesStatefulSet) ResourceStatus {
return statusFromReplicaAvailability(statefulSet.DesiredReplicas, statefulSet.ReadyReplicas)
}
func statusFromKubernetesDaemonSet(daemonSet models.KubernetesDaemonSet) ResourceStatus {
desired := daemonSet.DesiredNumberScheduled
ready := daemonSet.NumberReady
if daemonSet.NumberMisscheduled > 0 || daemonSet.NumberUnavailable > 0 {
if ready > 0 {
return StatusWarning
}
return StatusOffline
}
return statusFromReplicaAvailability(desired, ready)
}
func statusFromKubernetesJob(job models.KubernetesJob) ResourceStatus {
if job.Failed > 0 {
return StatusOffline
}
if job.Succeeded > 0 {
return StatusOnline
}
if job.Active > 0 {
return StatusWarning
}
return StatusUnknown
}
func statusFromKubernetesCronJob(cronJob models.KubernetesCronJob) ResourceStatus {
if cronJob.Suspend {
return StatusWarning
}
return StatusOnline
}
func statusFromKubernetesEndpointSlice(slice models.KubernetesEndpointSlice) ResourceStatus {
if slice.EndpointCount <= 0 {
return StatusUnknown
}
if slice.ReadyEndpointCount <= 0 {
return StatusWarning
}
return StatusOnline
}
func statusFromKubernetesPhase(phase string) ResourceStatus {
switch strings.ToLower(strings.TrimSpace(phase)) {
case "active", "bound", "available":
return StatusOnline
case "pending", "released":
return StatusWarning
case "failed", "lost", "terminating":
return StatusOffline
default:
return StatusUnknown
}
}
func statusFromKubernetesEvent(event models.KubernetesEvent) ResourceStatus {
if strings.EqualFold(strings.TrimSpace(event.EventType), "warning") {
return StatusWarning
}
return StatusOnline
}
func statusFromKubernetesPodDisruptionBudget(budget models.KubernetesPodDisruptionBudget) ResourceStatus {
if budget.ExpectedPods <= 0 {
return StatusUnknown
}
if budget.CurrentHealthy >= budget.DesiredHealthy {
return StatusOnline
}
if budget.CurrentHealthy <= 0 {
return StatusOffline
}
return StatusWarning
}
func statusFromKubernetesHorizontalPodAutoscaler(autoscaler models.KubernetesHorizontalPodAutoscaler) ResourceStatus {
if autoscaler.MaxReplicas > 0 && autoscaler.DesiredReplicas > autoscaler.MaxReplicas {
return StatusWarning
}
if autoscaler.DesiredReplicas > 0 && autoscaler.CurrentReplicas <= 0 {
return StatusOffline
}
return StatusOnline
}
func statusFromReplicaAvailability(desired, ready int32) ResourceStatus {
if desired <= 0 {
if ready > 0 {
return StatusOnline
}
return StatusUnknown
}
if ready >= desired {
return StatusOnline
}
if ready == 0 {
return StatusOffline
}
return StatusWarning
}