From 9eb83530ac96d1dfce233aab2ab9b6bca8030f5b Mon Sep 17 00:00:00 2001 From: Jonada Hoxha Date: Thu, 14 Sep 2023 11:46:54 +0200 Subject: [PATCH] Sync ingresses --- cmd/icinga-kubernetes/main.go | 5 + pkg/schema/v1/ingress.go | 166 ++++++++++++++++++++++++++++++++++ schema/mysql/schema.sql | 49 +++++++++- 3 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 pkg/schema/v1/ingress.go diff --git a/cmd/icinga-kubernetes/main.go b/cmd/icinga-kubernetes/main.go index 43f794de..c17ef217 100644 --- a/cmd/icinga-kubernetes/main.go +++ b/cmd/icinga-kubernetes/main.go @@ -206,6 +206,11 @@ func main() { return s.Run(ctx) }) + g.Go(func() error { + s := syncv1.NewSync(db, factory.Networking().V1().Ingresses().Informer(), log.WithName("ingresses"), schemav1.NewIngress) + + return s.Run(ctx) + }) if err := g.Wait(); err != nil { klog.Fatal(err) } diff --git a/pkg/schema/v1/ingress.go b/pkg/schema/v1/ingress.go new file mode 100644 index 00000000..d32b3e15 --- /dev/null +++ b/pkg/schema/v1/ingress.go @@ -0,0 +1,166 @@ +package v1 + +import ( + "database/sql" + "github.com/icinga/icinga-kubernetes/pkg/database" + "github.com/icinga/icinga-kubernetes/pkg/types" + networkingv1 "k8s.io/api/networking/v1" + kmetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type Ingress struct { + Meta + Id types.Binary + IngressTls []IngressTls `db:"-"` + IngressBackendService []IngressBackendService `db:"-"` + IngressBackendResource []IngressBackendResource `db:"-"` + IngressRule []IngressRule `db:"-"` +} + +type IngressTls struct { + IngressId types.Binary + TlsHost string + TlsSecret string +} + +type IngressBackendService struct { + ServiceId types.Binary + IngressId types.Binary + IngressRuleId types.Binary + ServiceName string + ServicePortName string + ServicePortNumber int32 +} + +type IngressBackendResource struct { + ResourceId types.Binary + IngressId types.Binary + IngressRuleId types.Binary + ApiGroup sql.NullString + Kind string + Name string +} + +type IngressRule struct { + Id types.Binary + BackendId types.Binary + IngressId types.Binary + Host string + Path string + PathType sql.NullString +} + +func NewIngress() Resource { + return &Ingress{} +} + +func (i *Ingress) Obtain(k8s kmetav1.Object) { + i.ObtainMeta(k8s) + + ingress := k8s.(*networkingv1.Ingress) + + i.Id = types.Checksum(i.Namespace + "/" + i.Name) + for _, tls := range ingress.Spec.TLS { + for _, host := range tls.Hosts { + i.IngressTls = append(i.IngressTls, IngressTls{ + IngressId: i.Id, + TlsHost: host, + TlsSecret: tls.SecretName, + }) + } + } + + if ingress.Spec.DefaultBackend != nil { + if ingress.Spec.DefaultBackend.Service != nil { + serviceId := types.Checksum(i.Namespace + ingress.Spec.DefaultBackend.Service.Name + ingress.Spec.DefaultBackend.Service.Port.Name) + i.IngressBackendService = append(i.IngressBackendService, IngressBackendService{ + ServiceId: serviceId, + IngressId: i.Id, + ServiceName: ingress.Spec.DefaultBackend.Service.Name, + ServicePortName: ingress.Spec.DefaultBackend.Service.Port.Name, + ServicePortNumber: ingress.Spec.DefaultBackend.Service.Port.Number, + }) + } + if ingress.Spec.DefaultBackend.Resource != nil { + resourceId := types.Checksum(i.Namespace + ingress.Spec.DefaultBackend.Resource.Kind + ingress.Spec.DefaultBackend.Resource.Name) + var apiGroup sql.NullString + if ingress.Spec.DefaultBackend.Resource.APIGroup != nil { + apiGroup.String = *ingress.Spec.DefaultBackend.Resource.APIGroup + apiGroup.Valid = true + i.IngressBackendResource = append(i.IngressBackendResource, IngressBackendResource{ + ResourceId: resourceId, + IngressId: i.Id, + ApiGroup: apiGroup, + Kind: ingress.Spec.DefaultBackend.Resource.Kind, + Name: ingress.Spec.DefaultBackend.Resource.Name, + }) + } + } + } + + for _, rules := range ingress.Spec.Rules { + for _, ruleValue := range rules.IngressRuleValue.HTTP.Paths { + var pathType sql.NullString + if ruleValue.PathType != nil { + pathType.String = string(*ruleValue.PathType) + pathType.Valid = true + } + if ruleValue.Backend.Service != nil { + ingressRuleId := types.Checksum(string(i.Id) + rules.Host + ruleValue.Path + ruleValue.Backend.Service.Name) + serviceId := types.Checksum(string(ingressRuleId) + i.Namespace + ruleValue.Backend.Service.Name) + i.IngressBackendService = append(i.IngressBackendService, IngressBackendService{ + ServiceId: serviceId, + IngressId: i.Id, + IngressRuleId: ingressRuleId, + ServiceName: ruleValue.Backend.Service.Name, + ServicePortName: ruleValue.Backend.Service.Port.Name, + ServicePortNumber: ruleValue.Backend.Service.Port.Number, + }) + i.IngressRule = append(i.IngressRule, IngressRule{ + Id: ingressRuleId, + BackendId: serviceId, + IngressId: i.Id, + Host: rules.Host, + Path: ruleValue.Path, + PathType: pathType, + }) + } else if ruleValue.Backend.Resource != nil { + ingressRuleId := types.Checksum(string(i.Id) + rules.Host + ruleValue.Path + ruleValue.Backend.Resource.Name) + resourceId := types.Checksum(string(ingressRuleId) + i.Namespace + ruleValue.Backend.Resource.Name) + var apiGroup sql.NullString + if ruleValue.Backend.Resource.APIGroup != nil { + apiGroup.String = *ruleValue.Backend.Resource.APIGroup + apiGroup.Valid = true + } + i.IngressBackendResource = append(i.IngressBackendResource, IngressBackendResource{ + ResourceId: resourceId, + IngressId: i.Id, + IngressRuleId: ingressRuleId, + ApiGroup: apiGroup, + Kind: ruleValue.Backend.Resource.Kind, + Name: ruleValue.Backend.Resource.Name, + }) + i.IngressRule = append(i.IngressRule, IngressRule{ + Id: ingressRuleId, + IngressId: i.Id, + BackendId: resourceId, + Host: rules.Host, + Path: ruleValue.Path, + PathType: pathType, + }) + } + } + + } +} + +func (i *Ingress) Relations() []database.Relation { + fk := database.WithForeignKey("ingress_id") + + return []database.Relation{ + database.HasMany(i.IngressTls, fk), + database.HasMany(i.IngressBackendService, fk), + database.HasMany(i.IngressBackendResource, fk), + database.HasMany(i.IngressRule, fk), + } +} diff --git a/schema/mysql/schema.sql b/schema/mysql/schema.sql index fff6676c..9be19128 100644 --- a/schema/mysql/schema.sql +++ b/schema/mysql/schema.sql @@ -92,7 +92,7 @@ CREATE TABLE pod_condition ( CREATE TABLE pod_owner ( pod_id binary(20) NOT NULL, - kind enum('daemon_set', 'node', 'replica_set', 'stateful_set') COLLATE utf8mb4_unicode_ci NOT NULL, + kind enum('daemon_set', 'node', 'replica_set', 'stateful_set', 'job') COLLATE utf8mb4_unicode_ci NOT NULL, name varchar(253) COLLATE utf8mb4_unicode_ci NOT NULL, uid varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, controller enum('n', 'y') COLLATE utf8mb4_unicode_ci NOT NULL, @@ -194,6 +194,53 @@ CREATE TABLE service ( PRIMARY KEY (namespace, name) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; +CREATE TABLE ingress ( + id binary(20) NOT NULL, + namespace varchar(63) COLLATE utf8mb4_unicode_ci NOT NULL, + name varchar(63) COLLATE utf8mb4_unicode_ci NOT NULL, + uid varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + resource_version varchar(255) NOT NULL, + created bigint unsigned NOT NULL, + PRIMARY KEY(id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + +CREATE TABLE ingress_tls ( + ingress_id binary(20) NOT NULL, + tls_host varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + tls_secret varchar(255) COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, + PRIMARY KEY(ingress_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + +CREATE TABLE ingress_backend_service ( + service_id binary(20) NOT NULL, + ingress_id binary(20) NOT NULL, + ingress_rule_id binary(20) NULL DEFAULT NULL, + service_name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + service_port_name varchar(255) COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, + service_port_number int unsigned NULL DEFAULT NULL, + PRIMARY KEY(service_id, ingress_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + +CREATE TABLE ingress_backend_resource ( + resource_id binary(20) NOT NULL, + ingress_id binary(20) NOT NULL, + ingress_rule_id binary(20) NULL DEFAULT NULL, + api_group varchar(255) COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, + kind varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY(resource_id, ingress_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + +CREATE TABLE ingress_rule ( + id binary(20) NOT NULL, + backend_id binary(20) NOT NULL, + ingress_id binary(20) NOT NULL, + host varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + path varchar(255) COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, + path_type varchar(255) COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, + PRIMARY KEY(id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + CREATE TABLE replica_set ( id binary(20) NOT NULL, namespace varchar(63) COLLATE utf8mb4_unicode_ci NOT NULL,