From 0f261866249599b82031ab8167bc5cae7271eda4 Mon Sep 17 00:00:00 2001 From: Jonada Hoxha Date: Tue, 29 Oct 2024 08:14:30 +0100 Subject: [PATCH] Sync pods that belong to a service --- cmd/icinga-kubernetes/main.go | 3 +- pkg/schema/v1/service.go | 53 +++++++++++++++++++++++++++++++++-- schema/mysql/schema.sql | 6 ++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/cmd/icinga-kubernetes/main.go b/cmd/icinga-kubernetes/main.go index 5a0e410..307a39a 100644 --- a/cmd/icinga-kubernetes/main.go +++ b/cmd/icinga-kubernetes/main.go @@ -413,7 +413,8 @@ func main() { }) g.Go(func() error { - s := syncv1.NewSync(db, factory.Core().V1().Services().Informer(), log.WithName("services"), schemav1.NewService) + f := schemav1.NewServiceFactory(clientset) + s := syncv1.NewSync(db, factory.Core().V1().Services().Informer(), log.WithName("services"), f.NewService) return s.Run(ctx) }) diff --git a/pkg/schema/v1/service.go b/pkg/schema/v1/service.go index 2b68191..0f31b46 100644 --- a/pkg/schema/v1/service.go +++ b/pkg/schema/v1/service.go @@ -1,6 +1,7 @@ package v1 import ( + "context" "database/sql" "github.com/icinga/icinga-go-library/strcase" "github.com/icinga/icinga-go-library/types" @@ -10,9 +11,14 @@ import ( kruntime "k8s.io/apimachinery/pkg/runtime" kserializer "k8s.io/apimachinery/pkg/runtime/serializer" kjson "k8s.io/apimachinery/pkg/runtime/serializer/json" + "k8s.io/client-go/kubernetes" "strings" ) +type ServiceFactory struct { + clientset *kubernetes.Clientset +} + type Service struct { Meta ClusterIP string @@ -40,6 +46,8 @@ type Service struct { Annotations []Annotation `db:"-"` ServiceAnnotations []ServiceAnnotation `db:"-"` ResourceAnnotations []ResourceAnnotation `db:"-"` + ServicePods []ServicePod `db:"-"` + factory *ServiceFactory } type ServiceSelector struct { @@ -77,8 +85,19 @@ type ServiceAnnotation struct { AnnotationUuid types.UUID } -func NewService() Resource { - return &Service{} +type ServicePod struct { + ServiceUuid types.UUID + PodUuid types.UUID +} + +func NewServiceFactory(clientset *kubernetes.Clientset) *ServiceFactory { + return &ServiceFactory{ + clientset: clientset, + } +} + +func (f *ServiceFactory) NewService() Resource { + return &Service{factory: f} } func (s *Service) Obtain(k8s kmetav1.Object) { @@ -217,6 +236,29 @@ func (s *Service) Obtain(k8s kmetav1.Object) { } s.InternalTrafficPolicy = internalTrafficPolicy + if len(service.Spec.Selector) > 0 { + selector := kmetav1.LabelSelector{ + MatchLabels: service.Spec.Selector, + } + labelSelector, err := kmetav1.LabelSelectorAsSelector(&selector) + if err != nil { + return + } + + pods, err := s.queryMatchingPods(labelSelector.String()) + if err != nil { + return + } + + for _, pod := range pods.Items { + podUuid := EnsureUUID(pod.ObjectMeta.UID) + s.ServicePods = append(s.ServicePods, ServicePod{ + ServiceUuid: s.Uuid, + PodUuid: podUuid, + }) + } + } + scheme := kruntime.NewScheme() _ = kcorev1.AddToScheme(scheme) codec := kserializer.NewCodecFactory(scheme).EncoderForVersion(kjson.NewYAMLSerializer(kjson.DefaultMetaFactory, scheme, scheme), kcorev1.SchemeGroupVersion) @@ -224,6 +266,12 @@ func (s *Service) Obtain(k8s kmetav1.Object) { s.Yaml = string(output) } +func (s *Service) queryMatchingPods(labelSelector string) (*kcorev1.PodList, error) { + return s.factory.clientset.CoreV1().Pods("").List(context.TODO(), kmetav1.ListOptions{ + LabelSelector: labelSelector, + }) +} + func (s *Service) Relations() []database.Relation { fk := database.WithForeignKey("service_uuid") @@ -238,5 +286,6 @@ func (s *Service) Relations() []database.Relation { database.HasMany(s.ServiceAnnotations, fk), database.HasMany(s.Annotations, database.WithoutCascadeDelete()), database.HasMany(s.ResourceAnnotations, fk), + database.HasMany(s.ServicePods, fk), } } diff --git a/schema/mysql/schema.sql b/schema/mysql/schema.sql index 7116809..5d1014b 100644 --- a/schema/mysql/schema.sql +++ b/schema/mysql/schema.sql @@ -897,6 +897,12 @@ CREATE TABLE service_label ( PRIMARY KEY (service_uuid, label_uuid) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; +CREATE TABLE service_pod ( + service_uuid binary(16) NOT NULL, + pod_uuid binary(16) NOT NULL, + PRIMARY KEY (service_uuid, pod_uuid) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + CREATE TABLE service_port ( service_uuid binary(16) NOT NULL, name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,