From 5719d4647c37743ae8cf6adf0c9f196dbeafe775 Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Tue, 18 Mar 2025 17:29:41 -0300 Subject: [PATCH 01/15] add HPAConfigSpec --- kubernetes/common.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kubernetes/common.py b/kubernetes/common.py index d218c0e..b2e7811 100644 --- a/kubernetes/common.py +++ b/kubernetes/common.py @@ -358,6 +358,10 @@ class VPAConfigSpec(kgenlib.BaseModel): update_mode: str = "Auto" resource_policy: Dict[str, List[Dict]] = {} +class HPAConfigSpec(kgenlib.BaseModel): + min_replicas: Optional[int] = None + max_replicas: Optional[int] = None + metrics: List[Dict[str, Any]] = [] class ServiceMonitororConfigSpec(kgenlib.BaseModel): endpoints: list = [] @@ -389,7 +393,7 @@ class WorkloadConfigSpec(KubernetesResourceSpec, ContainerSpec): grace_period: int = 30 host_network: Optional[bool] = None host_pid: Optional[bool] = None - hpa: dict = {} + hpa: Optional[HPAConfigSpec] = None image_pull_secrets: list = [] init_containers: Optional[Dict[str, Union[InitContainerSpec, None]]] = {} istio_policy: dict = {} From 49435daf659ce20cb3ee24e1a302cdd1177daa9c Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Wed, 26 Mar 2025 16:29:11 -0300 Subject: [PATCH 02/15] add string_data to find_key_in_config --- kubernetes/workloads.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/workloads.py b/kubernetes/workloads.py index 9c79c2b..68a0960 100644 --- a/kubernetes/workloads.py +++ b/kubernetes/workloads.py @@ -338,7 +338,7 @@ class Container(BaseModel): @staticmethod def find_key_in_config(key, configs): for name, config in configs.items(): - if key in config.data.keys(): + if key in config.data or key in config.string_data: return name raise ( BaseException( From d6908464e4004d78fe29504d649ea0585eb1e4c7 Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Thu, 3 Apr 2025 14:34:38 -0300 Subject: [PATCH 03/15] Add config attribute to "special case" PodDisruption Budge `_add_component` expects `config_attr` to exist in `self.config` We were not passing the attribute to the function --- kubernetes/workloads.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kubernetes/workloads.py b/kubernetes/workloads.py index 68a0960..802424c 100644 --- a/kubernetes/workloads.py +++ b/kubernetes/workloads.py @@ -637,7 +637,8 @@ def body(self): if self.config.type != "job" and ( self.config.pdb_min_available or self.config.auto_pdb ): - self._add_component(PodDisruptionBudget, workload=workload) + config_attr = "pdb_min_available" if self.config.pdb_min_available else "auto_pdb" + self._add_component(PodDisruptionBudget, config_attr, workload=workload) self.add(workload) From 5b8437651378850ef7b4f104ba23a26504b73e8b Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Thu, 3 Apr 2025 14:40:27 -0300 Subject: [PATCH 04/15] Update PodDisruptionBudget api version --- kubernetes/autoscaling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/autoscaling.py b/kubernetes/autoscaling.py index 287c5b8..f4c7cd1 100644 --- a/kubernetes/autoscaling.py +++ b/kubernetes/autoscaling.py @@ -44,7 +44,7 @@ def body(self): class PodDisruptionBudget(KubernetesResource): kind: str = "PodDisruptionBudget" - api_version: str = "policy/v1beta1" + api_version: str = "policy/v1" def body(self): super().body() From 86ea64fccb671eedce38757d61e48ba79d670829 Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Thu, 3 Apr 2025 14:45:08 -0300 Subject: [PATCH 05/15] Update HPA api version --- kubernetes/autoscaling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/autoscaling.py b/kubernetes/autoscaling.py index f4c7cd1..2736d5e 100644 --- a/kubernetes/autoscaling.py +++ b/kubernetes/autoscaling.py @@ -77,7 +77,7 @@ def body(self): class HorizontalPodAutoscaler(KubernetesResource): kind: str = "HorizontalPodAutoscaler" - api_version: str = "autoscaling.k8s.io/v2beta2" + api_version: str = "autoscaling.k8s.io/v2" def body(self): super().body() From 43970efbf333839f4e8e0f6b6d975c28fdf1fd79 Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Fri, 4 Apr 2025 13:58:28 -0300 Subject: [PATCH 06/15] Update the default podantiaffinity to use the label `name` as we don't create the label `app` by default --- kubernetes/workloads.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kubernetes/workloads.py b/kubernetes/workloads.py index 802424c..47e3d14 100644 --- a/kubernetes/workloads.py +++ b/kubernetes/workloads.py @@ -137,7 +137,7 @@ def body(self): "podAffinityTerm": { "labelSelector": { "matchExpressions": [ - {"key": "app", "operator": "In", "values": [name]} + {"key": "name", "operator": "In", "values": [name]} ] }, "topologyKey": "kubernetes.io/hostname", @@ -155,7 +155,7 @@ def body(self): "podAffinityTerm": { "labelSelector": { "matchExpressions": [ - {"key": "app", "operator": "In", "values": [name]} + {"key": "name", "operator": "In", "values": [name]} ] }, "topologyKey": "topology.kubernetes.io/zone", From 8571fe63a929ca6c84cd3da45264413c493c584d Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Mon, 7 Apr 2025 11:36:46 -0300 Subject: [PATCH 07/15] Fix defaultBackend key --- kubernetes/networking.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kubernetes/networking.py b/kubernetes/networking.py index b321ab7..549483c 100644 --- a/kubernetes/networking.py +++ b/kubernetes/networking.py @@ -32,8 +32,8 @@ def body(self): config = self.config if config.default_backend: - self.root.spec.backend.service.name = config.default_backend.get("name") - self.root.spec.backend.service.port = config.default_backend.get("port", 80) + self.root.spec.defaultBackend.service.name = config.default_backend.get("name") + self.root.spec.defaultBackend.service.port = config.default_backend.get("port", 80) if config.paths: host = config.host paths = config.paths From b78be2a4af08e65893e93073129af070c492c159 Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Mon, 7 Apr 2025 16:26:13 -0300 Subject: [PATCH 08/15] fix serviceAccount metadata.name --- kubernetes/rbac.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kubernetes/rbac.py b/kubernetes/rbac.py index bbc44f7..6cbe20b 100644 --- a/kubernetes/rbac.py +++ b/kubernetes/rbac.py @@ -31,6 +31,10 @@ def body(self): else: self.name = config.name or self.name super().body() + # Force the name again after super().body() + # This is needed for when we are setting service_account.name. + # Wihthout this, only labels.name is set correctly + self.root.metadata.name = self.name if self.spec: self.add_annotations(self.spec.annotations) From a11a4590d36c63f56e042414a0fe9c32fa4c4a1d Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Tue, 15 Apr 2025 16:05:08 -0300 Subject: [PATCH 09/15] fix ManagedCertificate api version --- kubernetes/networking.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/networking.py b/kubernetes/networking.py index 549483c..3759757 100644 --- a/kubernetes/networking.py +++ b/kubernetes/networking.py @@ -47,7 +47,7 @@ def body(self): class GoogleManagedCertificate(KubernetesResource): kind: str = "ManagedCertificate" - api_version: str = "networking.gke.io/v1beta1" + api_version: str = "networking.gke.io/v1" def body(self): super().body() From 02219bf0f6e78b04e6ac9e10ced2b7d82386ad15 Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Thu, 1 May 2025 09:22:49 -0300 Subject: [PATCH 10/15] fix cert-manager spec --- kubernetes/certmanager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kubernetes/certmanager.py b/kubernetes/certmanager.py index 292cd92..5e07fd6 100644 --- a/kubernetes/certmanager.py +++ b/kubernetes/certmanager.py @@ -13,7 +13,7 @@ class CertManagerIssuer(KubernetesResource): def body(self): config = self.config super().body() - self.root.spec = config.get("spec") + self.root.spec = config.spec @kgenlib.register_generator(path="certmanager.cluster_issuer") @@ -24,7 +24,7 @@ class CertManagerClusterIssuer(KubernetesResource): def body(self): config = self.config super().body() - self.root.spec = config.get("spec") + self.root.spec = config.spec @kgenlib.register_generator(path="certmanager.certificate") @@ -35,4 +35,4 @@ class CertManagerCertificate(KubernetesResource): def body(self): config = self.config super().body() - self.root.spec = config.get("spec") + self.root.spec = config.spec From 7dc611fe15da9c0adb7ce27a890f38eb54a85c90 Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Mon, 5 May 2025 12:22:48 -0300 Subject: [PATCH 11/15] add FrontendConfig, FrontendConfigGenerator, BackendConfigGenerator --- kubernetes/gke.py | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/kubernetes/gke.py b/kubernetes/gke.py index 82806c7..5662ee0 100644 --- a/kubernetes/gke.py +++ b/kubernetes/gke.py @@ -2,7 +2,8 @@ logger = logging.getLogger(__name__) -from .common import KubernetesResource +from .common import KubernetesResource, kgenlib +from typing import Any class BackendConfig(KubernetesResource): @@ -11,4 +12,41 @@ class BackendConfig(KubernetesResource): def body(self): super().body() - self.root.spec = self.config.backend_config + spec = self.spec + self.root.spec = spec + + +@kgenlib.register_generator(path="generators.kubernetes.backend_config") +class BackendConfigGenerator(kgenlib.BaseStore): + name: str + config: Any + + def body(self): + name = self.name + config = self.config + spec = self.config.spec + backend_config = BackendConfig(name=name, config=config, spec=spec) + self.add(backend_config) + + +class FrontendConfig(KubernetesResource): + kind: str = "FrontendConfig" + api_version: str = "networking.gke.io/v1beta1" + + def body(self): + super().body() + spec = self.spec + self.root.spec = spec + + +@kgenlib.register_generator(path="generators.kubernetes.frontend_config") +class FrontendConfigGenerator(kgenlib.BaseStore): + name: str + config: Any + + def body(self): + name = self.name + config = self.config + spec = self.config.spec + frontend_config = FrontendConfig(name=name, config=config, spec=spec) + self.add(frontend_config) \ No newline at end of file From 0e363af6f73ab50e060bf1924cee576137a2eaee Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Mon, 5 May 2025 12:33:16 -0300 Subject: [PATCH 12/15] Add FrontendConfig to workloads --- kubernetes/workloads.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kubernetes/workloads.py b/kubernetes/workloads.py index 47e3d14..76074d5 100644 --- a/kubernetes/workloads.py +++ b/kubernetes/workloads.py @@ -24,7 +24,7 @@ WorkloadTypes, kgenlib, ) -from .gke import BackendConfig +from .gke import BackendConfig, FrontendConfig from .istio import IstioPolicy from .networking import NetworkPolicy, Service from .prometheus import PrometheusRule, ServiceMonitor @@ -117,7 +117,7 @@ def body(self): affinity = self.root.spec.template.spec.affinity if config.prefer_pods_in_node_with_expression and not config.node_selector: affinity.nodeAffinity.setdefault( - "preferredDuringSchedulingIgnoredDuringExecutio", [] + "preferredDuringSchedulingIgnoredDuringExecution", [] ) affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.append( { @@ -504,6 +504,7 @@ def body(self): apply_patches=[ "generators.manifest.default_config", 'applications."{application}".component_defaults', + 'generators.manifest.resource_defaults.{type}' ], ) class Components(kgenlib.BaseStore): @@ -521,6 +522,7 @@ def _add_component( if config_attr and getattr(self.config, config_attr): spec = spec or getattr(self.config, config_attr, {}) name = name or self.name + component = component_class( name=name, config=self.config, spec=spec, workload=workload, **kwargs ) @@ -528,6 +530,7 @@ def _add_component( logger.debug(f"Added component {component.root.metadata} for {self.name}.") return component + def _generate_and_add_multiple_objects( self, generating_class, config_attr, workload ): @@ -630,8 +633,9 @@ def body(self): self._add_component( ClusterRoleBinding, "cluster_role", role=role, sa=sa ) + self._add_component(BackendConfig, "backend_config", spec=self.config.backend_config) + self._add_component(FrontendConfig, "frontend_config", spec=self.config.backend_config) - self._add_component(BackendConfig, "backend_config") # Handling a special case where pdb_min_available or auto_pdb is set, but config.type isn't "job" if self.config.type != "job" and ( From b68e454d98868bf84f8b35fe634fb774e3e1d542 Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Mon, 5 May 2025 12:35:32 -0300 Subject: [PATCH 13/15] type --- kubernetes/workloads.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/workloads.py b/kubernetes/workloads.py index 76074d5..a104667 100644 --- a/kubernetes/workloads.py +++ b/kubernetes/workloads.py @@ -634,7 +634,7 @@ def body(self): ClusterRoleBinding, "cluster_role", role=role, sa=sa ) self._add_component(BackendConfig, "backend_config", spec=self.config.backend_config) - self._add_component(FrontendConfig, "frontend_config", spec=self.config.backend_config) + self._add_component(FrontendConfig, "frontend_config", spec=self.config.frontend_config) # Handling a special case where pdb_min_available or auto_pdb is set, but config.type isn't "job" From f935dfb1bc9a776fd2a6e3c98c6651b4a84dea8d Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Mon, 5 May 2025 12:38:28 -0300 Subject: [PATCH 14/15] add frontend_config to WorkloadConfigSpec --- kubernetes/common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/kubernetes/common.py b/kubernetes/common.py index b2e7811..2fc6748 100644 --- a/kubernetes/common.py +++ b/kubernetes/common.py @@ -386,6 +386,7 @@ class WorkloadConfigSpec(KubernetesResourceSpec, ContainerSpec): application: Optional[str] = None auto_pdb: bool = False backend_config: dict = {} + frontend_config: dict = {} cluster_role: Optional[Dict] = None containers: dict = {} deployment_progress_deadline_seconds: int | None = None From 7966aaa58c657611f4a4234184b59fbd69684678 Mon Sep 17 00:00:00 2001 From: Bruno Almeida Date: Mon, 5 May 2025 14:48:32 -0300 Subject: [PATCH 15/15] add namespace to GoogleManagedCertificate --- kubernetes/networking.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kubernetes/networking.py b/kubernetes/networking.py index 3759757..0667e76 100644 --- a/kubernetes/networking.py +++ b/kubernetes/networking.py @@ -410,6 +410,7 @@ def body(self): ) self.add( GoogleManagedCertificate( - name=certificate_name, config={"domains": domains} + name=certificate_name, namespace=self.config.namespace, + config={"domains": domains} ) )