From f7f833e3703df29192ea09060b9d4203aa696326 Mon Sep 17 00:00:00 2001 From: Jonada Hoxha Date: Tue, 28 May 2024 11:01:12 +0200 Subject: [PATCH] Add Icinga states to node --- pkg/schema/v1/node.go | 46 +++++++++++++++++++++++++++++++++++++++++ schema/mysql/schema.sql | 2 ++ 2 files changed, 48 insertions(+) diff --git a/pkg/schema/v1/node.go b/pkg/schema/v1/node.go index c6392d0d..eaf9912e 100644 --- a/pkg/schema/v1/node.go +++ b/pkg/schema/v1/node.go @@ -1,6 +1,7 @@ package v1 import ( + "fmt" "github.com/icinga/icinga-go-library/types" "github.com/icinga/icinga-kubernetes/pkg/database" "github.com/pkg/errors" @@ -37,6 +38,8 @@ type Node struct { ContainerRuntimeVersion string KubeletVersion string KubeProxyVersion string + IcingaState IcingaState + IcingaStateReason string Conditions []NodeCondition `db:"-"` Volumes []NodeVolume `db:"-"` Labels []Label `db:"-"` @@ -122,6 +125,8 @@ func (n *Node) Obtain(k8s kmetav1.Object) { } n.Roles = strings.Join(roles, ", ") + n.IcingaState, n.IcingaStateReason = n.getIcingaState(node) + for _, condition := range node.Status.Conditions { n.Conditions = append(n.Conditions, NodeCondition{ NodeUuid: n.Uuid, @@ -185,6 +190,47 @@ func (n *Node) Obtain(k8s kmetav1.Object) { } } +func (n *Node) getIcingaState(node *kcorev1.Node) (IcingaState, string) { + if node.Status.Phase == kcorev1.NodePending { + return Pending, fmt.Sprintf("Node %s is pending", node.Name) + } + + if node.Status.Phase == kcorev1.NodeTerminated { + return Ok, fmt.Sprintf("Node %s is terminated", node.Name) + } + + var state IcingaState + + if node.Status.Phase == kcorev1.NodeRunning { + var reason []string + + for _, condition := range n.Conditions { + if condition.Status == string(kcorev1.ConditionTrue) { + switch condition.Type { + case string(kcorev1.NodeDiskPressure): + state = Critical + reason = append(reason, fmt.Sprintf("Node %s is running out of disk space", n.Name)) + case string(kcorev1.NodeMemoryPressure): + state = Critical + reason = append(reason, fmt.Sprintf("Node %s is running out of available memory", n.Name)) + case string(kcorev1.NodePIDPressure): + state = Critical + reason = append(reason, fmt.Sprintf("Node %s is running out of process IDs", n.Name)) + case string(kcorev1.NodeNetworkUnavailable): + state = Critical + reason = append(reason, fmt.Sprintf("Node %s network is not correctly configured", n.Name)) + } + } + } + + if state != Ok { + return state, strings.Join(reason, ". ") + } + } + + return Ok, fmt.Sprintf("Node %s is healthy", n.Name) +} + func (n *Node) Relations() []database.Relation { fk := database.WithForeignKey("node_uuid") diff --git a/schema/mysql/schema.sql b/schema/mysql/schema.sql index 5d4a8fa0..6ca7d77a 100644 --- a/schema/mysql/schema.sql +++ b/schema/mysql/schema.sql @@ -47,6 +47,8 @@ CREATE TABLE node ( container_runtime_version varchar(255) NOT NULL, kubelet_version varchar(255) NOT NULL, kube_proxy_version varchar(255) NOT NULL, + icinga_state enum('ok', 'warning', 'critical', 'unknown') COLLATE utf8mb4_unicode_ci NOT NULL, + icinga_state_reason text NOT NULL, created bigint unsigned NOT NULL, PRIMARY KEY (uuid) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;