diff --git a/pkg/schema/v1/stateful_set.go b/pkg/schema/v1/stateful_set.go index ecf2dcd5..b9879d64 100644 --- a/pkg/schema/v1/stateful_set.go +++ b/pkg/schema/v1/stateful_set.go @@ -1,6 +1,7 @@ package v1 import ( + "fmt" "github.com/icinga/icinga-go-library/types" "github.com/icinga/icinga-go-library/utils" "github.com/icinga/icinga-kubernetes/pkg/database" @@ -26,6 +27,8 @@ type StatefulSet struct { CurrentReplicas int32 UpdatedReplicas int32 AvailableReplicas int32 + IcingaState IcingaState + IcingaStateReason string Conditions []StatefulSetCondition `db:"-"` Labels []Label `db:"-"` StatefulSetLabels []StatefulSetLabel `db:"-"` @@ -83,6 +86,7 @@ func (s *StatefulSet) Obtain(k8s kmetav1.Object) { s.CurrentReplicas = statefulSet.Status.CurrentReplicas s.UpdatedReplicas = statefulSet.Status.UpdatedReplicas s.AvailableReplicas = statefulSet.Status.AvailableReplicas + s.IcingaState, s.IcingaStateReason = s.getIcingaState() for _, condition := range statefulSet.Status.Conditions { s.Conditions = append(s.Conditions, StatefulSetCondition{ @@ -109,6 +113,35 @@ func (s *StatefulSet) Obtain(k8s kmetav1.Object) { } } +func (s *StatefulSet) getIcingaState() (IcingaState, string) { + switch { + case s.AvailableReplicas == 0: + reason := fmt.Sprintf("StatefulSet %s/%s has 0 available replicas", s.Namespace, s.Name) + + return Critical, reason + case s.AvailableReplicas < s.DesiredReplicas: + reason := fmt.Sprintf("The number of available replicas is less than the number of desired replicas: %d current/%d desired", s.AvailableReplicas, s.DesiredReplicas) + + return Warning, reason + case s.ReadyReplicas < s.DesiredReplicas: + reason := fmt.Sprintf("The number of ready replicas is less than the number of desired replicas: %d ready/%d desired", s.ReadyReplicas, s.DesiredReplicas) + + return Warning, reason + case s.CurrentReplicas != s.DesiredReplicas: + reason := fmt.Sprintf("StatefulSet %s/%s has a mismatch between current number of replicas and desired number of replicas: %d current/%d desired", s.Namespace, s.Name, s.CurrentReplicas, s.DesiredReplicas) + + return Warning, reason + case s.UpdatedReplicas < s.DesiredReplicas: + reason := fmt.Sprintf("The number of updated replicas is less than the number of desired replicas: %d updated/%d desired", s.UpdatedReplicas, s.DesiredReplicas) + + return Warning, reason + default: + reason := fmt.Sprintf("StatefulSet %s/%s is functioning as expected", s.Namespace, s.Name) + + return Ok, reason + } +} + func (s *StatefulSet) Relations() []database.Relation { fk := database.WithForeignKey("stateful_set_id") diff --git a/schema/mysql/schema.sql b/schema/mysql/schema.sql index b5fdcc62..ae2d4de4 100644 --- a/schema/mysql/schema.sql +++ b/schema/mysql/schema.sql @@ -427,6 +427,8 @@ CREATE TABLE stateful_set ( current_replicas int unsigned NOT NULL, updated_replicas int unsigned NOT NULL, available_replicas int unsigned 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 (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;